共计 6483 个字符,预计需要花费 17 分钟才能阅读完成。
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。
Can i Use – Motion-Path:
目前而言,除去 IE 浏览器,就期待 Safari 何时可能兼容了,具体是否应用,还须要依据目标群体浏览器应用状况进行取舍。
最初
好了,本文到此结束,介绍了静止门路动画 Motion Path,并且利用它实现了一些以往无奈简略实现的门路动画成果,心愿对你有帮忙 :)
想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 😄
更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。
如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。