100 lines
2.5 KiB
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>
|