欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

CSS使用SVG實(shí)現(xiàn)動(dòng)態(tài)分布的圓環(huán)發(fā)散路徑動(dòng)畫

  發(fā)布時(shí)間:2022-10-27 17:02:11   作者:MiyueFE   我要評(píng)論
這篇文章主要介紹了CSS使用SVG實(shí)現(xiàn)動(dòng)態(tài)分布的圓環(huán)發(fā)散路徑動(dòng)畫,第一時(shí)間看到這個(gè)需求想到的就是 SVG 或者 Canvas,但是由于開發(fā)時(shí)可能還需要插入其他元素,所以這里還是希望通過 純 DOM + CSS 或者 SVG 的方式來實(shí)現(xiàn),需要的朋友可以參考下

開篇

這個(gè)需求也是最近的 大屏項(xiàng)目 里面需要用到的一個(gè)效果,大致需求是實(shí)現(xiàn)一個(gè)圓形范圍內(nèi) 由一個(gè)不確定坐標(biāo)的點(diǎn) 向圓周進(jìn)行曲線發(fā)散 的效果,曲線圓弧向上并伴隨路徑動(dòng)畫。第一時(shí)間看到這個(gè)需求想到的就是 SVG 或者 Canvas。但是由于開發(fā)時(shí)可能還需要插入其他元素,所以這里還是希望通過 純 DOM + CSS 或者 SVG 的方式來實(shí)現(xiàn)。

當(dāng)然這個(gè)中心點(diǎn)還是比較確定哈,因?yàn)?strong>最后的效果是希望左右對(duì)稱的,所以中心肯定在 width / 2 的那條縱線上。

于是今天忙活了半天,總算是有了一個(gè) SVG 實(shí)現(xiàn)的雛形。最終效果就和封面圖一樣,只是因?yàn)殇浿频膯栴}動(dòng)畫顯得有斷層。

先設(shè)計(jì)

為了方便顯示,整個(gè) SVG 的默認(rèn)視口大小設(shè)置為了 600 的一個(gè)正方形,并且內(nèi)部固定有一個(gè)中心點(diǎn)和圓周,當(dāng)然這個(gè)中心點(diǎn) 目前還是固定的。

然后 曲線就通過遍歷數(shù)組來創(chuàng)建 SVG 路徑,路徑動(dòng)畫與每條曲線進(jìn)行綁定,然后每條曲線的路徑的話,就通過 Vue 計(jì)算屬性返回一個(gè)閉包函數(shù),通過元素下標(biāo)來計(jì)算曲線的路徑

并且,為了 方便后面判斷曲線的左右分布,將 圓心的坐標(biāo) 作為了 SVG 的坐標(biāo)中心。

再實(shí)現(xiàn)

首先是模擬數(shù)據(jù)

這里是生成一個(gè) 10 ~ 20 之間的數(shù)組,再模擬處理每個(gè)點(diǎn)的坐標(biāo)的。

export default {
  name: "ArcAnimation",
  data() {
    return {
      arr: [],
      width: 600
    };
  },
  created() {
    this.updateArray(false);
  },
  methods: {
    updateArray(timing) {
      const length = Math.floor(Math.random() * 10 + 10);
      // 這里是因?yàn)?svg 的中心點(diǎn)也在圓心,所以就是 0,0
      const center = { x: 0, y: 0 };
      this.arr = this.calcCircularLayout(length, center, 296);
      timing && setTimeout(() => this.updateArray(true), 2000);
    },
    /**
     * 計(jì)算N個(gè)點(diǎn)均勻排列成圓的各個(gè)點(diǎn)坐標(biāo)
     * @param nodeSize 參與排列成圓的元素個(gè)數(shù)
     * @param center 圓的中心點(diǎn)坐標(biāo) {x:, y:}
     * @param radius 圓的半徑
     * @return 各個(gè)元素的坐標(biāo):[{x:, y:}, {x:, y:}, ...]
     */
    calcCircularLayout(nodeSize, center, radius) {
      let i;
      let _i;
      let _layouts = [];
      for (i = _i = 0; _i < nodeSize; i = ++_i) {
        let x = center.x + radius * Math.sin((2 * Math.PI * i) / nodeSize);
        let y = center.y + radius * Math.cos((2 * Math.PI * i) / nodeSize);

        _layouts.push({ x: x, y: y, k: i });
      }

      return _layouts;
    }
  }
};

