css - 路径动画知多少

42 阅读5分钟

一、css 路径动画

咱做网页的时候,是不是总觉得动画差点意思?按钮只会上下跳,图片只会淡入淡出,跟 “老年迪斯科” 似的没劲儿~

今天给大家介绍 CSS 路径动画 —— 这玩意儿简直是网页 “气氛组天花板”!能让云朵沿着曲线飘,让小车顺着赛道跑,甚至能让文字绕着圈跳舞,瞬间让静态页面活过来!

今天就带大家从零搞懂路径动画,代码直接抄,看完包你学会 “指挥” 元素在网页里 “自由飞翔”~

二、基础入门:就俩核心属性,别被名字吓住!

很多人一看到 “路径动画” 就觉得高深,其实核心就俩 CSS 属性,记住它们俩,你就赢了一半!

(一)俩 “主角” 属性:offset-path 和 offset-distance

先上最简单的代码,感受下魔法:

/* 让小球沿着圆形跑 */
.ball {
  width: 20px;
  height: 20px;
  background: red;
  border-radius: 50%;
  /* 定义运动路径:一个半径100px的圆 */
  offset-path: circle(100px);
  /* 动画:让offset-distance从0跑到100%(绕一圈) */
  animation: move 3s linear infinite;
}
@keyframes move {
  from { offset-distance: 0%; }
  to { offset-distance: 100%; }
}

是不是超简单?咱来扒扒这俩属性:

  • offset-path:相当于给元素画 “跑道”,告诉它 “你得沿着这条线跑”
  • offset-distance:相当于元素的 “脚”,控制它在跑道上跑了多远(0% 是起点,100% 是终点)

别记复杂概念!就理解成:offset-path 画赛道,offset-distance 控制跑多远~

(二)画赛道的 2 种方式:SVG 路径 vs CSS 形状

赛道咋画?俩办法,按需选择:

  1. CSS 形状函数(简单场景首选)

直接用 CSS 自带的形状函数,不用写 SVG,懒人福音:

/* 圆形跑道 */
offset-path: circle(100px);
/* 椭圆形跑道 */
offset-path: ellipse(150px 100px);
/* 矩形跑道(带圆角) */
offset-path: rect(0 200px 200px 0 round 20px);

缺点:只能画简单形状,想搞复杂赛道得用下面这个~

  1. SVG 路径(复杂赛道必备)

