探秘神奇的运动路径动画 Motion Path
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>
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()
的运动带动了子元素的小球:
<div class="g-container">
<div class="g-ball"></div>
</div>
.g-container {
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>
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()
添加多个关键帧类似:
完整的 Demo 你可以戳这里:CodePen Demo -- CSS Motion Path Demo
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"
:
<svg width="400" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80" stroke="black" fill="transparent"/>
</svg>
对应这样一条连续的贝塞尔曲线:
将对应的路径应用在 offset-path: path
中:
<div>
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
,元素的朝向也是跟随路径的朝向一直变化的。(可以联想成开车的时候,车头一直跟随道路会进行变化的,带动整个车身的角度变化)
完整的 Demo 你可以戳这里:CodePen Demo -- CSS Motion Path Demo
理解 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 下暂时无法生效~
完整的 Demo 你可以戳这里:CodePen Demo -- CSS Motion Path offset-anthor Demo
运用 Motion Path 制作动画效果
OK,上面我们基本把原理给过了一遍,下面我们就看看,运用 Motion Path,可以在实践中如何运用。
利用 Motion Path 制作按钮效果
利用运动路径,我们可以制作一些简单的按钮点击效果。在之前,我在 CodePen 上见到过这样一种按钮点击效果:
其原理是运用了 background-radial
去生成每一个小圆点,通过控制 background-position
控制小圆点的位移,详细的 Demo 代码你可以戳这里:
CodePen Demo -- Bubbly button (Design by Gal Shir)
但是小圆点的运动路径基本上都是直线,运用本文的 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 不是直线,效果如下:
完整的代码你可以戳这里:
CodePen Demo -- Button Animation with CSS Offset Paths
利用 Motion-Path 绘制地图路径寻路动画
这个也是非常实用的,现在我们可以完全利用 CSS Motion-Path 实现地图上的寻路动画:
该 Demo 源自 Ahmad Emran,完整的代码你可以戳这里:
CodePen Demo -- CodePen Home Animation with offset-path | Only Using CSS & HTML
利用 Motion-Path 绘制路径动画
又或者,我们利用 Path 能绘制任意路径的特性,实现各种我们想要的路径,譬如加入购物车的抛物线,或者各类运动轨迹,都不在话下,这里再提供一个 Demo:
CodePen Demo -- CSS Motion Path offset-path animation
Can i Use - Motion-Path
来看看 Motion-Path 目前的兼容性如何?截止至 2021-04-27。
目前而言,除去 IE 浏览器,就等待 Safari 何时能够兼容了,具体是否使用,还需要根据目标群体浏览器使用情况进行取舍。
最后
好了,本文到此结束,介绍了运动路径动画 Motion Path,并且利用它实现了一些以往无法简单实现的路径动画效果,希望对你有帮助
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
探秘神奇的运动路径动画 Motion Path的更多相关文章
- WPF编程,通过Path类型制作沿路径运动的动画一种方法。
原文:WPF编程,通过Path类型制作沿路径运动的动画一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/de ...
- WPF编程,通过Path类型制作沿路径运动的动画另一种方法。
原文:WPF编程,通过Path类型制作沿路径运动的动画另一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/d ...
- Silverlight & Blend动画设计系列十一:沿路径动画(Animation Along a Path)
Silverlight 提供一个好的动画基础,但缺少一种方便的方法沿任意几何路径对象进行动画处理.在Windows Presentation Foundation中提供了动画处理类DoubleAnim ...
- 沿路径动画(Animation Along a Path)
Silverlight 提供一个好的动画基础,但缺少一种方便的方法沿任意几何路径对象进行动画处理.在Windows Presentation Foundation中提供了动画处理类DoubleAnim ...
- 通通玩blend美工(8)——动态绘制路径动画,画出个萌妹子~
原文:通通玩blend美工(8)--动态绘制路径动画,画出个萌妹子~ 2年前我在玩Flex的时候就一直有一个疑问,就是如何来实现一个蚊香慢慢烧完的Loading动画呢? 刚经历了某甲方高强度一个月的洗 ...
- WPF中的PathAnimation(路径动画)
原文:WPF中的PathAnimation(路径动画) WPF中的PathAnimation(路径动画) ...
- WPF 精修篇 路径动画
原文:WPF 精修篇 路径动画 路径动画 是让一个对象围绕指定Path 的运动路径 进行移动的动画 举栗子 路径动画 使用 Blend 来设置 是十分简单的 首先用工具 笔 点出一条线 新建一个圆形 ...
- osg 路径 动画 效果
osg 路径 动画 效果 转自:http://blog.csdn.net/zhuyingqingfen/article/details/8248157 #include <osg/Group&g ...
- WPF动画之路径动画(3)
XAML代码: <Window x:Class="路径动画.MainWindow" xmlns="http://schemas.microsoft.com/winf ...
随机推荐
- Vue3.0+Electron聊天室|electron跨平台仿QQ客户端|vue3.x聊天应用
基于vue3+electron11跨端仿制QQ桌面应用实战Vue3ElectronQchat. 使用vue3+electron+vuex4+ant-design-vue+v3scroll+v3laye ...
- 并发\并行,同步\异步,阻塞\非阻塞,IO多路复用解释
并发.并行 并发:是指一个时间段内,有几个程序在同一个CPU上运行,但是任意时刻只有一个程序在CPU上运行.由于CPU的运行速度极快,可以在多个程序之间切换,这样造成一个假象就是多个程序同时在运行.并 ...
- 如何理解JavaScript中的函数
转: 如何理解JavaScript中的函数 JS中的函数简介 JS中的函数是一种通过调用来完成具体业务的一段代码块.最核心的目的是将可重复执行的操作进行封装,然后供调用方无限制的调用. JS中的函数的 ...
- C++类的静态成员笔记
下面是C++类的静态成员笔记. 静态数据成员特征 用关键字static声明 为该类的所有对象共享,静态数据成员具有静态生存期 必须在类外定义和初始化,用(::)来指明所属的类 举例说明-具有静态数据成 ...
- MongoDB -> kafka 高性能实时同步(sync 采集)mongodb数据到kafka解决方案
写这篇博客的目的 让更多的人了解 阿里开源的MongoShake可以很好满足mongodb到kafka高性能高可用实时同步需求(项目地址:https://github.com/alibaba/Mong ...
- css整理之-----------技巧、黑魔法
css 看起来比较简单,但是要想做的好也不是那么容易,我们在平时开发中,主要用css 来美化我们的html结构,所有我觉得css 还是挺重要的,这里记录整理一些关于css 的技巧以及容易忘记的知识点. ...
- 用水浒传来学习OKR
用水浒传来学习OKR 目录 用水浒传来学习OKR 0x00 摘要 0x01 OKR 1.1 基本概念 1.2 OKR管理的意义 1.3 Objective 1.3.1 什么是好的O 1.3.2 上下级 ...
- Flask模板注入
Flask模板注入 Flask模板注入漏洞属于经典的SSTI(服务器模板注入漏洞). Flask案例 一个简单的Flask应用案例: from flask import Flask,render_te ...
- PTA 统计二叉树结点个数
6-1 统计二叉树结点个数 (10 分) 本题要求实现一个函数,可统计二叉树的结点个数. 函数接口定义: int NodeCount ( BiTree T); T是二叉树树根指针,函数NodeCo ...
- springBoot高级:自动配置分析,事件监听,启动流程分析,监控,部署
知识点梳理 课堂讲义 02-SpringBoot自动配置-@Conditional使用 Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载 ...