原理:绑定点击事件 拾取开始和结束坐标点 动态调整中间点位 即可画出曲线 ,在使用css 创建动画,就可以实现曲线流光效果
<script setup>
import { reactive, getCurrentInstance, ref,onMounted,computed } from "vue";
const { proxy } = getCurrentInstance();
const begin = ref("M 1591 626"); // 起始
const end = ref("1307 493"); // 结束
const valuex = ref(1357); // 控制点x
const valuey = ref(500); // 控制点y
const valuex2 = ref(1920); // 控制点x
const valuey2 = ref(919); // 控制点y
const trueD = computed(() => {
return begin.value + " Q " + valuex.value + " " + valuey.value + ", " + end.value;
});
const trueV = computed(() => {
return "0 0 " + valuex2.value + " " + valuey2.value;
});
onMounted(() => {
console.log( "mounted")
const svg = document.querySelector("svg");
const rect = svg.getBoundingClientRect();
// valuex2.value = rect.width;
// valuey2.value = rect.height;
svg.addEventListener("click", function (event) {
const rect = svg.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
console.log(`Clicked at (${x} ${y})`);
});
});
</script>
<template>
<div class="container">
<div class="g-container">
<div class="g-svg">
<svg
id="svgBox"
xmlns="http://www.w3.org/2000/svg"
:viewBox="trueV"
preserveAspectRatio="none"
>
<!-- 辅助线 画线用,不实际展示-->
<!-- <path :d="trueD" stroke="#fff" stroke-width="2" fill="transparent" /> -->
<path
class="g-dashed-line"
d="M 947 460 Q 1004 290, 1173 375 Q 1423 500, 1421 195"
stroke="#fff"
stroke-width="2"
fill="transparent"
/>
<path
class="g-dashed-line"
d="M 933 463 Q 884 290, 707 375 Q 467 500, 457 200"
stroke="#fff"
stroke-width="2"
fill="transparent"
/>
<path
class="g-dashed-line"
d="M 940 437 Q 942 333, 827 350 Q 641 426, 643 274"
stroke="#fff"
stroke-width="2"
fill="transparent"
/>
<path
class="g-dashed-line"
d="M 940 437 Q 949 330, 1051 349 Q 1245 429, 1236 270"
stroke="#fff"
stroke-width="2"
fill="transparent"
/>
<path
class="g-dashed-line1"
d="M 608 516 Q 414 578, 608 638 Q 789 677, 961 674 Q 1244 670, 1336 630 Q 1495 574, 1312 516"
stroke="#fff"
stroke-width="2"
fill="transparent"
/>
<path
class="g-dashed-line1"
d="M 612 493 Q 173 576, 408 689 Q 533 735, 763 756 Q 1073 775, 1319 737 Q 1569 695, 1591 626 Q 1615 544, 1307 493"
stroke="#fff"
stroke-width="2"
fill="transparent"
/>
</svg>
<!-- <canvas id="myCanvas"></canvas>-->
</div>
<!--画线工具 不实际展示-->
<div
style="
position: absolute;
right: 469px;
bottom: 58px;
width: 310px;
height: 100px;
z-index: 9999;
color: #fff;
"
v-if="false"
>
x<input type="number" v-model="valuex" /><br />
y<input type="number" v-model="valuey" /><br />
{{ trueD }}<br />
viewBox<br />
x2<input type="number" v-model="valuex2" /><br />
y2<input type="number" v-model="valuey2" /><br />
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.container {
background-image: url(@/assets/GuidePage/12.jpg);
background-size: 100% 100%;
background-repeat: no-repeat;
height: 100vh;
width: 100vw;
.g-container {
width: 100vw;
height: 100vh;
}
#svgBox {
width: 100vw;
height: 100vh;
}
.g-dashed-line {
fill: transparent;
stroke: #6aedff;
stroke-dasharray: 80, 620;
stroke-dashoffset: 0;
animation: move 3.4s infinite linear;
filter: drop-shadow(0 0 5px #00e4ff);
// filter:drop-shadow(0 0 1px rgb(65, 233, 200));
}
.g-dashed-line1 {
fill: transparent;
stroke: #6aedff;
stroke-dasharray: 120, 620;
stroke-dashoffset: 0;
animation: move1 3.4s infinite linear;
filter: drop-shadow(0 0 5px #00e4ff);
}
@keyframes move1 {
0% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -750;
}
}
@keyframes move {
0% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -700;
}
}
.left1 {
position: absolute;
left: 3vh;
top: 23vh;
// width: 30vh;
// height: 6vh;
width: 14vw;
animation: left1 1s ease-in-out;
}
.left2 {
position: absolute;
left: 13vh;
top: 43vh;
// width: 30vh;
// height: 6vh;
width: 14vw;
animation: left2 1s ease-in-out;
}
.right1 {
position: absolute;
right: 4vh;
top: 23vh;
// width: 30vh;
// height: 6vh;
width: 14vw;
animation: right1 1s ease-in-out;
}
.right2 {
position: absolute;
right: 13vh;
top: 43vh;
// width: 30vh;
// height: 6vh;
width: 14vw;
animation: right2 1s ease-in-out;
}
.a4 {
position: absolute;
left: 49%;
top: 17.3vh;
transform: translateX(-50%) scale(1);
transition: all 0.3s ease-in-out;
cursor: pointer;
width: 10vw;
}
.a6 {
position: absolute;
left: 50%;
top: 62vh;
width: 12vw;
transform: translateX(-50%) scale(1);
transition: all 0.3s ease-in-out;
cursor: pointer;
&:hover {
transform: translateX(-50%) scale(1.1);
}
}
.ajtright {
position: absolute;
left: 38%;
top: 60.8vh;
transform: translateX(-50%) rotate(-180deg);
animation: ajt2 cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
}
.ajtleft {
position: absolute;
left: 54%;
top: 60.7vh;
animation: ajt cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
}
.a1 {
position: absolute;
left: 62%;
top: 49vh;
width: 9vw;
transform: translateX(-50%) scale(1);
transition: all 0.3s ease-in-out;
cursor: pointer;
&:hover {
transform: translateX(-50%) scale(1.1);
}
}
.a3 {
position: absolute;
left: 37%;
top: 49vh;
width: 9vw;
transform: translateX(-50%) scale(1);
transition: all 0.3s ease-in-out;
cursor: pointer;
&:hover {
transform: translateX(-50%) scale(1.1);
}
}
.a9 {
position: absolute;
left: 49.5%;
top: 53vh;
width: 12vw;
transform: translateX(-50%) scale(0.8);
transition: all 0.3s ease-in-out;
cursor: pointer;
&:hover {
transform: translateX(-50%) scale(1);
}
}
.jtright {
position: absolute;
left: 43%;
top: 16vh;
transform: translateX(-50%) rotate(-180deg);
animation: jt2 cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
}
.jtleft {
position: absolute;
left: 54%;
top: 16vh;
animation: jt cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
}
.item {
position: absolute;
text-align: center;
color: #fff;
font-size: 1.6vh;
font-family: "Microsoft YaHei";
display: flex;
flex-direction: column;
align-items: center;
.icon {
width: 8vh;
height: 8vh;
background-image: url(@/assets/GuidePage/8.png);
background-size: 100% 100%;
background-repeat: no-repeat;
}
}
.zp {
position: absolute;
background-size: 100% 100%;
background-repeat: no-repeat;
width: 16vh;
height: 11vh;
}
.zp1 {
left: 18%;
top: 57vh;
background-image: url(@/assets/GuidePage/闸门控制.png);
animation: mydrop-shadow-move1 1s linear , mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
animation-delay: 2s; /* 动画将在2秒后开始 */
animation-fill-mode: both;
}
.zp2 {
left: 23%;
top: 66vh;
background-image: url(@/assets/GuidePage/水位监测.png);
animation: mydrop-shadow-move3 1s linear, mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
animation-delay: 1s; /* 动画将在2秒后开始 */
animation-fill-mode: both;
}
.zp3 {
left: 32%;
top: 70vh;
background-image: url(@/assets/GuidePage/流量监测.png);
animation: mydrop-shadow-move5 1s linear, mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
animation-fill-mode: both;
}
.zp4 {
left: 46%;
top: 72vh;
background-image: url(@/assets/GuidePage/视频监控.png);
animation: mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
}
.zp5 {
left: 60%;
top: 70vh;
background-image: url(@/assets/GuidePage/墒情监测.png);
animation: mydrop-shadow-move6 1s linear, mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
animation-fill-mode: both;
}
.zp6 {
left: 70%;
top: 64vh;
background-image: url(@/assets/GuidePage/压力监测.png);
animation: mydrop-shadow-move4 1s linear, mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
animation-delay: 1s; /* 动画将在2秒后开始 */
animation-fill-mode: both;
}
.zp7 {
left: 75%;
top: 55vh;
background-image: url(@/assets/GuidePage/泵站控制.png);
animation: mydrop-shadow-move2 1s linear, mydrop-shadow 1s cubic-bezier(0.36, 0, 0.64, 1) -2s infinite alternate;
animation-delay: 2s; /* 动画将在2秒后开始 */
animation-fill-mode: both;
}
.item1 {
left: 28%;
top: 30vh;
animation: item cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
}
.item6 {
left: 23%;
top: 22vh;
animation: item cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
animation-delay: 0.3s; /* 动画将在2秒后开始 */
}
.item2 {
left: 35%;
top: 25vh;
animation: item cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
animation-delay: 0.5s; /* 动画将在2秒后开始 */
}
.item3 {
left: 58%;
top: 26vh;
animation: item cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
animation-delay: 1s; /* 动画将在2秒后开始 */
}
.item4 {
left: 65%;
top: 31vh;
animation: item cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
animation-delay: 0.6s; /* 动画将在2秒后开始 */
}
.item5 {
left: 71%;
top: 23vh;
animation: item cubic-bezier(0.36, 0, 0.64, 1) 1.5s infinite alternate;
animation-delay: 0.8s; /* 动画将在2秒后开始 */
}
.a4:hover {
transform: translateX(-50%) scale(1.1);
}
@keyframes left1 {
0% {
left: -30vh;
}
100% {
left: 3vh;
}
}
@keyframes left2 {
0% {
left: -30vh;
}
100% {
left: 13vh;
}
}
@keyframes right1 {
0% {
right: -30vh;
}
100% {
right: 3vh;
}
}
@keyframes right2 {
0% {
right: -30vh;
}
100% {
right: 13vh;
}
}
@keyframes jt {
0% {
left: 54%;
}
100% {
left: 55%;
}
}
@keyframes jt2 {
0% {
left: 43%;
}
100% {
left: 42%;
}
}
@keyframes ajt {
0% {
left: 55.2%;
}
100% {
left: 56.2%;
}
}
@keyframes ajt2 {
0% {
left: 43.8%;
}
100% {
left: 42.8%;
}
}
@keyframes item {
0% {
transform: translateY(0);
}
100% {
transform: translateY(1.5vh);
}
}
}
@keyframes mydrop-shadow-move1 {
0% {
left: 46%;
top: 72vh;
opacity: 0;
}
100% {
left: 18%;
top: 57vh;
opacity: 1;
}
}
@keyframes mydrop-shadow-move2 {
0% {
left: 46%;
top: 72vh;
opacity: 0;
}
100% {
left: 75%;
top: 55vh;
opacity: 1;
}
}
@keyframes mydrop-shadow-move3 {
0% {
left: 46%;
top: 72vh;
opacity: 0;
}
100% {
left: 23%;
top: 66vh;
opacity: 1;
}
}
@keyframes mydrop-shadow-move4 {
0% {
left: 46%;
top: 72vh;
opacity: 0;
}
100% {
left: 70%;
top: 64vh;
opacity: 1;
}
}
@keyframes mydrop-shadow-move5 {
0% {
left: 46%;
top: 72vh;
opacity: 0;
}
100% {
left: 32%;
top: 70vh;
opacity: 1;
}
}
@keyframes mydrop-shadow-move6 {
0% {
left: 46%;
top: 72vh;
opacity: 0;
}
100% {
left: 60%;
top: 70vh;
opacity: 1;
}
}
</style>