CSS 中有一个非常有意思的模块 -- CSS Motion Path Module Level 1,翻译过来也就是运动路径。本文将对 motion path 一探究竟,通过本文,你可以了解到:什么是 CSS motion path

使用 CSS motion path 制作简单路径动画

使用 CSS motion path 制作复杂路径动画

什么是 CSS Motion Path 运动路径?

什么是 CSS Motion Path 运动路径?利用这个规范规定的属性,我们可以控制元素按照特定的路径进行位置变换的动画。并且,这个路径可以是非常复杂的一条路径。

在进一步介绍 CSS Motion Path 之前,我们先看看使用传统的 CSS 的能力,我们如何实现路径动画。

CSS 传统方式实现直线路径动画

在之前,我们希望将一个物体从 A 点直线运动到 B 点,通常而言可以使用 transform: translate()、top | left | bottom | right 或者 是 margin 之类的可以改变物体位置的属性。

简单的一个 Demo:

div {

width: 60px;

height: 60px;

background: #000;

animation: move infinite 1s alternate linear;

}

@keyframes move {

100% {

transform: translate(100px, 100px);

}

}

对于简单的从 A 点直线运动到 B 点的效果如下:

CSS 传统方式实现曲线路径动画

当然,CSS 也可以实现一些简单的曲线路径动画的。如果我们希望从 A 点运动到 B 点走的不是一条直线,而是一条曲线,该怎么做呢?

对于一些简单的圆弧曲线路径,还是可以借助一些巧妙的办法实现的,看看下面这个例子。

这次,我们使用了两个元素,子元素是希望被曲线运动的小球,但是实际上我们是通过设定了父元素的 transform-origin,让父元素进行了一个 transform: rotate() 的运动带动了子元素的小球:

position: relative;

width: 10vmin;

height: 70vmin;

transform-origin: center 0;

animation: rotate 1.5s infinite alternate;

}

