初探CSS路径动画

发布于 大漠

在Web网站或Web应用程序上经常能看到动效的效果,而且实现动效的方式有很多种,比如说CSS、SVG、Canvas、WebGL以及JavaScript等技术手段都可以实现。到目前为止,CSS Animations Level 1CSS TransitionsWeb Animation API以及CSS Houdini的CSS Animation Worklet API等规范可以很好的指导我们如何制作Web动效。特别是CSS的animationtransition令CSSer感到兴奋,因为它们可以让我们使用纯CSS就可以实现以前很多需要依赖JavaScript才能实现的动效。

CSS的animationtransition实现从A点到B点的动画效果很简单,而且效果也不错,但这些效果都具有一个特性,即 沿着一条直线运动。即使你使用贝塞尔曲线也无法让某物体(运动对象)沿着曲线路径运动。简单地说,就是无法很好或者轻易的实现路径动画效果。

CSS的animationtransition有一个共性

使用我们熟悉的animationtransition实现一个帧动画或者过渡动画,他们都有一个共性,即改变物体的xy轴的坐标。大多数看到的动画效果就是从A点到B点(甚至是更多的坐标点),但这些坐标点都可以通过xy来描述。如果坐标点个数少的话,他的运动曲线是一条直线(或者说是一条折线),如下图所示:

这些点都可以通过transformtranslate(x, y)来描述。当然也可以通过lefttop等描述,但translate要比lefttop描述元素运动位置性能更好。

当然,我们可以把描述元素运动位置的点布得更密集,密集的让你无法忍受:

你们当年实现猫沿着指定路径运动,就是这样描出来的路径:

事实上,即使我们可以像上面那样通过N个坐标点构建一个曲线,但使用animation@keyframes也是有一定难度的。另外,这种模式也不灵活,一旦需求改变(路径改变)需要重新描点构造路径。想想都痛苦。

@Tobias Ahlin提出了一个新的技术方案,就是分层运动。简单地说,就是把一个运动元素分成两个部分,如果用HTML来描述的话,就像下面这样:

<div class="xAxis">
    <div class="yAxis"></div>
</div>

其中div.xAxis沿着x轴从标运动,div.yAxis沿着y坐标运动:

.xAxis {
    animation: xAxis 2.5s infinite cubic-bezier(0.02, 0.01, 0.21, 1);
}

.yAxis {
    animation: yAxis 2.5s infinite cubic-bezier(0.3, 0.27, 0.07, 1.64);
}

@keyframes yAxis {
    50% {
        animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1);
        transform: translateY(-100px);
    }
}

@keyframes xAxis {
    50% {
        animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64);
        transform: translateX(100px);
    }
}

效果如下:

两层分开来看的话,运动规律如下:

针对该技术的介绍,如果你不喜欢阅读英文,可以阅读该文的译文

该技术看上去比描N个坐标点好一些了,但要实现复杂的曲线效果还是有一定难度的。不过庆幸的是,CSS的Motion Path Module Level 1为我们提供了新的纯CSS技术方案,即路径动画。接下来,我们就和大家一起聊聊这方面的技术。如果您感兴趣的话,请继续往下阅读。

CSS路径动画发展史

到编写该文为止,W3C在以前的动效规范的基础上新添加了另外一个模块规范,该模块是独立的,就是用来描述CSS路径动画,到目前为止是Level 1(Motion Path Module Level 1)。

CSS路径动画并不是现在提出来的,从提出到现在已经历过重大的变化。早在2015年夏天,就有CSS路径动画相关的草案,该草案提供了三个新的CSS属性,即motion-pathmotion-offsetmotion-rotation。这几个属性可以让我们轻松的构建一个路径动效。2016年,在另一个圆形显式器和极坐标的规范中,径动画相关与相关部分合并后,发生了一些变化。

这也意味着,首先是我们不再有这些属性,因为它们被重命名

  • motion-path重命名为offset-path
  • motion-offset重命名为offset-distance

在新的路径动画规范中新增了offset-positionoffset-anchoroffset-rotate以及它们对应的简写属性offset

这些变化是有意义的,因为只有当这些属性与CSS的animationtransition相结合时,移动才会发生。只有这些属性才能简单地在路径上放置一个元素。如果你只是想要放置一个东西沿着路径,你只需要使用offset-distance属性为它声明偏移距离即可。如果你想要沿着路径移动,那么你可以通过CSS的animationtransition来实现我们所需要路径动画效果。

