update 自定义飞线组件
parent
4ac6bae1e2
commit
3d4abe7a19
@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<svg
|
||||
:viewBox="`0 0 ${props.width} ${props.height}`"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g v-for="(line, index) in lines" :key="index">
|
||||
<!-- 定义阴影滤镜 -->
|
||||
<defs>
|
||||
<filter
|
||||
v-if="line.am && line.dot"
|
||||
:id="`shadow-${uid}-${index}`"
|
||||
x="-200%"
|
||||
y="-200%"
|
||||
width="500%"
|
||||
height="500%"
|
||||
>
|
||||
<feDropShadow
|
||||
dx="0"
|
||||
dy="0"
|
||||
:stdDeviation="1"
|
||||
:flood-color="line.flyingColor"
|
||||
flood-opacity="1"
|
||||
/>
|
||||
</filter>
|
||||
|
||||
<!-- 定义线性渐变 -->
|
||||
<linearGradient
|
||||
v-if="line.am && line.flying"
|
||||
:id="`gradient-${uid}-${index}`"
|
||||
x1="0%"
|
||||
y1="0%"
|
||||
x2="100%"
|
||||
y2="0%"
|
||||
>
|
||||
<stop offset="0%" style="stop-color: black; stop-opacity: 1" />
|
||||
<stop offset="100%" style="stop-color: white; stop-opacity: 1" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- 定义mask -->
|
||||
<mask :id="`mask-${uid}-${index}`" v-if="line.am && line.flying">
|
||||
<rect
|
||||
:x="-line.flyingLen"
|
||||
:y="-line.size"
|
||||
:width="line.flyingLen"
|
||||
:height="line.size * 3"
|
||||
:fill="`url(#gradient-${uid}-${index})`"
|
||||
>
|
||||
<animateMotion
|
||||
:dur="line.time"
|
||||
repeatCount="indefinite"
|
||||
rotate="auto"
|
||||
>
|
||||
<mpath :href="`#bezierPath-${uid}-${index}`" />
|
||||
</animateMotion>
|
||||
</rect>
|
||||
</mask>
|
||||
</defs>
|
||||
<!-- 定义二次贝塞尔曲线路径 -->
|
||||
<path
|
||||
:id="`bezierPath-${uid}-${index}`"
|
||||
:d="line.path"
|
||||
:stroke-width="line.size"
|
||||
:stroke="line.lineColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
/>
|
||||
<path
|
||||
v-if="line.am && line.flying"
|
||||
:d="line.path"
|
||||
:stroke-width="line.size"
|
||||
:stroke="line.flyingColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
fill="none"
|
||||
:mask="`url(#mask-${uid}-${index})`"
|
||||
/>
|
||||
|
||||
<!-- 定义光点 -->
|
||||
<circle
|
||||
v-if="line.am && line.dot"
|
||||
cx="0"
|
||||
cy="0"
|
||||
:r="(line.size / 5) * 3"
|
||||
:fill="line.flyingColor"
|
||||
:filter="`url(#shadow-${uid}-${index})`"
|
||||
>
|
||||
<!-- 使用animateMotion让光点沿路径移动 -->
|
||||
<animateMotion
|
||||
:dur="line.time"
|
||||
repeatCount="indefinite"
|
||||
calcMode="linear"
|
||||
>
|
||||
<mpath :href="`#bezierPath-${uid}-${index}`" rotate="reverse" />
|
||||
</animateMotion>
|
||||
</circle>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
<script setup>
|
||||
import { IdGenerator } from "@/util";
|
||||
import { computed } from "vue";
|
||||
|
||||
//唯一标识
|
||||
const uid = IdGenerator.next();
|
||||
|
||||
const defineLine = {
|
||||
path: `M 10,10 C 200,10,10,200,290,290`,
|
||||
size: 1,
|
||||
lineColor: "var(--w-bg-dark)",
|
||||
flyingColor: "var(--w-main)",
|
||||
flyingLen: 20,
|
||||
flying: true,
|
||||
dot: true,
|
||||
am: true,
|
||||
time: "5s",
|
||||
};
|
||||
|
||||
const props = defineProps({
|
||||
width: { type: Number, default: 300 },
|
||||
height: { type: Number, default: 300 },
|
||||
lines: { type: Array, default: [] },
|
||||
});
|
||||
|
||||
const lines = computed(()=>{
|
||||
return props.lines.map((line) => {
|
||||
return {
|
||||
...defineLine,
|
||||
...line,
|
||||
};
|
||||
});
|
||||
})
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@ -0,0 +1,26 @@
|
||||
class IdGenerator {
|
||||
static #idGenerator = new IdGenerator();
|
||||
|
||||
#count = 0;
|
||||
|
||||
#countGen() {
|
||||
this.#count++;
|
||||
if (this.#count >= 1296) {
|
||||
this.#count = 0;
|
||||
}
|
||||
return this.#count.toString(36).padEnd(2, "0");
|
||||
}
|
||||
next() {
|
||||
return (
|
||||
Date.now().toString(36) +
|
||||
this.#countGen() +
|
||||
Math.random().toString(36).substring(2, 10)
|
||||
);
|
||||
}
|
||||
|
||||
static next() {
|
||||
return IdGenerator.#idGenerator.next();
|
||||
}
|
||||
}
|
||||
|
||||
export { IdGenerator }
|
||||
Loading…
Reference in New Issue