探秘神奇的运动路径动画MotionPath

CSS 中有一个非常有意思的模块 -- CSS Motion Path Module Level 1[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:

  
 
 
 
  1.  

  
 
 
 
  1. div { 
  2.     width: 60px; 
  3.     height: 60px; 
  4.     background: #000; 
  5.     animation: move infinite 1s alternate linear; 
  6. @keyframes move { 
  7.     100% { 
  8.         transform: translate(100px, 100px); 
  9.     } 

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

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

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

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

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

  
 
 
 
  1.  
  2.     
 
  •  
      
     
     
     
    1. .g-container { 
    2.     position: relative; 
    3.     width: 10vmin; 
    4.     height: 70vmin; 
    5.     transform-origin: center 0; 
    6.     animation: rotate 1.5s infinite alternate; 
    7. .g-ball { 
    8.     position: absolute; 
    9.     width: 10vmin; 
    10.     height: 10vmin; 
    11.     border-radius: 50%; 
    12.     background: radial-gradient(circle, #fff, #000); 
    13.     bottom: 0; 
    14.     left: 0; 
    15. @keyframes rotate { 
    16.     100% { 
    17.         transform: rotate(90deg); 
    18.     } 

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

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

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

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

    CSS Motion Path 实现直线路径动画

    CSS Motion Path 规范主要包含以下几个属性:

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

       
     
     
     
    1.  

       
     
     
     
    1. div { 
    2.     width: 60px; 
    3.     height: 60px; 
    4.     background: linear-gradient(#fc0, #f0c); 
    5.     offset-path: path("M 0 0 L 100 100"); 
    6.     offset-rotate: 0deg; 
    7.     animation: move 2000ms infinite alternate ease-in-out; 
    8. @keyframes move { 
    9.     0% { 
    10.         offset-distance: 0%; 
    11.     } 
    12.     100% { 
    13.         offset-distance: 100%; 
    14.     } 

    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 路径[2]

    我们会得到如下结果:

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

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

       
     
     
     
    1. div { 
    2.     // 只改变运动路径,其他保持一致 
    3.     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"); 
    4.     animation: move 2000ms infinite alternate linear; 
    5. @keyframes move { 
    6.     0% { 
    7.         offset-distance: 0%; 
    8.     } 
    9.     100% { 
    10.         offset-distance: 100%; 
    11.     } 

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

    image

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

    完整的 Demo 你可以戳这里:CodePen Demo -- CSS Motion Path Demo[3]

    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":

       
     
     
     
    1.  
    2.    
    3.  

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

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

        
     
     
     
    1.  

        
     
     
     
    1. div:nth-child(2) { 
    2.     width: 40px; 
    3.     height: 40px; 
    4.     background: linear-gradient(#fc0, #f0c); 
    5.     offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80'); 
    6. @keyframes move { 
    7.     0% { 
    8.         offset-distance: 0%; 
    9.     } 
    10.     100% { 
    11.         offset-distance: 100%; 
    12.     } 

    可以得到如下运动效果:

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

    完整的 Demo 你可以戳这里:CodePen Demo -- CSS Motion Path Demo[4]

    理解 offset-anchor 运动锚点

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

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

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

        
     
     
     
    1. width: 40px; 
    2.  height: 40px; 
    3.  clip-path: polygon(0 0, 100% 50%, 0 100%); 
    4.  background: linear-gradient(#fc0, #f0c); 

     

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

        
     
     
     
    1. .ball { 
    2.     width: 40px; 
    3.     height: 40px; 
    4.     clip-path: polygon(0 0, 100% 50%, 0 100%); 
    5.     offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80'); 
    6.     offset-anchor: 0 100%; 
    7.     background: linear-gradient(#fc0, #f0c); 
    8.     animation: move 3000ms infinite alternate linear; 
    9. @keyframes move { 
    10.     0% { 
    11.         offset-distance: 0%; 
    12.     } 
    13.     100% { 
    14.         offset-distance: 100%; 
    15.     } 

     

    完整的 Demo 你可以戳这里:CodePen Demo -- CSS Motion Path offset-anthor Demo[5]

    运用 Motion Path 制作动画效果

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

    利用 Motion Path 制作按钮效果

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

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

    CodePen Demo -- Bubbly button (Design by Gal Shir)[6]

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

        
     
     
     
    1. .btn 
    2.   -for(var i=0; i<60; i++) 
    3.     span.dot 

        
     
     
     
    1. .btn { 
    2.   position: relative; 
    3.   padding: 1.5rem 4.5rem; 
    4. .btn .dot { 
    5.   position: absolute; 
    6.   width: 4px; 
    7.   height: 4px; 
    8.    
    9.   @for $i from 1 through $count {  
    10.     &:nth-child(#{$i}) { 
    11.         top: 50%; 
    12.         left: 50%; 
    13.         transform: translate3d(-50%, -50%, 0) rotate(#{360 / $count * $i}deg); 
    14.       } 
    15.   } 
    16.    
    17.   &::before { 
    18.     content: ""; 
    19.     position: absolute; 
    20.     top: 0; 
    21.     left: 0; 
    22.     width: 4px; 
    23.     height: 4px; 
    24.     border-radius: 50%; 
    25.     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"); 
    26.     offset-distance: 0; 
    27.   } 
    28.  
    29. .btn.is-animating:active .dot:nth-child(4n+1)::before { 
    30.   animation: dot var(--animation-time) var(--animation-timging-function); 
    31. .btn.is-animating:active .dot:nth-child(4n+2)::before { 
    32.   border: 1px solid var(--color-primary); 
    33.   background: transparent; 
    34.   animation: dot var(--animation-time) var(--animation-timging-function) 0.1s; 
    35. .btn.is-animating:active .dot:nth-child(4n+3)::before { 
    36.   animation: dot var(--animation-time) var(--animation-timging-function) 0.2s; 
    37. .btn.is-animating:active .dot:nth-child(4n)::before { 
    38.   border: 1px solid var(--color-primary); 
    39.   background: transparent; 
    40.   animation: dot var(--animation-time) var(--animation-timging-function) 0.3s; 
    41.  
    42. @keyframes dot { 
    43.   0% { 
    44.     offset-distance: 0%; 
    45.     opacity: 1; 
    46.   } 
    47.   90% { 
    48.     offset-distance: 60%; 
    49.     opacity: .5; 
    50.   } 
    51.   100% { 
    52.     offset-distance: 100%; 
    53.     opacity: 0; 
    54.   } 

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

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

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

    CodePen Demo -- Button Animation with CSS Offset Paths[7]

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

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

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

    CodePen Demo -- CodePen Home Animation with offset-path | Only Using CSS & HTML[8]

    利用 Motion-Path 绘制路径动画

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

    CodePen Demo -- CSS Motion Path offset-path animation[9]

    Can i Use - Motion-Path

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

    Can i Use - Motion-Path[10]:

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

    最后

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

    更多精彩 CSS 技术文章汇总在我的 Github -- iCSS[11] 。

    参考资料

    [1]CSS Motion Path Module Level 1:

    https://drafts.fxtf.org/motion-1/

    [2]SVG 路径:

    https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Paths

    [3]CodePen Demo -- CSS Motion Path Demo:

    https://codepen.io/Chokcoco/pen/gOgqoem

    [4]CodePen Demo -- CSS Motion Path Demo:

    https://codepen.io/Chokcoco/pen/gOgqoem

    [5]CodePen Demo -- CSS Motion Path offset-anthor Demo:

    https://codepen.io/Chokcoco/pen/poRGZeE

    [6]CodePen Demo -- Bubbly button (Design by Gal Shir):

    https://codepen.io/Chokcoco/pen/bGGMLdd

    [7]CodePen Demo -- Button Animation with CSS Offset Paths:

    https://codepen.io/Chokcoco/pen/xxgMPzJ

    [8]CodePen Demo -- CodePen Home Animation with offset-path | Only Using CSS & HTML:

    https://codepen.io/ahmadbassamemran/pen/bXByBv

    [9]CodePen Demo -- CSS Motion Path offset-path animation:

    https://codepen.io/Chokcoco/pen/dyNaZea

    [10]Can i Use - Motion-Path:

    https://caniuse.com/?search=motion%20path

    [11]Github -- iCSS:

    https://github.com/chokcoco/iCSS

    分享标题:探秘神奇的运动路径动画MotionPath
    网站网址:http://www.shufengxianlan.com/qtweb/news49/85849.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

    猜你还喜欢下面的内容

    域名注册知识

    同城分类信息