這個(gè) 圓周每個(gè)點(diǎn)的坐標(biāo)是從網(wǎng)上找的,但是因?yàn)楫?dāng)時(shí)忘記留地址了。要是作者看見了可以聯(lián)系我刪除或者加上您的文章地址。

每個(gè)元素的 path 的計(jì)算放到了后面說明的。

然后是模板部分

因?yàn)樽罱K代碼在 calcCircularLayout 這里會(huì)計(jì)算好路徑放到數(shù)組元素中,但是因?yàn)?path 路徑計(jì)算在后面說嘛,所以這里大家就先當(dāng)這個(gè)數(shù)組里面已經(jīng)有 path 了。

<template>
  <div class="ArcAnimation">
    <h1>ArcAnimation Page</h1>
    <p>
      <el-button @click="updateArray(false)">刷新數(shù)據(jù)</el-button>
      <el-button @click="updateArray(true)">自動(dòng)刷新</el-button>
    </p>

      <div class="base-content">
        <svg :viewBox="`-${width / 2} -${width / 2} ${width} ${width}`">
          <g v-for="i in arr" :key="i.k">
            <path :d="i.path" fill="none" stroke="#c4605f" stroke-width="4px"></path>
            <circle r="5" fill="#af4">
              <animateMotion dur="4s" repeatCount="indefinite" :path="i.path" />
            </circle>
          </g>
          <circle r="30" cx="0" cy="-60" fill="#2bc0e4" />
          <circle r="296" cx="0" cy="0" fill="none" stroke="#2bc0e4" stroke-width="4px" />
        </svg>
      </div>
  </div>
</template>

這里只有一點(diǎn):

在 for 循環(huán)中循環(huán)生成的是一個(gè) g 分組標(biāo)簽,里面是一個(gè) path 曲線元素和一個(gè) circle 原點(diǎn),并且這個(gè)原點(diǎn)添加了一個(gè)與 曲線一致 的路徑動(dòng)畫。

最后是曲線路徑計(jì)算

方法如下:

computedDotPath({ x, y }) {
  const centerX = 0;
  const centerY = -60;
  let controlX = (centerX + x) / 1.4;
  let controlY = (centerY + y) / 2;
  if (y < centerY) {
    controlX = x / 2;
    controlY = y / 1.2;
  }
  return `M0,-60 C${controlX},${controlY} ${controlX},${controlY} ${x},${y}`;
},

這里說明一下幾點(diǎn)

  • centerXcenterY 代表的是 UI 圖中的中心點(diǎn),也是每個(gè)曲線的起點(diǎn),可以根據(jù)情況修改
  • if 判斷是因?yàn)?如果不調(diào)整控制點(diǎn)的話,曲線的方向會(huì)與需求方向 相反
  • 兩次 除的 除數(shù) 數(shù)值不一樣,也是因?yàn)橹行狞c(diǎn)的位置偏上,所以稍微有修改,當(dāng)然后面也可以調(diào)整

后續(xù)

后面可能還會(huì)涉及到路徑計(jì)算的調(diào)整、路徑動(dòng)畫配置等其他優(yōu)化的方案,后面也會(huì)慢慢完善的。也會(huì)試驗(yàn)使用純CSS結(jié)合DIV來實(shí)現(xiàn)。

到此這篇關(guān)于CSS使用SVG實(shí)現(xiàn)動(dòng)態(tài)分布的圓環(huán)發(fā)散路徑動(dòng)畫的文章就介紹到這了,更多相關(guān)svg路徑動(dòng)畫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論