CSS使用SVG实现动态分布的圆环发散路径动画


Posted in HTML / CSS onDecember 24, 2022

开篇

这个需求也是最近的 大屏项目 里面需要用到的一个效果,大致需求是实现一个圆形范围内 由一个不确定坐标的点 向圆周进行曲线发散 的效果,曲线圆弧向上并伴随路径动画。第一时间看到这个需求想到的就是 SVG 或者 Canvas。但是由于开发时可能还需要插入其他元素,所以这里还是希望通过 纯 DOM + CSS 或者 SVG 的方式来实现。

CSS使用SVG实现动态分布的圆环发散路径动画

当然这个中心点还是比较确定哈,因为最后的效果是希望左右对称的,所以中心肯定在 width / 2 的那条纵线上

于是今天忙活了半天,总算是有了一个 SVG 实现的雏形。最终效果就和封面图一样,只是因为录制的问题动画显得有断层。

先设计

为了方便显示,整个 SVG 的默认视口大小设置为了 600 的一个正方形,并且内部固定有一个中心点和圆周,当然这个中心点 目前还是固定的

然后 曲线就通过遍历数组来创建 SVG 路径,路径动画与每条曲线进行绑定,然后每条曲线的路径的话,就通过 Vue 计算属性返回一个闭包函数,通过元素下标来计算曲线的路径

并且,为了 方便后面判断曲线的左右分布,将 圆心的坐标 作为了 SVG 的坐标中心

再实现

首先是模拟数据

这里是生成一个 10 ~ 20 之间的数组,再模拟处理每个点的坐标的。