.g-ball {

position: absolute;

width: 10vmin;

height: 10vmin;

border-radius: 50%;

background: radial-gradient(circle, #fff, #000);

bottom: 0;

left: 0;

}

@keyframes rotate {

100% {

transform: rotate(90deg);

}

}

为了方便理解,在运动的过程中,我让父元素的轮廓显现出来:

这样,我们算是勉强得到了一个非直线路径运动动画,它的实际运动轨迹是一条曲线。

然而,这基本上是之前 CSS 能做到的极限了,使用纯 CSS 的方法,没办法实现更复杂的路径动画,譬如下面这样一条路径动画:

直到现在,我们有了一种更为强大的专门做这个事情的规范,也就是本文的主角 -- CSS Motion Path。

CSS Motion Path 实现直线路径动画

CSS Motion Path 规范主要包含以下几个属性:offset-path:接收一个 SVG 路径(与 SVG 的path、CSS 中的 clip-path 类似),指定运动的几何路径

offset-distance:控制当前元素基于 offset-path 运动的距离

offset-position:指定 offset-path 的初始位置

offset-anchor:定义沿 offset-path 定位的元素的锚点。 这个也算好理解,运动的元素可能不是一个点,那么就需要指定元素中的哪个点附着在路径上进行运动

offset-rotate:定义沿 offset-path 定位时元素的方向,说人话就是运动过程中元素的角度朝向

下面,我们使用 Motion Path 实现一个简单的直线位移动画。

div {

width: 60px;

height: 60px;

background: linear-gradient(#fc0, #f0c);

offset-path: path("M 0 0 L 100 100");

offset-rotate: 0deg;

animation: move 2000ms infinite alternate ease-in-out;

}

@keyframes move {

0% {

offset-distance: 0%;

}

100% {

offset-distance: 100%;

}

}

offset-path 接收一个 SVG 的 path 路径,这里我们的路径内容是一条自定义路径 path("M 0 0 L 100 100"),翻译过来就是从 0 0 点运动到 100px 100px 点。offset-path 接收一个 SVG 路径,指定运动的几何路径。与 SVG 的path、CSS 中的 clip-path 类似,对于这个 SVG Path 还不太了解的可以戳这里先了解下 SVG 路径内容:SVG 路径

我们会得到如下结果:

通过控制元素的 offset-distance 从 0% 变化到 100% 进行元素的路径动画。

当然,上述的动画是最基本的,我可以充分利用 path 的特性,增加多个中间关键帧,稍微改造下上述代码:div {

// 只改变运动路径,其他保持一致

offset-path: path("M 0 0 L 100 0 L 200 0 L 300 100 L 400 0 L 500 100 L 600 0 L 700 100 L 800 0");

animation: move 2000ms infinite alternate linear;

}

@keyframes move {

0% {

offset-distance: 0%;

}

100% {

offset-distance: 100%;

}

}

这里最主要还是运用了 path 中的 L 指令,得到了如下图这样一条直线路径:

最终的效果如下,与利用 transform: translate() 添加多个关键帧类似:

CSS Motion Path 实现曲线路径动画

上面的运动轨迹都是由直线构成,下面我们看看如何使用 CSS Motion Path 实现曲线路径动画。

其实原理还是一模一样,只需要在 offset-path: path() 中添加曲线相关的路径即可。

在 SVG 的 Path 中,我们取其中一种绘制曲线的方法 -- 贝塞尔曲线,譬如下述这条 path,其中的 path 为 d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80":

对应这样一条连续的贝塞尔曲线:

将对应的路径应用在 offset-path: path 中:

div:nth-child(2) {

width: 40px;

height: 40px;

background: linear-gradient(#fc0, #f0c);

offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');

}

@keyframes move {

0% {

offset-distance: 0%;

}

100% {

offset-distance: 100%;

}

}

可以得到如下运动效果:

可以看到,元素是沿着贝塞尔曲线的路径进行运动的,并且,由于这次没有限制死 offset-rotate,元素的朝向也是跟随路径的朝向一直变化的。(可以联想成开车的时候,车头一直跟随道路会进行变化的,带动整个车身的角度变化)

理解 offset-anchor 运动锚点

OK,那么接下来,我们再看看 offset-anchor 如何理解。

还是上述的 DEMO,我们把小正方形替换成一个三角形,并且把运动的曲线给画到页面上,像是这样:

其中,三角形是通过 clip-path 实现的:width: 40px;

height: 40px;

clip-path: polygon(0 0, 100% 50%, 0 100%);

background: linear-gradient(#fc0, #f0c);

通常而言,沿着曲线运动的是物体的中心点(类比 transform-origin),在这里,我们可以通过 offset-anchor 改变运动的锚点,譬如,我们希望三角形的最下方沿着曲线运动:.ball {

width: 40px;

height: 40px;

clip-path: polygon(0 0, 100% 50%, 0 100%);

offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');

offset-anchor: 0 100%;

background: linear-gradient(#fc0, #f0c);

animation: move 3000ms infinite alternate linear;

}

@keyframes move {

0% {

offset-distance: 0%;

}

100% {

offset-distance: 100%;

}

}

经过实测,Can i use 上写着 offset-anchor 属性的兼容性在为 Chrome 79+、Firefox 72+,但是实际只有 Firefox 支持,Chrome 下暂时无法生效~

运用 Motion Path 制作动画效果

OK,上面我们基本把原理给过了一遍,下面我们就看看,运用 Motion Path,可以在实践中如何运用。

利用 Motion Path 制作按钮效果

利用运动路径,我们可以制作一些简单的按钮点击效果。在之前,我在 CodePen 上见到过这样一种按钮点击效果:

其原理是运用了 background-radial 去生成每一个小圆点,通过控制 background-position 控制小圆点的位移,详细的 Demo 代码你可以戳这里:

但是小圆点的运动路径基本上都是直线,运用本文的 Motion Path,我们也可以实现一些类似的效果,核心代码如下,HTML 这里我们使用了 Pug 模板,CSS 使用了 SASS:.btn

-for(var i=0; i<60; i++)

span.dot.btn {

position: relative;

padding: 1.5rem 4.5rem;

}

.btn .dot {

position: absolute;

width: 4px;

height: 4px;

@for $i from 1 through $count {

&:nth-child(#{$i}) {

top: 50%;

left: 50%;

transform: translate3d(-50%, -50%, 0) rotate(#{360 / $count * $i}deg);

}

}

&::before {

content: "";

position: absolute;

top: 0;

left: 0;

width: 4px;

height: 4px;

border-radius: 50%;

offset-path: path("M0 1c7.1 0 10.7 2 14.3 4s7.1 4 14.3 4 10.7-2 14.3-4 7.2-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4 10.7-2 14.3-4 7.1-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4 10.7-2 14.3-4 7.1-4 14.3-4 10.7 2 14.3 4 7.1 4 14.3 4");

offset-distance: 0;

}

}

.btn.is-animating:active .dot:nth-child(4n+1)::before {

animation: dot var(--animation-time) var(--animation-timging-function);

}

.btn.is-animating:active .dot:nth-child(4n+2)::before {

border: 1px solid var(--color-primary);

background: transparent;

animation: dot var(--animation-time) var(--animation-timging-function) 0.1s;

}

.btn.is-animating:active .dot:nth-child(4n+3)::before {

animation: dot var(--animation-time) var(--animation-timging-function) 0.2s;

}

.btn.is-animating:active .dot:nth-child(4n)::before {

border: 1px solid var(--color-primary);

background: transparent;

animation: dot var(--animation-time) var(--animation-timging-function) 0.3s;

}

@keyframes dot {

0% {

offset-distance: 0%;

opacity: 1;

}

90% {

offset-distance: 60%;

opacity: .5;

}

100% {

offset-distance: 100%;

opacity: 0;

}

}

别看代码多有一点点复杂,但是不难理解,本质就是给每个子元素小点点设置同样的 offset-path: path(),给不同分组下的子元素设定不同的旋转角度,并且利用了动画延迟 animation-delay 设定了 4 组同时出发的动画。

这里我们的轨迹 path 不是直线,效果如下:

完整的代码你可以戳这里:

利用 Motion-Path 绘制地图路径寻路动画

这个也是非常实用的,现在我们可以完全利用 CSS Motion-Path 实现地图上的寻路动画:

该 Demo 源自 Ahmad Emran,完整的代码你可以戳这里:

利用 Motion-Path 绘制路径动画

又或者,我们利用 Path 能绘制任意路径的特性,实现各种我们想要的路径,譬如加入购物车的抛物线,或者各类运动轨迹,都不在话下,这里再提供一个 Demo:

Can i Use - Motion-Path

来看看 Motion-Path 目前的兼容性如何?截止至 2021-04-27。

目前而言,除去 IE 浏览器,就等待 Safari 何时能够兼容了,具体是否使用,还需要根据目标群体浏览器使用情况进行取舍。

最后

好了,本文到此结束,介绍了运动路径动画 Motion Path,并且利用它实现了一些以往无法简单实现的路径动画效果,希望对你有帮助 :)

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻

html5 路径运动,探秘神奇的运动路径动画 Motion Path相关推荐

  1. Web动画API教程:可爱的运动路径(Motion Path)

    这是介绍浏览器中web动画API的系列教程的第五篇.如果你有什么问题/想法,或者发现我理解错了规范的内容,或是希望我在接下来的文章中对某部分内容进行探讨的话,请在Twitter给我留言吧~@dancw ...

  2. Python数据清洗:strava运动跑步和骑行路径路线经纬度散点序列数据

    在这这个链接中(https://download.csdn.net/download/zhangphil/13614362),离线下载数据文件,这是strava一个在线的运动跑步和骑行路径路线经纬度散 ...

  3. HTML5+CSS期末大作业:运动体育网站设计主题——体育铅球(5页)带注册 期末作业HTML代码

    学生网页课程设计期末作业下载 web网页设计制作成品- 详情介绍 常见网页设计作业题材有 个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. 茶叶. 家居. 酒店. 舞蹈. 动漫. 明星. ...

  4. HTML5+CSS期末大作业:运动体育网站设计主题——体育铅球(5页)带注册 期末作业HTML代码 学生网页课程设计期末作业下载 web网页设计制作成品...

    常见网页设计作业题材有 ​​个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. 茶叶. 家居. 酒店. 舞蹈. 动漫. 明星. 服装. 体育. 化妆品. 物流. 环保. 书籍. 婚纱. 军 ...

  5. php3D动画,html5的canvas实现几何模型3D运动动画效果

    html5的canvas实现几何模型3D运动动画效果 JS片段: var {atan2,sqrt,sin,cos,PI,acos} = Math; function project3D(x,y,z,v ...

  6. 路径与轨迹、路径规划与轨迹规划、路径跟踪与轨迹跟踪

    对于无人车辆来说,全局路径点只要包含空间位置信息即可,也可以包含姿态信息,而不需要与时间相关,但局部规划时,则可以考虑时间信息.这里规定轨迹点也是一种路径点,即当路径点信息中加入时间约束,就可以被称为 ...

  7. 无人驾驶路径规划(三)局部路径规划-Frenet坐标系下的动态轨迹规划

    前言:对于无人驾驶路径规划系列的第二篇RRT算法的改进部分,由于有些内容属于个人想到的创新点,有想法投一篇小论文所以暂时没有公开,等后续完成后我会再公开介绍.今天第三篇内容开启一个新的算法介绍:Fre ...

  8. 自动驾驶路径规划——基于概率采样的路径规划算法(RRT、RRT*)

    目录 1. RRT算法背景 1.1 RRT算法核心思想 1.2 RRT算法优缺点 2. 经典RRT算法 2.1 RRT算法流程 2.2 RRT伪代码 3. 基于目标概率采样 4. RRT*算法 4.1 ...

  9. 自动驾驶路径规划——基于概率采样的路径规划算法(PRM)

    目录 1. PRM算法流程 1.1 预处理 1.2 搜索 2. PRM算法案例 2.1 构型采样 2.2 邻域计算 2.3 图搜索(A*搜索) 3. 采样数量的影响 4. 采样策略 4.1 基于障碍物 ...

最新文章

  1. wampserver搭建本地服务器
  2. Java消息系统简单设计与实现
  3. 03_Weblogic之配置简单域:启动和配置域,使用模板创建域,使用控制台
  4. 07_QueueWithTwoStacks
  5. MVC视图之间调用方法总结
  6. try...catch...finally java
  7. Django DEBUG=False
  8. 静态/动态注冊广播的差别
  9. pgsql 9.4修改数据库只读
  10. Redux零碎知识点回顾
  11. java如何抽离_「小程序JAVA实战」 小程序抽离公用方法进行模块化(12)
  12. DIV+CSS两种盒子模型
  13. 块截断编码图像压缩技术
  14. [转载]autorun.inf病毒源代码
  15. android视频适配与裁剪
  16. 深度学习7日入门-CV疫情特辑心得
  17. 如何让Python画笔画一个圆
  18. Excel如何给数字拼接加双引号或者加单引号加逗号
  19. 微信域名防封技术,微信域名防封解决方案
  20. 数据结构与算法 -- 树结构与图结构

热门文章

  1. C++ 学习笔记之---类的自动转换
  2. 如何哄骗文艺青年安装Node.js? 将网易云音乐灰色歌曲变亮
  3. 爱尔兰拥抱数字货币和互联网金融解决方案
  4. 关于spring boot启动报Error creating bean with name ‘XXX‘ defined in file异常
  5. Arcgis画等高线
  6. Nginx的重写功能——Rewrite
  7. 智能远传水表管理解决方案
  8. c语言 system(pause)为什么报错,c语言-指针-分配内存和赋值需要注意的
  9. python3 自定义排序函数_Python自定义排序函数
  10. R语言作图不显示中文解决办法,如何使用中文字体