时间:2022-12-06来源:www.pcxitongcheng.com作者:电脑系统城
这个需求也是最近的 大屏项目 里面需要用到的一个效果,大致需求是实现一个圆形范围内 由一个不确定坐标的点 向圆周进行曲线发散 的效果,曲线圆弧向上并伴随路径动画。第一时间看到这个需求想到的就是 SVG 或者 Canvas。但是由于开发时可能还需要插入其他元素,所以这里还是希望通过 纯 DOM + CSS 或者 SVG 的方式来实现。
当然这个中心点还是比较确定哈,因为最后的效果是希望左右对称的,所以中心肯定在 width / 2 的那条纵线上。
于是今天忙活了半天,总算是有了一个 SVG 实现的雏形。最终效果就和封面图一样,只是因为录制的问题动画显得有断层。
为了方便显示,整个 SVG 的默认视口大小设置为了 600 的一个正方形,并且内部固定有一个中心点和圆周,当然这个中心点 目前还是固定的。
然后 曲线就通过遍历数组来创建 SVG 路径,路径动画与每条曲线进行绑定,然后每条曲线的路径的话,就通过 Vue 计算属性返回一个闭包函数,通过元素下标来计算曲线的路径。
并且,为了 方便后面判断曲线的左右分布,将 圆心的坐标 作为了 SVG 的坐标中心。
这里是生成一个 10 ~ 20 之间的数组,再模拟处理每个点的坐标的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
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 了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<template> <div class= "ArcAnimation" > <h 1 >ArcAnimation Page</h 1 > <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 原点,并且这个原点添加了一个与 曲线一致 的路径动画。
方法如下:
1 2 3 4 5 6 7 8 9 10 11 |
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 `M 0 , -60 C${controlX},${controlY} ${controlX},${controlY} ${x},${y}`; }, |
这里说明一下几点
后面可能还会涉及到路径计算的调整、路径动画配置等其他优化的方案,后面也会慢慢完善的。也会试验使用纯CSS结合DIV来实现。
2023-03-06
css3鼠标滑过实现动画线条边框2023-03-06
css scroll-snap控制滚动元素的实现2023-03-06
CSS实现多层嵌套列表自动编号的示例代码传统的灰色纯色边框你是不是觉得太难看了?你是否想设计一些精美的边框,例如渐变、圆角、彩色的边框?那你来对地方了,本文将介绍如何用纯CSS就能实现具有渐变和圆角的彩色边框...
2023-03-06
今天给大家带来一个如何实现圆角三角形的方案,这个方案虽然可以实现,但是也是借助拼凑等方式来实现的,假如想一个div来实现圆角三角形,还是比较困难的。之前文章讲了如何实现对话框,里面介绍了三角形的实现方式。今天讲讲...
2023-03-06