export default {
  name: "ArcAnimation",
  data() {
    return {
      arr: [],
      width: 600
    };
  },
  created() {
    this.updateArray(false);
  },
  methods: {
    updateArray(timing) {
      const length = Math.floor(Math.random() * 10 + 10);
      // 这里是因为 svg 的中心点也在圆心,所以就是 0,0
      const center = { x: 0, y: 0 };
      this.arr = this.calcCircularLayout(length, center, 296);
      timing && setTimeout(() => this.updateArray(true), 2000);
    },
    /**
     * 计算N个点均匀排列成圆的各个点坐标
     * @param nodeSize 参与排列成圆的元素个数
     * @param center 圆的中心点坐标 {x:, y:}
     * @param radius 圆的半径
     * @return 各个元素的坐标:[{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;
    }
  }
};

这个 圆周每个点的坐标是从网上找的,但是因为当时忘记留地址了。要是作者看见了可以联系我删除或者加上您的文章地址。

每个元素的 path 的计算放到了后面说明的。

然后是模板部分

因为最终代码在 calcCircularLayout 这里会计算好路径放到数组元素中,但是因为 path 路径计算在后面说嘛,所以这里大家就先当这个数组里面已经有 path 了。

<template>
  <div class="ArcAnimation">
    <h1>ArcAnimation Page</h1>
    <p>
      <el-button @click="updateArray(false)">刷新数据</el-button>
      <el-button @click="updateArray(true)">自动刷新</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>

这里只有一点:

在 for 循环中循环生成的是一个 g 分组标签,里面是一个 path 曲线元素和一个 circle 原点,并且这个原点添加了一个与 曲线一致 的路径动画

最后是曲线路径计算

方法如下:

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}`;
},

这里说明一下几点

  • centerXcenterY 代表的是 UI 图中的中心点,也是每个曲线的起点,可以根据情况修改
  • if 判断是因为 如果不调整控制点的话,曲线的方向会与需求方向 相反
  • 两次 除的 除数 数值不一样,也是因为中心点的位置偏上,所以稍微有修改,当然后面也可以调整

后续

后面可能还会涉及到路径计算的调整、路径动画配置等其他优化的方案,后面也会慢慢完善的。也会试验使用纯CSS结合DIV来实现

到此这篇关于CSS使用SVG实现动态分布的圆环发散路径动画的文章就介绍到这了,更多相关svg路径动画内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
HTML / CSS 相关文章推荐
css3 border-radius属性详解
Jul 05 HTML / CSS
CSS3的常见transformation图形变化用法小结
May 13 HTML / CSS
HTML5+CSS3网页加载进度条的实现,下载进度条的代码实例
Dec 30 HTML / CSS
通过css3的filter滤镜改变png图片的颜色的示例代码
May 06 HTML / CSS
CSS3制作圆形滚动进度条动画的示例
Nov 05 HTML / CSS
HTML5里autofocus自动聚焦属性使用介绍
Jun 22 HTML / CSS
使用HTML5 Canvas API中的clip()方法裁剪区域图像
Mar 25 HTML / CSS
HTML5本地存储之Web Storage应用介绍
Jan 06 HTML / CSS
html标签之Object和EMBED标签详解
Jul 04 HTML / CSS
HTML5 canvas基本绘图之绘制五角星
Jun 27 HTML / CSS
HTML5触摸事件(touchstart、touchmove和touchend)的实现
May 08 HTML / CSS
HTML5公共页面提取作为公用代码的方法
Jun 30 HTML / CSS
CSS中理解层叠性及权重如何分配
Dec 24 #HTML / CSS
CSS 鼠标点击拖拽效果的实现代码
Dec 24 #HTML / CSS
详解CSS3浏览器兼容
Dec 24 #HTML / CSS
HTML5页面打开微信小程序功能实现
Sep 23 #HTML / CSS
CSS元素定位之通过元素的标签或者元素的id、class属性定位详解
Sep 23 #HTML / CSS
微信小程序纯CSS实现无限弹幕滚动效果
Sep 23 #HTML / CSS
使用 CSS 构建强大且酷炫的粒子动画效果
You might like
php date与gmdate的获取日期的区别
2010/02/08 PHP
Windows下部署Apache+PHP+MySQL运行环境实战
2012/08/31 PHP
PHP数组生成XML格式数据的封装类实例
2016/11/10 PHP
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
2009/09/19 Javascript
jQuery 动画弹出窗体支持多种展现方式
2010/04/29 Javascript
js 操作select和option常用代码整理
2012/12/13 Javascript
javascript获取form里的表单元素的示例代码
2014/02/14 Javascript
jquery中的ajax方法怎样通过JSONP进行远程调用
2014/05/04 Javascript
jquery动态添加元素事件失效问题解决方法
2014/05/23 Javascript
Egret引擎开发指南之发布项目
2014/09/03 Javascript
node.js中的fs.closeSync方法使用说明
2014/12/17 Javascript
javascript 动态创建表格
2015/01/08 Javascript
js实现延迟加载的方法
2015/06/24 Javascript
JavaScript+html5 canvas制作的百花齐放效果完整实例
2016/01/26 Javascript
jQuery Easyui使用(一)之可折叠面板的布局手风琴菜单
2016/08/17 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
Vue 组件(component)教程之实现精美的日历方法示例
2018/01/08 Javascript
详解ajax的data参数错误导致页面崩溃
2018/04/30 Javascript
JavaScript实现京东购物放大镜和选项卡效果的方法分析
2018/07/05 Javascript
Layui多选只有最后一个值的解决方法
2019/09/02 Javascript
layui 实现自动选择radio单选框(checked)的方法
2019/09/03 Javascript
element form 校验数组每一项实例代码
2019/10/10 Javascript
微信小程序表单验证WxValidate的使用
2019/11/27 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
2020/03/13 Javascript
web.py获取上传文件名的正确方法
2014/08/26 Python
解决pycharm无法调用pip安装的包问题
2018/05/18 Python
基于python代码实现简易滤除数字的方法
2018/07/17 Python
解析Python的缩进规则的使用
2019/01/16 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
Python之修改图片像素值的方法
2019/07/03 Python
Python 中使用 PyMySQL模块操作数据库的方法
2019/11/10 Python
pyCharm 设置调试输出窗口中文显示方式(字符码转换)
2020/06/09 Python
中国高端鲜花第一品牌:roseonly(一生只送一人)
2017/02/12 全球购物
搞笑爱情保证书
2014/04/29 职场文书
个人委托书怎么写
2014/09/17 职场文书
党员群众路线教育实践活动学习笔记
2014/11/05 职场文书