之前遇见动画就很想用 CSS 实现, 显然有些效果是我们力所不能及, 实现起来麻烦, 效果不好, 让人捉急其实归结起来, 不同的动画有自己的优势, 根据实际情况进行取舍本文就告诉大家如何用 SVG 写出个简单动画就让我们以路径动画为例来说明吧
类似于下面动画, 这种之前就觉得好炫酷
好吧, 就算不说这个, 没学习之前, svg 实现的 loading 我也不知道怎么搞得
当然 SVG 肯定不是只是来做这个的啦, 这只是人家神奇的一部分 SVG 的优势是 跨设备能力强体积小图像可透明, 可以与 js 交互等等等等, 在这里不一一介绍啦我们直接从小例子开始, 动手实现个按路径运动的动画
首先让我们来实现一个描绘图形边框的小例子, 如下图:
要描绘如上图的五角星图形, 我们首先应该确定各个角的坐标, 然后将它们连接起来就好了说起来简单, 做起来其实更简单, 简单代码实现如下:
- <svg version="1.1"
- xmlns="http://www.w3.org/2000/svg" width="500" height="500" viewbox="-500 -500 2500 2500">
- <polygon points="-12 -69,-58 85,64 -14,-81 -14,41 85" class="star-path"></polygon>
- <polygon points="-12 -69,-58 85,64 -14,-81 -14,41 85" class="star-fill"></polygon>
- </svg>
在以上的代码中, polygon 标签是 svg 多边形标签, points 属性定义多边形每个角的 x 和 y 坐标通过 class 为 star-path 的标签来实现我们图中的灰色轨迹, 通过 class 为 star-fill 的标签来实现描绘的动画
上边我们实现了五角星的图形, 下面我们就结合 css, 来完成这个完整的描绘动画:
- .star-path{
- fill: none;
- stroke-width:10;
- stroke:#d3dce6;
- stroke-linejoin:round;
- stroke-linecap:round;
- }
- .star-fill{
- fill: none;
- stroke-width:10;
- stroke:#ff7700;
- stroke-linejoin:round;
- stroke-linecap:round;
- stroke-dasharray: 782;
- stroke-dashoffset: 0;
- animation: starFill 2s ease-out infinite;
- }
- @keyframes starFill {
- 0%{
- stroke-dashoffset:782;
- }
- 100%{
- stroke-dashoffset: 0;
- }
- }
在上面的代码中, 最核心的属性就是 stroke-dasharray 和 stroke-dashoffset stroke-dasharray: 定义描边的虚线长度, 如果提供奇数个, 则会自动复制该值成偶数 stroke-dashoffset: 定义虚线描边的偏移量 在上面代码中, stroke-dasharray 代表虚线之间的间距大小当我们设置了间距足够长的时候, 以至于大于我们图形的总边长, 就会达到我们想要的效果一开始我们的短划线是 0, 缺口是全部长度, 随动画的进行, 短划线的长度慢慢增长为图形总边长的全部长度, 达到了慢慢充满全部的效果另外, 我们要知道路径长度也可以借助 如下代码 path.getTotalLength() 函数获取路径的长度
document.querySelector('.star-path').getTotalLength();
除此之外, 我们还可以改变偏移 stroke-dashoffset 来达到效果, 将虚线的偏移量设置为 0, 此时我们看到的路径描边就是没有间断的连续曲线, 通过设置虚线偏移量等于曲线的长度, 那该曲线恰好消失, 代码如下:
- .star-path{
- fill: none;
- stroke-width:10;
- stroke:#d3dce6;
- stroke-linejoin:round;
- stroke-linecap:round;
- }
- .star-fill{
- fill: none;
- stroke-width:10;
- stroke:#ff7700;
- stroke-linejoin:round;
- stroke-linecap:round;
- stroke-dasharray: 1340;
- stroke-dashoffset: 0;
- animation: starFill 2s ease-out infinite;
- }
- @keyframes starFill {
- 0%{
- stroke-dashoffset:1340;
- }
- 100%{
- stroke-dashoffset: 0;
- }
- }
很多时候我们可以运用这种方法到我们运营活动项目中, stroke-dasharray 和 stroke-dashoffset 是创造大量 SVG 路径动画所要用到的两个重要属性, 掌握原理就可以给各种图形描边
另外我们再实现个根据运动路径运动的小例子, 这里要涉及到 svg 的 path 属性实现, 如下图:
- <svg width="500" height="500">
- <path d="M100 150 L200 50 L300 150 L400 50 Z"
- stroke="#ccc" stroke-width="2"
- fill="none"
- />
- <circle r="20" x="150" y="0" style="fill:#336622;">
- <animateMotion
- dur="3s"
- repeatCount="indefinite"
- rotate="auto"
- path="M100 150 L200 50 L300 150 L400 50 Z" />
- </circle>
- </svg>
path 标签用于指定一条运动路径, 从点 (100,150) 到(200,50)再到 (300,150) 再到 (400,50) 最后再链接起点 我们用了 svg 的 animateMotion 动画标签 repeatCount 属性描述动画的重复次数, indefinite 是无限循环, dur 属性描述动画的持续时间, 我们这里让整个动画持续 3 秒 我们用 start 和 end 可以控制整个动画的开始结束时间, 而且如果我们想点击控制运动的开始可以加入 begin="click"
当然我们实现的很简单的效果, 如果涉及到想元素自动根据运动路径的角度来改变它的运动方向, 我们可以使用 rotate 设置为 auto, 想让元素在外围运动, 可以设置 rotate="auto-reverse"
另外, 当路径复杂的时候再用 path 属性来描述就显得很多余和麻烦, 这时候我们可以使用 标签来指定运动路径:
- <svg width="500" height="500">
- <path d="M100 150 L200 50 L300 150 L400 50 Z"
- stroke="#ccc" stroke-width="2"
- fill="none"
- id="myPath"
- />
- <circle r="20" x="150" y="0" style="fill:#336622;">
- <animateMotion
- dur="6s"
- begin="click"
- repeatCount="indefinite"
- rotate="auto">
- <mpath xlink:href="#myPath" />
- </animateMotion>
- </circle>
- </svg>
以上是 svg 按路径运动的典型例子, 我们用代码方式进行剖析 svg 很多属性和当时学习 css 动画属性很相似, 很方便学习很多时候动画就是简单组成了复杂, 或者没有从简单思考显得复杂我们看到酷炫的动效可能要复杂一些, 但看完本文你是不是也能完成自己的小动画了呢?
来源: https://juejin.im/entry/5aa7298f6fb9a028de445d15