[CSS] svg路径动画

1. 背景

在制作CSS动画的时候,经常会有这样的需求,
让一个方块 沿着给定的路径 运动。

如果运动路径是不规则的,通过设置topleft的属性值,就显得非常困难了。
这时候可以借助svg来实现。

2. svg的path元素

path元素的形状是通过它的 d属性 定义的,
d 属性的值,是一个“命令+参数”的序列。

<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
    <path d="M 20 30 L 160 180" />
</svg>

<style>
    svg {
        background: gray;
    }
    svg path {
        stroke: black;
        fill: none;
        stroke-width: 2;
    }
</style>

其中,M 20 30 L 160 180,包含了2个命令序列,
M 20 30,表示将画笔移动到坐标20,30处,
L 160 180,表示从画笔当前位置,到160,180位置画直线。

path元素支持多种命令,可以参考这里,curve commands

3. offset-path 与 offset-distance 属性

html元素的CSS样式属性offset-path ,表示偏移路径
通过指定offset-path的值为path元素的d属性值,我们可以实现元素沿着给定的path路径运动。

<div class="container">
    <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
        <path d="M 20 30 L 160 180" />
    </svg>

    <div class="rect"></div>
</div>


<style>
    .container {
        position: relative;
    }

    .container svg {
        background: gray;
    }

    .container svg path {
        stroke: black;
        fill: none;
        stroke-width: 2;
    }

    .container .rect {
        position: absolute;
        top: 0;
        left: 0;
        width: 10px;
        height: 10px; 
        background: darkred;

        offset-path: path("M 20 30 L 160 180");
        offset-distance: 20%;
    }
</style>

其中,offset-distance 指定了元素偏移初始位置的百分比。

4. 动画中设置offset-distance

通过在@keyframes中逐帧更改offset-distance,可以实现动画效果。

<div class="container">
    <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
        <path d="M 20 30 L 160 180" />
    </svg>

    <div class="rect"></div>
</div>


<style>
    .container {
        position: relative;
    }

    .container svg {
        background: gray;
    }

    .container svg path {
        stroke: black;
        fill: none;
        stroke-width: 2;
    }

    @keyframes svg-path-animation {
        from {
            offset-distance: 0%;
        }

        to {
            offset-distance: 100%;
        }
    }

    .container .rect {
        position: absolute;
        top: 0;
        left: 0;
        width: 10px;
        height: 10px; 
        background: darkred;

        offset-path: path("M 20 30 L 160 180");
        offset-distance: 0%;
        
        animation: svg-path-animation 2s ease-in-out 0s infinite normal none;
    }
</style>

5. 任意path路径

我们修改path的d属性为M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80
相应的也修改小方块的offset-path属性。

就可以实现小方块沿着path运动的效果了。

<div class="container">
    <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
        <path d="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" />
    </svg>

    <div class="rect"></div>
</div>


<style>
    .container {
        position: relative;
    }

    .container svg {
        background: gray;
    }

    .container svg path {
        stroke: black;
        fill: none;
        stroke-width: 2;
    }

    @keyframes svg-path-animation {
        from {
            offset-distance: 0%;
        }

        to {
            offset-distance: 100%;
        }
    }

    .container .rect {
        position: absolute;
        top: 0;
        left: 0;
        width: 10px;
        height: 10px; 
        background: darkred;

        offset-path: path("M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80");
        offset-distance: 0%;
        
        animation: svg-path-animation 2s ease-in-out 0s infinite normal none;
    }
</style>

参考

MDN: paths
MDN: offset-path
MDN: offset-distance
A How-to Guide to SVG Animation
Scalable Vector Graphics (SVG) 2 - Chapter 9: Paths

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容