呆恋小喵

Svg 路径动画实现旋转进度条

尝试使用 Svg 实现简易的动画效果。有关 Svg 的具体知识点不在此文赘述,仅就所举示例的需求点阐述实现思路。

先阐明具体需求:白色轨迹需自起始点旋转至由用户成长值决定的终点。

动画效果如下:若无效果请戳这里

该动画可拆分为两部分实现:粉红圆环轨迹、粉红圆形尾巴。


绘制粉红圆环轨迹

相关代码:

<path d="M 110 10 a 100 100 0 0 1 0 200 a 100 100 0 0 1 0 -200 Z" fill="none" stroke="#FD7991" stroke-width="4" stroke-linecap="round" stroke-dasharray="628.4073486328125">
    <animate attributeName="stroke-dashoffset" from="628.4073486328125" to="0" dur="2s" repeatCount="indefinite" />
</path>

使用 path 绘制半径 100 的圆环轨迹。起点 M 110 10,右半圆弧 a 100 100 0 0 1 0 200,左半圆弧 a 100 100 0 0 1 0 -200,闭合路径 Z

不了解 Svg Paths 的同学建议自行科普~

可优先了解 圆弧 A a

A rx ry x-axis-rotation large-arc-flag sweep-flag x y
a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy

路径绘制完毕如何添加描线效果呢?请注意 stroke-dasharraystroke-dashoffset

属性 stroke-dasharray 控制描边点划线的图案范式;属性 stroke-dashoffset 指定 dash 模式至路径开始的距离。

stroke-dashoffset 偏移量为 path 路径长度时,粉红轨迹完全不可见,逐步减小偏移至 0 可使之完全呈现。

这好比在热狗上挤果酱,本应从其左侧挤至右侧。而你却从其右侧开始向右挤,整整偏移了一条热狗的长度。热狗上无半点果酱,只能靠减小偏移来加料喽。

指定 stroke-dasharraypath 路径长度,意味着操作空间为整条热狗。

友情提示如何获取路径长度:

var pathLength = $('path')[0].getTotalLength();

绘制粉红圆形尾巴

尾巴可使用图片绘制:

<defs>
    <pattern id="tail" width="100%" height="100%" patternContentUnits="objectBoundingBox">
        <image width="1" height="1" xlink:href="https://sunmengyuan.github.io/materials/garden/post/svg-comet/tail.png" />
    </pattern>
</defs>
<g>
    <circle cx="0" cy="0" r="8" fill="url(#tail)"></circle>
</g>

也可使用渐变绘制:

<defs>
    <radialGradient cx="50%" cy="50%" fx="50%" fy="50%" r="60%" id="tail">
        <stop stop-opacity="1" stop-color="#FD7991" offset="30%"/>
        <stop stop-opacity="0.5" stop-color="#fD97AA" offset="40%"/>
        <stop stop-opacity="0" stop-color="#FECBD4" offset="80%"/>
    </radialGradient>
</defs>
<g>
    <rect x="-10" y="-10" width="20" height="20" fill="url(#tail)"></rect>
</g>

为尾巴添加动画:

<rect x="-10" y="-10" width="20" height="20" fill="url(#tail)">
    <animateMotion path="M 110 10 a 100 100 0 0 1 0 200 a 100 100 0 0 1 0 -200 Z" rotate="auto" dur="2s" repeatCount="indefinite" />
</rect>

动画路径、执行时间、速度曲线等属性与粉红圆环轨迹保持一致即可~


控制动画终止位置

再次阐明具体需求:白色轨迹需自起始点旋转至由用户成长值决定的终点。

假定轨迹描线长度占圆环总长的百分比已知,如何控制动画终止位置?根据百分比计算描线长度然后巴拉巴拉计算坐标点…数学欠佳的还是绕行吧。

控制动画执行次数 repeatDur 便可…

var totalTime = 3;
var percent = 0.8;
var runAnimate = function () {
    var durTime = totalTime * percent;
    $circleAnimate[0].setAttribute('repeatDur', durTime + 's');
    $tailAnimate[0].setAttribute('repeatDur', durTime + 's');
    $circleAnimate[0].beginElement();
    $tailAnimate[0].beginElement();
};

本例 源码 demo


作者:呆恋小喵

我的后花园:https://sunmengyuan.github.io/garden/

我的 github:https://github.com/sunmengyuan

原文链接:https://sunmengyuan.github.io/garden/2017/11/16/svg-comet.html