SVG 的 ` 任意曲线,堪称 “赛道万能笔”!比如画个 “S” 形:

S形路径,id叫s-path -->
 width="0" height="0">
   d="M50,100 C150,20 250,180 350,100" id="s-path" />
>
沿着S形跑 -->
<div class="box">>
.box {
  width: 30px;
  height: 30px;
  background: blue;
  /* 引用SVG里的路径当赛道 */
  offset-path: path('url(#s-path)');
  animation: move 4s ease-in-out infinite;
}

看不懂 SVG 的d属性?没关系!直接用 AI、Figma 画好路径,导出 SVG 复制d值就行,不用自己写~

三、实战案例:俩趣味效果,直接抄代码!

光说不练假把式,来俩案例,代码直接复制粘贴就能用~

(一)案例 1:云朵沿着曲线飘(适合网页背景装饰)

效果:云朵慢悠悠沿着曲线飘,营造慵懒氛围~

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>offset-path</title>
  <style>
    body {
      height: 100vh;
      background: linear-gradient(to bottom, #87ceeb, #f0f8ff);
      display: flex;
      justify-content: center;
      align-items: center;
      overflow: hidden;
    }
    .cloud {
      width: 100px;
      height: 60px;
      background: white;
      border-radius: 30px;
      position: relative;
      /* 画云朵的小疙瘩 */
    }

    .cloud::before,
    .cloud::after {
      content: '';
      position: absolute;
      width: 40px;
      height: 40px;
      background: white;
      border-radius: 50%;
      top: -20px;
      left: 20px;
    }

    .cloud::after {
      width: 60px;
      height: 60px;
      top: -30px;
      right: 20px;
    }

    /* 重点:路径动画 */
    .cloud {
      /* 画一条平缓的曲线赛道 */
      offset-path: path('M50,100 C200,50 350,150 500,100');
      animation: float 15s linear infinite alternate;
    }

    @keyframes float {
      from {
        offset-distance: 0%;
      }

      to {
        offset-distance: 100%;
      }
    }
  </style>
</head>

<body>
  <div class="cloud"></div>
</body>

</html>

关键技巧:path里的C是画贝塞尔曲线,数值调得平缓点,云朵飘得更自然~ 嫌慢就把动画时间改短! 当然你也可以通过animate-timing 来自行调整

(二)案例 2:卡丁车沿着不规则赛道 “飙车”(适合游戏 / 互动组件)

效果:卡丁车顺着 “之字形” 赛道跑,还能自动转向,超有代入感~

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body {
      margin: 0;
      position: relative;
      min-height: 360px;
    }

    .track {
      position: absolute;
      top: 0;
      left: 0;
      width: 800px;
      height: 400px;
      z-index: 0;
      pointer-events: none;
    }

    .stage {
      width: 800px;
      height: 400px;
      position: relative;
      margin: 20px auto;
    }

    .car {
      width: 40px;
      height: 20px;
      background: #ff6b6b;
      border-radius: 5px 10px 10px 5px;
      position: absolute;
      z-index: 1;
      left: 0;
      top: 0;
      /* 使小车中心位于路径点上 */
      offset-anchor: 20px 10px;
      /* 让小车始终面向运动方向(关键!) */
      offset-rotate: auto;
      /* 引用SVG赛道 */
      offset-path: path('M100,200 L200,100 L300,300 L400,150 L500,250 L600,180 L700,220');
      animation: race 8s ease-in-out infinite alternate;
    }

    /* 小车轮子 */
    .car::before,
    .car::after {
      content: '';
      position: absolute;
      width: 8px;
      height: 8px;
      background: #333;
      border-radius: 50%;
      bottom: -4px;
    }

    .car::after {
      right: 10px;
    }

    @keyframes race {
      from {
        offset-distance: 0%;
      }

      to {
        offset-distance: 100%;
      }
    }
  </style>
</head>

<body>
  <div class="stage">
    <!-- 可视化轨道 SVG(使用与 offset-path 相同的路径) -->
    <svg class="track" viewBox="0 0 800 400" preserveAspectRatio="xMinYMin meet" aria-hidden="true">
      <path d="M100,200 L200,100 L300,300 L400,150 L500,250 L600,180 L700,220" stroke="#3a86ff" stroke-width="4" fill="none" stroke-linecap="round" stroke-linejoin="round" opacity="0.95" />
    </svg>

    <div class="car"></div>
  </div>
</body>

</html>

四、避坑指南:优化技巧 + 踩坑总结

(一)性能优化:别让动画 “卡成 PPT”

路径动画虽好,但搞复杂了容易卡!记住这 2 个小技巧:

  1. 给动画元素加 will-change: offset-path,提前告诉浏览器 “这玩意儿要动”,让它做好准备:
.car { will-change: offset-path; }
  1. 别用太复杂的 SVG 路径(比如几千个节点),浏览器渲染不过来,会变成 “慢动作回放”~

(二)细节吐槽:这些坑我替你踩过了!

  1. 动画跑一半 “跑偏”?大概率是 offset-path 的路径起点没对齐元素中心,给元素加 transform: translate(-50%, -50%) 居中就行~, 或者调整 offset-anchor[ ](offset-anchor - CSS | MDN)
  1. 浏览器不兼容?Chrome、Edge、Firefox 都支持,Safari 有点 “叛逆”,可以加前缀:
offset-path: path('...');
-webkit-offset-path: path('...'); /* Safari专属 */
  1. 想让动画暂停 / 继续?用 JS 控制 animation-play-state,超简单:
const car = document.querySelector('.car');
car.addEventListener('click', () => {
  car.style.animationPlayState = car.style.animationPlayState === 'paused' ? 'running' : 'paused';
});
  1. 小车车头指向方向,[offset-rotate](offset-rotate - CSS | MDN)控制。auto 为跟随路径方向,其他值不过多介绍,自行查阅即可

五、总结:路径动画 = 网页 “加分项” 神器

其实 CSS 路径动画一点都不难,核心就是 “画赛道 + 让元素跑”,俩属性 + 简单代码就能实现炫酷效果~

不管是做网页背景装饰、互动组件,还是小游戏,路径动画都能让你的页面 “脱颖而出”,再也不用跟别人的 “老年迪斯科” 动画撞款啦!