CSS 모션 경로 모듈이란 무엇인가요? 이 기사에서는 CSS 모션 경로 모듈에 대해 자세히 알아보고 사용법에 대해 이야기하며 이 모듈을 사용하여 간단하고 복잡한 경로 애니메이션을 만드는 방법을 소개합니다.
CSS에는 모션 경로로 변환되는 매우 흥미로운 모듈인 CSS 모션 경로 모듈 레벨 1이 있습니다. 이 문서에서는 모션 경로에 대해 자세히 살펴보겠습니다.
이전에는 객체를 A 지점에서 B 지점으로 직선으로 이동하려고 했습니다. 일반적으로 transform:transform()
을 사용할 수 있습니다. >, 왼쪽 상단 |오른쪽 하단
또는 margin
및 개체의 위치를 변경할 수 있는 기타 속성입니다.
간단한 데모:
<div></div>
div { width: 60px; height: 60px; background: #000; animation: move infinite 1s alternate linear; } @keyframes move { 100% { transform: translate(100px, 100px); } }
transform: translate()
、top | left | bottom | right
或者 是 margin
之类的可以改变物体位置的属性。
简单的一个 Demo:
<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); } }
对于简单的从 A 点直线运动到 B 点的效果如下:
当然,CSS 也可以实现一些简单的曲线路径动画的。如果我们希望从 A 点运动到 B 点走的不是一条直线,而是一条曲线,该怎么做呢?
对于一些简单的圆弧曲线路径,还是可以借助一些巧妙的办法实现的,看看下面这个例子。
这次,我们使用了两个元素,子元素是希望被曲线运动的小球,但是实际上我们是通过设定了父元素的 transform-origin
,让父元素进行了一个 transform: rotate()
的运动带动了子元素的小球:
<div></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%; } }
为了方便理解,在运动的过程中,我让父元素的轮廓显现出来:
这样,我们算是勉强得到了一个非直线路径运动动画,它的实际运动轨迹是一条曲线。
然而,这基本上是之前 CSS 能做到的极限了,使用纯 CSS 的方法,没办法实现更复杂的路径动画,譬如下面这样一条路径动画:
直到现在,我们有了一种更为强大的专门做这个事情的规范,也就是本文的主角 -- 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 { // 只改变运动路径,其他保持一致 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%; } }
<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
接收一个 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%
곡선 경로 애니메이션을 구현하는 CSS의 전통적인 방법
transform-origin
을 설정했습니다. 상위 요소는 변환을 수행합니다. transform:rotate()
의 움직임은 하위 요소의 공을 구동합니다: 🎜<div></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-path
: SVG 경로 수신(SVG 경로와 유사, CSS(유사) 클립 경로), 모션의 기하학적 경로 지정🎜🎜offset-distance
: offset-path
🎜🎜offset을 기반으로 현재 요소의 거리를 제어합니다. -position
: offset-path
의 초기 위치를 지정합니다. 🎜🎜offset-anchor
: offset-path를 따라 위치한 요소의 앵커 포인트를 정의합니다.
. 이는 이해하기 쉽습니다. 움직이는 요소는 점이 아닐 수 있으므로 요소의 어느 점이 이동 경로에 연결되는지 지정해야 합니다.🎜🎜offset-rotate
: 를 따라 정의합니다. offset-path
인간의 관점에서 위치 지정 중 요소의 방향은 이동 중 요소의 각도 방향입니다. 🎜🎜🎜 아래에서는 Motion Path를 사용하여 간단한 선형 변위 애니메이션을 구현합니다. 🎜width: 40px; height: 40px; clip-path: polygon(0 0, 100% 50%, 0 100%); background: linear-gradient(#fc0, #f0c);
.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%; } }
offset-path
는 SVG 경로를 수신합니다. 여기서 경로 콘텐츠는 사용자 정의 경로 path("M 0 0 L 100 100")
입니다. 번역 0 0
지점에서 100px 100px
지점으로 이동하세요. 🎜offset-path
는 SVG 경로를 수신하여 모션의 기하학적 경로를 지정합니다. CSS의 SVG 경로 및 클립 경로와 유사하며, 이 SVG 경로에 대해 잘 모르는 경우 여기를 클릭하여 SVG 경로 내용에 대해 알아볼 수 있습니다. SVG 경로
🎜다음 결과를 얻을 수 있습니다.🎜 🎜🎜🎜제어하여 요소의 offset-distance
가 0%
에서 100%
로 변경되어 요소의 경로에 애니메이션을 적용합니다. 🎜🎜물론, 위의 애니메이션은 가장 기본적인 경로의 특성을 최대한 활용하고 여러 중간 키 프레임을 추가하고 위의 코드를 약간 수정할 수 있습니다. 🎜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
地址:https://codepen.io/Chokcoco/pen/gOgqoem
上面的运动轨迹都是由直线构成,下面我们看看如何使用 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" style="max-width:90%" 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>
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
地址:https://codepen.io/Chokcoco/pen/gOgqoem
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
地址:https://codepen.io/Chokcoco/pen/poRGZeE
OK,上面我们基本把原理给过了一遍,下面我们就看看,运用 Motion Path,可以在实践中如何运用。
利用运动路径,我们可以制作一些简单的按钮点击效果。在之前,我在 CodePen 上见到过这样一种按钮点击效果:
其原理是运用了 background-radial
去生成每一个小圆点,通过控制 background-position
控制小圆点的位移
详细的 Demo 代码:CodePen Demo -- Bubbly button (Design by Gal Shir)
地址:https://codepen.io/Chokcoco/pen/bGGMLdd
但是小圆点的运动路径基本上都是直线,运用本文的 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 데모 -- CSS 오프셋 경로가 포함된 버튼 애니메이션
주소: https://codepen.io/Chokcoco/pen/xxgMPzJ
이것은 또한 매우 실용적입니다. 이제 CSS Motion-Path를 완전히 활용하여 지도에서 길 찾기 애니메이션을 구현할 수 있습니다.
이 데모는 Ahmad Emran에서 제공됩니다. 전체 코드: CodePen Demo - CodePen Home Animation with offset-path | CSS 및 HTML만 사용
주소: https://codepen.io/ahmadbassamemran/pen/bXByBv
또는 Path를 사용하여 무엇이든 그릴 수 있습니다. 경로의 특성은 장바구니에 추가된 포물선이나 다양한 모션 궤적과 같이 우리가 원하는 다양한 경로를 실현할 수 있습니다. 다음은 또 다른 데모입니다:
CodePen Demo -- CSS Motion Path offset-path animation
주소: https://codepen.io/Chokcoco/pen/dyNaZea
현재 Motion-Path의 호환성을 살펴볼까요? 2021-04-27 기준.
사용 가능 - Motion-Path:
현재 IE 브라우저와는 별개로, 대상 그룹의 브라우저 사용량에 따라 Safari가 언제 호환될지 기다리고 있습니다.
그럼 이번 글은 여기서 마치겠습니다. 모션 경로 애니메이션 Motion Path를 소개하고, 이를 사용하여 과거에는 쉽게 얻을 수 없었던 몇 가지 경로 애니메이션 효과를 구현하는 데 도움이 되기를 바랍니다. :)
이 기사에서 재인쇄됨 출처: https://segmentfault.com/a/1190000039916159
저자: chokcoco
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 비디오를 방문하세요! !
위 내용은 CSS 모션 경로 모듈이란 무엇입니까? 모션 경로에 애니메이션을 적용하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!