64 lines
1.4 KiB
Vue
64 lines
1.4 KiB
Vue
<template>
|
|
<Teleport to="body">
|
|
<video v-if="videoURL" controls :src="videoURL" ref="video">Hello</video>
|
|
</Teleport>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { useData } from "vitepress";
|
|
import { computed, useTemplateRef, watch } from "vue";
|
|
|
|
const { frontmatter } = useData<{ video?: string }>();
|
|
const videoURL = computed(() => frontmatter.value?.video);
|
|
const videoEl = useTemplateRef("video");
|
|
|
|
function setImgClick() {
|
|
document.removeEventListener("click", imgClickListener);
|
|
document.addEventListener("click", imgClickListener);
|
|
|
|
document.querySelectorAll("img").forEach((img) => {
|
|
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
|
|
const t = min && sec ? parseInt(min) * 60 + parseInt(sec) : null;
|
|
if (!t) return;
|
|
|
|
img.title = img.title || img.alt;
|
|
});
|
|
}
|
|
|
|
function imgClickListener(ev: PointerEvent) {
|
|
if (!(ev.target instanceof HTMLImageElement)) return;
|
|
const img = ev.target;
|
|
|
|
if (!videoEl.value) return;
|
|
const v = videoEl.value;
|
|
|
|
const [, min, sec] = /^(\d+)\:(\d+)$/.exec(img.alt) || [];
|
|
const t = min && sec ? parseInt(min) * 60 + parseInt(sec) : null;
|
|
if (!t) return;
|
|
|
|
v.currentTime = t;
|
|
}
|
|
|
|
watch(videoURL, () => {
|
|
setImgClick();
|
|
});
|
|
|
|
//@ts-ignore
|
|
const { SSR } = import.meta.env;
|
|
|
|
if (!SSR){
|
|
setTimeout(() => setImgClick(), 500);
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
video {
|
|
width: 400px;
|
|
overflow: visible;
|
|
position: fixed;
|
|
bottom: 10px;
|
|
left: 10px;
|
|
z-index: 100;
|
|
}
|
|
</style>
|