随着Firefox 72的发布,CSS路径动画(CSS Motion Path Module Level 1)可以在Firefox、新Edge、Chrome中正常运行。对于现代Web浏览器而言,就差Safari浏览器了。这也意味着除Safari浏览器之外,可以看到offset-pathoffset-distanceoffset-rotate。另外Firefox还发布了对offset-anchor的稳定支持,对于Blink内核的浏览器需要开启“实验性Web平台特性”(chrome://flags/#enable-experimental-web-platform-features)才能看到相应的效果。如果你的浏览器运行下面这个Demo,看到的都是绿色的,说明你的浏览器是棒棒的,接下来内容中示例的效果都可以看到:

换句话说,有了CSS路径动画,我们要实现像下图这样的效果就不再需要依赖于JavaScript脚本了:

看到上图是不是更有体感了,在一些旅游行业常能看到上图这样的效果。除此之外,在一些打车软件上看到小汽车沿着地图行走,也可以理解成小汽车沿着地图上线路(这个线路就是路径)运动的一个效果(动效)。也就是说,如果你掌握接下来的内容,说不定你就能很轻易的实现这些效果了。

CSS路径动画简介

一个CSS路径动画包含两个部分运动物体(即元素)运动路径。比如下图所示,飞机的示意图淍着路径运动的。其中飞机就是运动物体,虚线就是运动路径:

事实上上图还有一个方向的概念,飞机会沿着指定的路径移动时,对应的机头也会旋转方向。也就是说,一个较好的CSS路径动画是涵盖了“运动物体”、“运路路径”和“旋转方向”,注意这里所说的旋转方向并不是CSS中transformrotate()

W3C规范对路径动画是这样描述的

The Motion Path module allows specifying the position of a box as the distance (offset-distance) of the box’s anchor point (offset-anchor) along a geometrical path (offset-path) defined against the coordinates (offset-position) of its containing block. The box’s orientation can optionally be specified as a rotation (offset-rotate) with respect to the direction of the path at that point.

大致的意思是,CSS路径运动模块允许你通过offset-anchor指定元素框的位置(锚点位置)沿着offset-path设定的路径初始位置(offset-position)进行偏移(offset-distance),这样就改变了不同的位置,行为了沿着路径的动画效果。而且还可以使用offset-rotate指定元素的方向是相对于该点的路径方向旋转。

简单地来说:

  • offset-path定义了运动路径(该路径是任何你想要的)
  • offset-anchor指定了运动元素的锚点位置(你可能不想是元素的正中心点进行位移)
  • offset-position指定了路径本身的初始位置
  • offset-distance指定运动元素在路径上的位置
  • offset-rotate指定了对象的旋转角度或是如何自动旋转

接下来,我们就围绕着这几个属性来展开。

定义路径(offset-path

既然聊CSS路径动画,那么就离不开路径。在该模块中,offset-path可以用来定义路径动画中的路径,即指定偏移路径,也就是运动物体定位的几何路径。偏移路径可以是具有一个或多个子路径的指定路径,也可以是没有样式的基本形状的几何形状。

CSS的offset-path可接受的属性值有:

offset-path: none | ray() | path() | <url> | [ <basic-shape> || <geometry-box> ]

从上面的属性值看上去是不是很熟悉,比如path()<url><basis-shape><geometry-box>CSS Masking Module Level 1clip-path。而且创建几何形状的依据都源自于**CSS Shapes Module Level 1** 的 基本形状 部分。

在CSS路径动画中的路径可以是由一条射线或一个基本形状组成,而且为了允许你指定曲线和子路径,还可以使用SVG的路径。换句话说,除了使用我们熟悉的circle()inset()polygon()ellipse() (CSS Shapes中的绘制基本几何形状的函数)构建路径之外,还可以使用path()url()ray()。特别是ray()函数,我们着重来看这个函数的使用,毕竟他是一个新产物。

ray()函数构建路径

从几何的角度来说,直线上的一点和它一旁的部分所组成的图形称为射线(这是欧几里德几何学中描述)。而offset-path中的ray()也称为射线,不同的是,它以容器的中心为圆心,在容器中嵌入一个能够嵌入的最大圆形,结合自定义的夹角,将圆心与边上的点相连,形成的路径

offset-path中的ray()函数接受三个参数:

ray() = ray( [ <angle> && <size> && contain? ] )
<angle>

offset-path绘制的路径是一条线段,它从方框的位置开始,沿着指定的<angle>定义的方向前进。<angle>和渐变中的<angle>一样,都是轴承角0度向上,正值代表顺时针旋转。

注意:使用<angle>定义的路径,元素盒子使用的极坐标定位。在数学理论中,极轴通常被定义为x轴的正方向,但为了与其他CSS规范一致,这里将极轴视为y轴的正方向。

这个角度从圆的中心通过极坐标创建一条线来定位。当div.ray运用了offset-path:ray()

.ray {
    offset-path: ray(0deg closest-side);
}

好比.ray设置了定位,并且做了相应的偏移设置:

在上面的示例中,尝试着对复选框做操作(选中和未选中之间切换),你将看到下面的效果:

如果未给元素添加其他的路径动画相关的属性值,就仅offset-path:ray(),元素是动不起来的。另外,如果仅对offset-pathray()中的角度做改变,他的表现行为有点类似于transform中的rotate()

改变ray()<angle>值,可以看到元素会绕着自己的中心点旋转:

<size>

在上面的示例中,你可能已经发现了,在ray()函数中除了<angle>值,还显式的设置了closest-side值,该值对应的就是ray()函数中的<size>。该值可以用来决定路径的长短,它主要支持以下属性值:

<size> = [ closest-side | closest-corner | farthest-side | farthest-corner | sides ]

具体的含义是:

<size>属性值 描述
closest-side 初始位置到最近一边的距离
closest-corner 初始位置到最近一角的距离
farthest-side 初始位置到最远一边的距离
farthest-corner 初始位置到最远一角的距离
sides 初始位置到交线的距离

在上面的示例上稍作修改:

注意:在写这个示例的时候,<size>取不同值时,并没有发现其差异性。我自己也没有发现其中原因,只能先暂时当作目前主流浏览器还未支持。 在CSS的径向渐变其实也这几个关键词,我想他们的效果应该是类似

contain

ray()第三个参数是contain。该参数是个可选参数。在ray()中设置了contain参数时,会有两种情况发生:

  • 当在元素上显式的设置了offset-distance,那么该元素会完全包含在路径中
  • 当元素未显式设置offset-distance会导致元素被路径包围,那么路径大小就会最小程度地增加,这样就存在偏移距离

在W3C中提供了几个示例。演示了不同情况的效果。不过亲测之后,浏览器暂看不到效果。所以不在这里罗列,感兴趣的可以到W3C规范中查阅

<basic-shape>

<basic-shape>主要是使用CSS Shapes Module Level 1规范中定义的基本函数来绘制的基本形状。主要有:

  • inset():绘制一个矩形
  • circle():绘制一个圆形
  • ellipse():绘制一个椭圆形
  • polygon():绘制一个多边形

对于有明确中心位置的圆形和椭圆形基本形状,以及其他类型的基本形状,将会忽略offset-position。如果一个圆或椭圆的基本形状没有显式设置中心位置,那么形状以路径的初始位置为中心。使用上面函数绘制的形状,其初始位置的描述如下:

  • circle()ellipse()的初始位置是由圆或椭圆的水平切线到达顶部垂直位置的点,简单地说就是圆心
  • inset()的初始位置是矩形顶部水平线的左端,紧靠任何border-radius为半径绘制的弧形的右侧,简单地说就是左上角(顶点)
  • polygon()的初始位置则是多边形的第一个坐标点位置;初始方向是由连接的向量定义

<geometry-box>

<geometry-box><basic-shape>组合为<basic-shape>提供了参考框。如果没有显式指定参考框,则将border-box作为参考框。

<geometry-box>CSS Shapes Module Level 1的<shape-box>类似

如果<geometry-box>没有<basic-shape>,则初始位置为为顶部水平线的左端,紧靠任何border-radius圆弧的右侧,初始方向为右侧。

特别声明,目前在各主流浏览器上看不到有关于<geometry-box>运用于offset-path上的效果

path()<url>

如果你熟悉SVG的path或者曾经在别的地方使用过path()函数(比如clip-path)或者CSS Shapes中使用path()绘制的图形(也可以是路径),那么你对path就不会感到陌生。SVG中的path有很多绘制图形的指令:

path指令 参数 描述
M x y 起始点坐标x y
L x y 从当前点的坐标画直线到指定点的x y坐标
H x 从当前点的坐标画水平直线到指定的x轴坐标
V y 从当前点的坐标画垂直直线到指定的y轴坐标
C x1 y1 x2 y2 x y 从当前点的坐标画条贝塞尔曲线到指定点的x y坐标,其中x1 y1x2 y2为控制点
S x2 y2 x y 从当前点的坐标画条反射的贝塞尔曲线到指定点的x y坐标,其中x2 y2为反射的控制点
Q x1 y1 x y 从当前点的坐标画条反射二次贝塞尔曲线到指定点的x y坐标,其中x1 y1为控制点
T x y 从当前点的坐标画条反射二次贝塞尔曲线到指定点的x y坐标,以前一个坐标为反射控制点
A rx ry x-axis-rotation large-arc-flag sweep-flag x y 从当前点的坐标画个椭圆形到指定点的x y坐标,其中rx ry为椭圆形的x轴及y轴的半径,x-axis-rotation是弧线与x轴的旋转角度,large-arc-flag则设定1最大角度的弧线或是0最小角度的弧线,sweep-flag设定方向为1顺时针方向或0逆时针方向
Z 关闭路径,将当前点坐标与第一个点的坐标连接起来

如果你不想花太多时间了解这些指令的话,可以考虑使用一些绘制矢量图的软件来绘制路径,比如大家熟悉的Sketch

对于<url>可以引用SVG形状元素并使用其几何图形作为offset-path

none

offset-path设置值为none时,表示没有显式创建路径。当offset-path显式设置none值时,那么offset-distanceoffset-rotate将会失效,不会产生任何影响。

正如前面给大家所演示的示例,不管使用哪种方式绘制的路径(即offset-path设置的路径),并无法直接让元素按着路径动起来。如果需要让元素按着路径动起来,还是离不开CSS的animationtransition,或者通过JavaScript在不同的阶段改变CSS路径动画中的相关值。比如下面这个示例:

.ray {
    offset-path: ray(0deg closest-side);
    animation: rayAni 3000ms infinite linear;
}

@keyframes rayAni {
    from {
        offset-path: ray(0deg closest-side);
    }
    to {
        offset-path: ray(360deg closest-side);
    }
}

效果如下:

尝试在上例中选中复选框,你可以看到元素会绕着自身的中心点旋转:

是不是看上去和rotate()动效一样呀。

接着我们来看CSS路径动画中的第二个属性offset-distance,即定义距离

定义距离(offset-distance

offset-distanceCSS Motion Module Level 1另一个属性。主要用来指定元素在路径(offset-path绘制的路径)上的偏移位置。offset-path的值<length-percentage> ,即可以是长度值(<length>)或百分比值(<percentage>)。就以往的经验来看,设置百分比值是更易于指定物体的在路径上的偏移位置,因为0%表示没有任何偏移,而100%总是表示物体在路径的结束位置。

来看一个简单的示例:

特别声明,目前在主流浏览器中使用<basic-shape>绘制的路径暂时还无法看到效果,因此接下来的示例中,将以path()方式来绘制路径

在上面的示例中,我们使用path()offset-path设置路径:

.pathed {
    offset-path: path('M0,0 C40,240 200,240 240,0');
}

上面的示例是我们人肉的在调整offset-distance的值,可以看到offset-distance取值不同时,物体会在路径上偏移量也不同(有点类似于定位元素设置了不同的TRBL值,也有点类似于translate)。稍微调整一下上面的示例:

尝试着拖动示例中的进度条,你可以看到“红色盒子”会沿着offset-path指定的路径偏移,效果如下:

换句话说,我们在@keyframes中改变offset-distance的值,比如说从0%100%,然后使用animation就可以让红色盒子沿着白色虚线路径运动起来:

@keyframes ani {
    from {
        offset-distance: 0%;
    }
    to {
        offset-distance: 100%;
    }
}

.box {
    offset-path: path('M0,0 C40,240 200,240 240,0');
    offset-distance: var(--offset);
    animation: ani 2000ms linear alternate infinite;
}

效果如下:

在介绍offset-path的时候,我们提到过,可以改变offset-path实现路径动效。这里特意提一下,如果我们offset-path使用的是path()绘制路径的话,我们也可以动态的改变其数据点,但一定要保证path()所使用的数据点一定相同。如果采用的数据点数量不同的话就会造成插值计算的混乱,也就无法进行平滑的转换。比如下面这个示例:

定义元素面向何处(offset-rotate

offset-rotate主要用来定义运动物体在路径上的方向。因为有些运动物何是有方向感的,这个属性特别有用。该属性可用的值主要有:

offset-rotate: [ auto | reverse ] || <angle>

auto

autooffset-rotate的默认值,如果offset-distance是动态变化的话,那么运动物体将随着路径旋转。比如前面的示例,我们并没有显式的设置offset-rotate的值,因此其取值为auto。当offset-distance不断的使物体沿着路径向右(相对于正x轴的偏移路径),效果如下:

默认情况下,运动物体(元素)将“面”朝着路径的方向,其右侧始图垂直于路径

除了可以显式给offset-rotate显式的设置auto值之外,还可以在其基础上传第二个值,即以一个度为单位的旋转值,该值是一个可选的值。如果我们在auto的基础上添加了该角度值,那么将会按这个值调整运动物体的旋转角度。我们在上面的示例基础上来稍作修改:

正如上例所示,左侧未显式设置offset-rotate的值(取值为auto),右侧显式的设置了auto <angle>,效果如下:

将其和offset-distance结合在一起,并且在auto的基础上加上第二个参数,那么运动物体在不同位置的偏移时,拖动进度条调整运动物体的旋转角度:

如果不动态改变offset-distance的值,只是调整offset-rotate的值,其效果有点类似于transformrotate(),运动物体会围绕着运动物体自身中心点进行自转:

如果offset-distance动态的改变值,运动物体就会在路径上进行偏移(前面示例向大家演示了该效果),如果在运动过程中改变offset-rotate的值,那么物体在运动过程中朝向也会有所改变:

offset-rotateoffset-distance类似,也可以在@keyframes改变值。在上面的示例基础上稍作修改,你可以看到类似下例的动画效果:

reverse

offset-rotate可以取的另一个值是reverse,它刚好和auto反相,相对于正x轴加上180度。简单说,auto在不加任何角度设置的话,它的朝向是朝着路径的右侧;而reverse刚好与其相反,它的朝向是朝着路径的左侧。同样的,reverse也可以选择性的添加第二个参数,就是角度值。具体的效果如下:

在运动中改变角度,其效果和auto也类似,只是方向相反:

<angle>

offset-rotate还有另一个属性值<angle>,他可以是关键词autoreverse的第二个参数,除此之外还可以作为独立的一个参数。如果在offset-rotate属性中没有设置关键词autoreverse,只设置了<angle>的话,运动物体始终会面向相同的方向,而且不会随着路径旋转。比如下面这个示例:

注意,虽然offset-rotate从效果的表像上看和transformrotate有点类似,但这里所描述的旋转不会覆盖或替换transform属性中定义的任何旋转。

定义路径上的锚点(offset-anchor

offset-anchor常被称为路径锚点。我更喜欢把他称为和路径(offset-path绘制的路径)的稳合点。因为它定义了运动物体在沿偏移路径移动的点。在路径动画中,运动物体在默认情况下,其左上角将与路径对齐。但offset-anchor可以改变这个位置点。

我自己更喜欢这样来理解,可能会更好理解一点。

这里所说的运动物体他就是一个元素盒子,在CSS中元素盒子的原点位置一般都是在该盒子的左上角。将该盒子放到路径动画中,那么该盒子将会以路径的为中心。它的行为和我们熟悉的background-positiontransform-origin非常的相似。

offset-anchor属性可以接受两个属性值:auto<position>:

auto

offset-anchor的默认值是auto。如果将offset-anchor设置为auto,它将被赋予和transfrom-origin相同的值,因此我们可以选择使用transform-origin来获得相同的结果。比如下面这个示例:

在上面的示例中,offset-anchor显式的设置了值为auto,我们可以尝试着动态修改transform-origin的值,可以明显的看到运动物体锚点(也可以将其称为变换原点)在路径上的变化:

在上面的示例中,可以尝试在开启动画之后修改transform-origin的值,运动物体在路径上的锚点也会随着改变,而且效果也会有所不同:

offset-anchor取值为auto时,其计算规则一般依据下面的两点来做计算:

  • 如果offset-path为空(none)并且offset-position的值不是auto,那么offset-anchor的计算则会以offset-position来做计算(即取offset-position的值),否则会以transform-origin计算值
  • offset-path的值为none并且offset-anchor的值为auto,那么offset-position的行为类似于background-position

<position>

offset-anchor还可以取值<position>。取值为<position>时,可以使用具体的<length><percentage>两种方式来描述<position>。这个有点类似于我们的background-position,通过x轴和y来描述。

<position>采用的是百分比来描述的话,那和它的计算是根据运动物体(元素)的widthheight来计算,其中x相对于width计算,y相对于height计算。比如我们所说的50%, 50%指的就是我们常说的center(或者center center)。

<position>采用的是具体的长度值,那么它的计算是相对于运动物体(元素)的左上角(顶点位置是0, 0)来计算,其中x是距离左上角顶点的水平位置,y是相对左上角顶点的垂直位置(一般是向下)。

把上面的示例,换成百分比描述的offset-anchor的值:

定义路径上的起始点位置(offset-position

offset-position这部分内容没有完全整明白,接下来的内容来自于W3C规范中

offset-position主要用来指定路径的初始位置。如果CSS的position的值为static,那么offset-position将会被忽略。

offset-position主要接受两个值:auto<position>

auto

如果offset-position取值为auto。路径的初始位置将会使用position属性指定运动物体盒子的位置。

注意,当position取值为static而且offset-position显式的设置了值为auto(不会因为offset-path而被忽略),那么运动物何将会相对正常文档流来定位。

<position>

如果offset-position取值为<position>,指定的初始位置会在包含块作为定位区域,无大小(零大小框)作为目标区域。这有点类似于绝对定位,不同的是,offset-position不会影响到后面的元素的布局。

其中<position>可取值:

<position> = [ [ left | center | right ] || [ top | center | bottom ] | [ left | center | right | <length-percentage> ] [ top | center | bottom | <length-percentage> ]? | [ [ left | right ] <length-percentage> ] && [ [ top | bottom ] <length-percentage> ] ]

具体使用的时候,可以像下面这样使用:

/* Keyword values */
offset-position: auto;
offset-position: top;
offset-position: bottom;
offset-position: left;
offset-position: right;
offset-position: center;

/* <percentage> values */
offset-position: 25% 75%;

/* <length> values */
offset-position: 0 0;
offset-position: 1cm 2cm;
offset-position: 10ch 8em;

/* Edge offsets values */
offset-position: bottom 10px right 20px;
offset-position: right 3em bottom 10px;
offset-position: bottom 10px right;
offset-position: top right 10px;

/* Global values */
offset-position: inherit;
offset-position: initial;
offset-position: unset;

使用的语法和background-position是相似的。

offset-position除了auto之外,其他的值的计算结果都会创建一个层叠上下文和容器块,通常会用于transform中。另外,如果offset-path是一个几何盒(<geometry-box>)或一个基本形状(不包括圆或椭圆),则会忽略offset-position。在这些情况下,<geometry-box>或基本形状指定初始位置。

来看一个简单示例:

事实上,我并没有完全理解出他们之间的差异,而且动态修改<position>的值并没有啥变化:

简写属性offset

offset其实是有点类似于borderpadding这样的属性值,它是offset-positionoffset-pathoffset-distanceoffset-rotateoffset-anchor的缩写属性。如果你喜欢使用缩写属性的话,可以按下面的语法规则来书写:

offset: [ offset-position? [ offset-path [ offset-distance || offset-rotate ]? ]? ]!
[ / offset-anchor ]?

当然,你可以省略你不需要显式设置的值,其中省略的值则会取对应省略属性的初始值。

CSS Motion Path Module属性并不具备动效

虽然说CSS Motion Path Module提供的属性可以让我轻易的实现路径动效。但这里大家必须要知道:

CSS Motion Path Module 提供的任何属性自身是不具备动画效果的,需要借CSS的animationtransition属性,或者是Web Animation API等,才能真正的实现我们所说的路径动效

在前面的示例中,我们看到的都是只改变其中一个或两个属性的动效,接下来这个示例,我们来运用多个属性:

有关于更多相关的示例可以查看@Dan Wilson在Codepen上整理的Demo集

小结

上面提到的都是CSS Motion Path Module中的一些基础知识。虽然说现代主流浏览器(除Safari)都支持offset中的属性,但部分属性的用法也只得到部分支持。比如offset-path,到到目前也仅支持path()语法,而且在W3C规范中提供的案例和示例都在浏览器中跑不起来,这主要因素还是未得到浏览器的全面支持。虽然如此,但这不能阻碍我们去探索和学习相关的知识,而且对于该功能模块肯定还有很多知识值得我们去探索。

如果你对这方面的知识感兴趣的话,还可以阅读下面这些文章,如果你在这方面有较好的经验和建议,欢迎在评论中与我们一起共享: