line-and-surface/app/src/components/SVGContent.vue

100 lines
2.5 KiB
Vue

<template>
<div class="content" ref="root">
</div>
</template>
<script lang="ts">
import {defineComponent, onMounted, ref} from "vue";
import createPanZoom, {PanZoom} from "panzoom";
export default defineComponent({
name: "SVGContent",
props: {
url: {
type: String,
required: true
},
},
setup(props) {
const domparser = new DOMParser();
const root = ref(null);
onMounted(async () => {
const element = root.value as unknown as HTMLDivElement;
const panzoom = createPanZoom(element, {
smoothScroll: false,
zoomSpeed: 0.05
});
panzoom.on("transform", function (panzoom: PanZoom) {
const transform = panzoom.getTransform();
// console.log(transform);
});
panzoom.on("panend", function (panzoom: PanZoom) {
console.log("panend");
});
const fetchResult = await fetch(props.url);
const svgParsed = domparser.parseFromString(await fetchResult.text(), "image/svg+xml") as Document;
const svg = element.appendChild(svgParsed.firstElementChild as Element) as any;
const anchors = processAnchors(svg);
const anchor = anchors[0];
window.addEventListener("keydown", (ev) => {
if (ev.key !== " ") {
return;
}
const transform = panzoom.getTransform();
console.log(transform);
const currentRatio = svg.clientWidth * transform.scale / svg.viewBox.baseVal.width;
const targetScale = 2;
const svgTargetX = anchor.x.baseVal.value + anchor.width.baseVal.value / 2;
const svgTargetY = anchor.y.baseVal.value + anchor.height.baseVal.value / 2;
console.log(svgTargetX * currentRatio + transform.x);
panzoom.smoothMoveTo(
svgTargetX * currentRatio * -1 + window.innerWidth / 2,
svgTargetY * currentRatio * -1 + window.innerHeight / 2,
);
setTimeout(() => {
panzoom.smoothZoomAbs(window.innerWidth / 2, window.innerHeight / 2, 1);
}, 1000);
});
});
return {
root
};
}
});
function processAnchors(document: XMLDocument): SVGRectElement[] {
let result = [];
let i = 1;
while (true) {
let anchor = document.getElementById(`anchor_${i}`) as SVGRectElement | null;
if (anchor === null) {
break;
}
anchor.classList.add("svgcontent_anchor");
result.push(anchor);
i++;
}
return result;
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.svgcontent_anchor {
visibility: hidden;
}
</style>