SVG 曲线 流光动画

原理:绑定点击事件 拾取开始和结束坐标点  动态调整中间点位 即可画出曲线 ,在使用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>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值