adjust videoscroll size according to svg element, add all directions

master
Tomáš Mládek 2021-01-10 13:12:41 +01:00
parent e6f894cbf8
commit a6bc042876
2 changed files with 64 additions and 44 deletions

View File

@ -150,6 +150,10 @@ async function processScrolls(svg: XMLDocument): Promise<VideoScrollDef[]> {
const descNode = el.children[0]; // to fix
const [directionString, filesURL] = descNode.textContent!.split("\n");
if (!Object.values(VideoScrollDirection).includes(directionString as VideoScrollDirection)) {
throw new Error("Unknown direction string.");
}
const fileFetch = await fetch(`content/${filesURL}`);
const preURL = fileFetch.url.replace(/\/files.lst$/, "");
const files = (await fileFetch.text()).split("\n").filter(Boolean).map((str) => `${preURL}/${str}`);
@ -157,11 +161,10 @@ async function processScrolls(svg: XMLDocument): Promise<VideoScrollDef[]> {
return {
top: el.y.baseVal.value * ratio,
left: el.x.baseVal.value * ratio,
direction: VideoScrollDirection.RIGHT,
files,
style: {
width: `${el.width.baseVal.value * ratio}px`
}
width: el.width.baseVal.value * ratio,
height: el.height.baseVal.value * ratio,
direction: directionString as VideoScrollDirection,
files
};
})
);

View File

@ -1,21 +1,45 @@
<template>
<div class="video-scroll" ref="root">
<img class="visible loaded"
:src="definition.files[0]"
:style="{
top: `${Math.round(definition.top)}px`,
left:`${Math.round(definition.left)}px`,
}"
/>
<template v-if="definition.direction === 'left' || definition.direction === 'right'">
<img class="visible loaded"
:src="definition.files[0]"
:style="{
top: `${Math.round(definition.top)}px`,
left: `${Math.round(definition.left)}px`,
width: `${Math.round(definition.width)}px`,
}"
/>
<img v-for="(file, idx) in definition.files.slice(1)"
:data-src="file"
:style="{
top: `${Math.round(definition.top)}px`,
left: `${Math.round(definition.left) + width * (idx + 1)}px`,
}"
/>
<!--suppress RequiredAttributes -->
<img v-for="(file, idx) in definition.files.slice(1)"
:data-src="file"
:style="{
top: `${Math.round(definition.top)}px`,
left: `${Math.round(definition.left) + (definition.width * (idx + 1) * directionSign)}px`,
width: `${Math.round(definition.width)}px`,
}"
/>
</template>
<template v-else>
<img class="visible loaded"
:src="definition.files[0]"
:style="{
top: `${Math.round(definition.top)}px`,
left: `${Math.round(definition.left)}px`,
height: `${Math.round(definition.height)}px`,
}"
/>
<!--suppress RequiredAttributes -->
<img v-for="(file, idx) in definition.files.slice(1)"
:data-src="file"
:style="{
top: `${Math.round(definition.top) + (definition.height * (idx + 1) * directionSign)}px`,
left: `${Math.round(definition.left)}px`,
height: `${Math.round(definition.height)}px`,
}"
/>
</template>
</div>
</template>
@ -30,17 +54,19 @@ export default defineComponent({
required: true
}
},
computed: {
directionSign() {
if (this.definition.direction == VideoScrollDirection.RIGHT ||
this.definition.direction == VideoScrollDirection.DOWN) {
return 1;
} else {
return -1;
}
}
},
setup(props) {
const width = ref(0);
const height = ref(0);
const root = ref<Element | null>(null);
const definition = props.definition as VideoScrollDef;
getMeta(definition.files[0]).then((img) => {
width.value = img.width;
height.value = img.height;
});
onMounted(() => {
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach((entry) => {
@ -64,36 +90,27 @@ export default defineComponent({
});
return {
root,
width,
height
root
};
}
});
export enum VideoScrollDirection {
RIGHT
RIGHT = "right",
LEFT = "left",
UP = "up",
DOWN = "down"
}
export interface VideoScrollDef {
top: number,
left: number,
width: number,
height: number,
direction: VideoScrollDirection,
files: string[],
style?: { [key: string]: string }
files: string[]
}
function getMeta(url: string): Promise<HTMLImageElement> {
return new Promise((resolve, reject) => {
let img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject();
img.src = url;
});
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->