svg-animations

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
This skill guides creation of handcrafted SVG animations — from simple animated icons to complex multi-stage path animations. SVGs are a markup language for images; every element is a DOM node you can style, animate, and script.
本技能指导你创建手工制作的SVG动画——从简单的动画图标到复杂的多阶段路径动画。SVG是一种图像标记语言,每个元素都是可设置样式、添加动画和编写脚本的DOM节点。

SVG Fundamentals

SVG基础

Coordinate System

坐标系

SVGs use a coordinate system defined by
viewBox="minX minY width height"
. The viewBox is your canvas — all coordinates are relative to it, making SVGs resolution-independent.
svg
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- 200x200 unit canvas, scales to any size -->
</svg>
SVG使用由
viewBox="minX minY width height"
定义的坐标系。viewBox相当于你的画布——所有坐标都相对于它,使SVG具备分辨率无关性。
svg
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- 200x200单位画布,可缩放至任意尺寸 -->
</svg>

Shape Primitives

基础形状

svg
<rect x="10" y="10" width="80" height="40" rx="4" fill="#1a1a1a" />
<circle cx="50" cy="50" r="30" fill="#e63946" />
<ellipse cx="50" cy="50" rx="40" ry="20" fill="#457b9d" />
<line x1="10" y1="10" x2="90" y2="90" stroke="#2a9d8f" stroke-width="2" />
<polygon points="50,5 95,90 5,90" fill="#e9c46a" />
<polyline points="10,80 40,20 70,60 100,10" fill="none" stroke="#264653" stroke-width="2" />
svg
<rect x="10" y="10" width="80" height="40" rx="4" fill="#1a1a1a" />
<circle cx="50" cy="50" r="30" fill="#e63946" />
<ellipse cx="50" cy="50" rx="40" ry="20" fill="#457b9d" />
<line x1="10" y1="10" x2="90" y2="90" stroke="#2a9d8f" stroke-width="2" />
<polygon points="50,5 95,90 5,90" fill="#e9c46a" />
<polyline points="10,80 40,20 70,60 100,10" fill="none" stroke="#264653" stroke-width="2" />

The
<path>
Element — The Power Tool

<path>
元素——核心工具

The
d
attribute defines a path using commands. Uppercase = absolute, lowercase = relative.
CommandPurposeSyntax
M/mMove to
M x y
L/lLine to
L x y
H/hHorizontal line
H x
V/vVertical line
V y
C/cCubic bézier
C x1 y1, x2 y2, x y
S/sSmooth cubic bézier
S x2 y2, x y
Q/qQuadratic bézier
Q x1 y1, x y
T/tSmooth quadratic
T x y
A/aElliptical arc
A rx ry rotation large-arc sweep x y
Z/zClose path
Z
Cubic Bézier (
C
): Two control points define the curve. The first control point sets the departure angle, the second sets the arrival angle.
svg
<path d="M 10 80 C 40 10, 65 10, 95 80" stroke="#000" fill="none" stroke-width="2" />
Smooth Cubic (
S
): Reflects the previous control point automatically — perfect for chaining fluid S-curves.
svg
<path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="#000" fill="none" />
Arc (
A
):
rx ry x-rotation large-arc-flag sweep-flag x y
  • large-arc-flag
    : 0 = small arc, 1 = large arc (>180°)
  • sweep-flag
    : 0 = counterclockwise, 1 = clockwise
svg
<!-- Heart shape using arcs and quadratic curves -->
<path d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 Z"
      fill="#e63946" />
d
属性通过命令定义路径。大写字母表示绝对坐标,小写字母表示相对坐标。
命令用途语法
M/m移动到
M x y
L/l画线到
L x y
H/h水平线
H x
V/v垂直线
V y
C/c三次贝塞尔曲线
C x1 y1, x2 y2, x y
S/s平滑三次贝塞尔曲线
S x2 y2, x y
Q/q二次贝塞尔曲线
Q x1 y1, x y
T/t平滑二次贝塞尔曲线
T x y
A/a椭圆弧
A rx ry rotation large-arc sweep x y
Z/z闭合路径
Z
三次贝塞尔曲线 (
C
):两个控制点定义曲线。第一个控制点设置离开角度,第二个设置到达角度。
svg
<path d="M 10 80 C 40 10, 65 10, 95 80" stroke="#000" fill="none" stroke-width="2" />
平滑三次贝塞尔曲线 (
S
):自动反射前一个控制点——非常适合连接流畅的S型曲线。
svg
<path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="#000" fill="none" />
椭圆弧 (
A
):
rx ry x-rotation large-arc-flag sweep-flag x y
  • large-arc-flag
    :0 = 小弧,1 = 大弧(>180°)
  • sweep-flag
    :0 = 逆时针,1 = 顺时针
svg
<!-- 使用弧和二次曲线绘制心形 -->
<path d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 Z"
      fill="#e63946" />

Grouping and Transforms

分组与变换

svg
<g transform="translate(50, 50) rotate(45)" opacity="0.8">
  <rect x="-20" y="-20" width="40" height="40" fill="#264653" />
</g>
Use
<g>
to group elements for collective transforms, styling, and animation targets.
svg
<g transform="translate(50, 50) rotate(45)" opacity="0.8">
  <rect x="-20" y="-20" width="40" height="40" fill="#264653" />
</g>
使用
<g>
对元素进行分组,以便统一应用变换、样式和设置动画目标。

Gradients, Masks, and Filters

渐变、蒙版与滤镜

svg
<defs>
  <!-- Linear gradient -->
  <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#e63946" />
    <stop offset="100%" stop-color="#457b9d" />
  </linearGradient>

  <!-- Radial gradient -->
  <radialGradient id="glow" cx="50%" cy="50%" r="50%">
    <stop offset="0%" stop-color="#fff" stop-opacity="0.8" />
    <stop offset="100%" stop-color="#fff" stop-opacity="0" />
  </radialGradient>

  <!-- Mask -->
  <mask id="reveal">
    <rect width="100%" height="100%" fill="black" />
    <circle cx="100" cy="100" r="50" fill="white" />
  </mask>

  <!-- Blur filter -->
  <filter id="blur">
    <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
  </filter>
</defs>

<rect width="200" height="200" fill="url(#grad)" />
<rect width="200" height="200" fill="url(#grad)" mask="url(#reveal)" />
<circle cx="50" cy="50" r="20" filter="url(#blur)" fill="#e63946" />

svg
<defs>
  <!-- 线性渐变 -->
  <linearGradient id="grad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#e63946" />
    <stop offset="100%" stop-color="#457b9d" />
  </linearGradient>

  <!-- 径向渐变 -->
  <radialGradient id="glow" cx="50%" cy="50%" r="50%">
    <stop offset="0%" stop-color="#fff" stop-opacity="0.8" />
    <stop offset="100%" stop-color="#fff" stop-opacity="0" />
  </radialGradient>

  <!-- 蒙版 -->
  <mask id="reveal">
    <rect width="100%" height="100%" fill="black" />
    <circle cx="100" cy="100" r="50" fill="white" />
  </mask>

  <!-- 模糊滤镜 -->
  <filter id="blur">
    <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
  </filter>
</defs>

<rect width="200" height="200" fill="url(#grad)" />
<rect width="200" height="200" fill="url(#grad)" mask="url(#reveal)" />
<circle cx="50" cy="50" r="20" filter="url(#blur)" fill="#e63946" />

CSS Animations on SVG

SVG的CSS动画

Many SVG attributes are valid CSS properties:
fill
,
stroke
,
opacity
,
transform
,
stroke-dasharray
,
stroke-dashoffset
, etc.
许多SVG属性都是有效的CSS属性:
fill
stroke
opacity
transform
stroke-dasharray
stroke-dashoffset
等。

Basic CSS Animation

基础CSS动画

css
.pulse {
  animation: pulse 2s ease-in-out infinite;
  transform-origin: center;
}
@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.15); opacity: 0.7; }
}
css
.pulse {
  animation: pulse 2s ease-in-out infinite;
  transform-origin: center;
}
@keyframes pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.15); opacity: 0.7; }
}

Stroke Drawing Animation (The Classic)

路径描边动画(经典效果)

The most iconic SVG animation. Uses
stroke-dasharray
and
stroke-dashoffset
to make a path appear to draw itself.
How it works:
  1. Set
    stroke-dasharray
    to the path's total length (one giant dash + one giant gap)
  2. Set
    stroke-dashoffset
    to the same length (shifts the dash off-screen)
  3. Animate
    stroke-dashoffset
    to 0 (slides the dash into view)
svg
<svg viewBox="0 0 200 200">
  <path class="draw" d="M 20 100 C 20 50, 80 50, 80 100 S 140 150, 140 100"
        fill="none" stroke="#1a1a1a" stroke-width="3" />
</svg>

<style>
  .draw {
    stroke-dasharray: 300;
    stroke-dashoffset: 300;
    animation: draw 2s ease forwards;
  }
  @keyframes draw {
    to { stroke-dashoffset: 0; }
  }
</style>
Getting exact path length in JS:
js
const path = document.querySelector('.draw');
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;
这是最具代表性的SVG动画。使用
stroke-dasharray
stroke-dashoffset
实现路径逐步绘制的效果。
实现原理:
  1. stroke-dasharray
    设置为路径的总长度(一个长虚线+一个长间隙)
  2. stroke-dashoffset
    设置为相同的长度(将虚线移出可视区域)
  3. 动画
    stroke-dashoffset
    变为0(将虚线滑入可视区域)
svg
<svg viewBox="0 0 200 200">
  <path class="draw" d="M 20 100 C 20 50, 80 50, 80 100 S 140 150, 140 100"
        fill="none" stroke="#1a1a1a" stroke-width="3" />
</svg>

<style>
  .draw {
    stroke-dasharray: 300;
    stroke-dashoffset: 300;
    animation: draw 2s ease forwards;
  }
  @keyframes draw {
    to { stroke-dashoffset: 0; }
  }
</style>
使用JS获取精确路径长度:
js
const path = document.querySelector('.draw');
const length = path.getTotalLength();
path.style.strokeDasharray = length;
path.style.strokeDashoffset = length;

Staggered Multi-Path Drawing

多路径分步描边

css
.line-1 { animation-delay: 0s; }
.line-2 { animation-delay: 0.3s; }
.line-3 { animation-delay: 0.6s; }
css
.line-1 { animation-delay: 0s; }
.line-2 { animation-delay: 0.3s; }
.line-3 { animation-delay: 0.6s; }

CSS
d
Property Animation

CSS
d
属性动画

Modern browsers support animating the
d
attribute directly in CSS:
css
path {
  d: path("M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z");
  transition: d 0.5s ease;
}
path:hover {
  d: path("M 10,50 A 20,20 0,0,1 50,10 A 20,20 0,0,1 90,50 Q 90,80 50,100 Q 10,80 10,50 z");
}
Requirement: Both paths must have the same number and types of commands for interpolation to work.

现代浏览器支持直接在CSS中动画
d
属性:
css
path {
  d: path("M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z");
  transition: d 0.5s ease;
}
path:hover {
  d: path("M 10,50 A 20,20 0,0,1 50,10 A 20,20 0,0,1 90,50 Q 90,80 50,100 Q 10,80 10,50 z");
}
要求: 两个路径必须具有相同数量和类型的命令,才能实现插值动画。

SMIL Animations (Native SVG)

SMIL动画(原生SVG)

SMIL animations are declared directly inside SVG markup. They work even when SVG is loaded as an
<img>
or CSS
background-image
— where CSS and JS can't reach.
SMIL动画直接在SVG标记中声明。即使SVG以
<img>
或CSS
background-image
形式加载(此时CSS和JS无法生效),SMIL动画仍能正常工作。

<animate>
— Animate Any Attribute

<animate>
——动画任意属性

svg
<circle cx="50" cy="50" r="20" fill="#e63946">
  <animate attributeName="r" from="20" to="40" dur="1s"
           repeatCount="indefinite" />
</circle>
With keyframes:
svg
<animate attributeName="cx"
         values="50; 150; 100; 50"
         keyTimes="0; 0.33; 0.66; 1"
         dur="3s" repeatCount="indefinite" />
svg
<circle cx="50" cy="50" r="20" fill="#e63946">
  <animate attributeName="r" from="20" to="40" dur="1s"
           repeatCount="indefinite" />
</circle>
关键帧形式:
svg
<animate attributeName="cx"
         values="50; 150; 100; 50"
         keyTimes="0; 0.33; 0.66; 1"
         dur="3s" repeatCount="indefinite" />

<animateTransform>
— Transform Animations

<animateTransform>
——变换动画

svg
<rect x="-20" y="-20" width="40" height="40" fill="#264653">
  <animateTransform attributeName="transform" type="rotate"
                    from="0" to="360" dur="4s" repeatCount="indefinite" />
</rect>
Types:
translate
,
scale
,
rotate
,
skewX
,
skewY
svg
<rect x="-20" y="-20" width="40" height="40" fill="#264653">
  <animateTransform attributeName="transform" type="rotate"
                    from="0" to="360" dur="4s" repeatCount="indefinite" />
</rect>
变换类型:
translate
scale
rotate
skewX
skewY

<animateMotion>
— Move Along a Path

<animateMotion>
——沿路径移动

svg
<circle r="5" fill="#e63946">
  <animateMotion dur="3s" repeatCount="indefinite" rotate="auto">
    <mpath href="#motionPath" />
  </animateMotion>
</circle>
<path id="motionPath" d="M 20,50 C 20,0 80,0 80,50 S 140,100 140,50"
      fill="none" stroke="#ccc" />
rotate="auto"
orients the element tangent to the path.
rotate="auto-reverse"
flips it 180°.
svg
<circle r="5" fill="#e63946">
  <animateMotion dur="3s" repeatCount="indefinite" rotate="auto">
    <mpath href="#motionPath" />
  </animateMotion>
</circle>
<path id="motionPath" d="M 20,50 C 20,0 80,0 80,50 S 140,100 140,50"
      fill="none" stroke="#ccc" />
rotate="auto"
使元素与路径切线方向保持一致。
rotate="auto-reverse"
则将元素翻转180°。

<set>
— Discrete Value Changes

<set>
——离散值变化

svg
<rect width="40" height="40" fill="#264653">
  <set attributeName="fill" to="#e63946" begin="1s" />
</rect>
svg
<rect width="40" height="40" fill="#264653">
  <set attributeName="fill" to="#e63946" begin="1s" />
</rect>

Timing and Synchronization

时序与同步

svg
<!-- Chain animations by referencing IDs -->
<animate id="first" attributeName="cx" to="150" dur="1s" fill="freeze" />
<animate attributeName="cy" to="150" dur="1s" begin="first.end" fill="freeze" />
<animate attributeName="r" to="30" dur="0.5s" begin="first.end + 0.5s" fill="freeze" />
Trigger values:
  • begin="click"
    — on click
  • begin="2s"
    — after 2 seconds
  • begin="other.end"
    — when another animation ends
  • begin="other.end + 1s"
    — 1s after another ends
  • begin="other.repeat(2)"
    — on 2nd repeat of another
svg
<!-- 通过引用ID串联动画 -->
<animate id="first" attributeName="cx" to="150" dur="1s" fill="freeze" />
<animate attributeName="cy" to="150" dur="1s" begin="first.end" fill="freeze" />
<animate attributeName="r" to="30" dur="0.5s" begin="first.end + 0.5s" fill="freeze" />
触发条件:
  • begin="click"
    —— 点击时
  • begin="2s"
    —— 2秒后
  • begin="other.end"
    —— 另一个动画结束时
  • begin="other.end + 1s"
    —— 另一个动画结束1秒后
  • begin="other.repeat(2)"
    —— 另一个动画重复第2次时

Easing with
calcMode
and
keySplines

使用
calcMode
keySplines
设置缓动

svg
<animate attributeName="cx" values="50;150" dur="1s"
         calcMode="spline" keySplines="0.42 0 0.58 1" />
calcMode
options:
linear
(default),
discrete
,
paced
,
spline
keySplines
takes cubic-bezier control points (x1 y1 x2 y2) per interval. Common easings:
  • Ease-in-out:
    0.42 0 0.58 1
  • Ease-out:
    0 0 0.58 1
  • Bounce-ish:
    0.34 1.56 0.64 1
svg
<animate attributeName="cx" values="50;150" dur="1s"
         calcMode="spline" keySplines="0.42 0 0.58 1" />
calcMode
选项:
linear
(默认)、
discrete
paced
spline
keySplines
为每个间隔提供三次贝塞尔控制点(x1 y1 x2 y2)。常见缓动效果:
  • 缓入缓出:
    0.42 0 0.58 1
  • 缓出:
    0 0 0.58 1
  • 弹跳效果:
    0.34 1.56 0.64 1

Shape Morphing with SMIL

SMIL形状变形

Both shapes must have identical command structures (same number of points, same command types):
svg
<path fill="#e63946">
  <animate attributeName="d" dur="2s" repeatCount="indefinite"
    values="M 50,10 L 90,90 L 10,90 Z;
            M 50,90 L 90,10 L 10,10 Z;
            M 50,10 L 90,90 L 10,90 Z" />
</path>

两个形状必须具有完全相同的命令结构(相同数量的点、相同类型的命令):
svg
<path fill="#e63946">
  <animate attributeName="d" dur="2s" repeatCount="indefinite"
    values="M 50,10 L 90,90 L 10,90 Z;
            M 50,90 L 90,10 L 10,10 Z;
            M 50,10 L 90,90 L 10,90 Z" />
</path>

Animation Patterns & Recipes

动画模式与示例

Loading Spinner

加载动画

svg
<svg viewBox="0 0 50 50">
  <circle cx="25" cy="25" r="20" fill="none" stroke="#1a1a1a"
          stroke-width="3" stroke-linecap="round"
          stroke-dasharray="90 150" stroke-dashoffset="0">
    <animateTransform attributeName="transform" type="rotate"
                      from="0 25 25" to="360 25 25" dur="1s"
                      repeatCount="indefinite" />
    <animate attributeName="stroke-dashoffset" values="0;-280"
             dur="1.5s" repeatCount="indefinite" />
  </circle>
</svg>
svg
<svg viewBox="0 0 50 50">
  <circle cx="25" cy="25" r="20" fill="none" stroke="#1a1a1a"
          stroke-width="3" stroke-linecap="round"
          stroke-dasharray="90 150" stroke-dashoffset="0">
    <animateTransform attributeName="transform" type="rotate"
                      from="0 25 25" to="360 25 25" dur="1s"
                      repeatCount="indefinite" />
    <animate attributeName="stroke-dashoffset" values="0;-280"
             dur="1.5s" repeatCount="indefinite" />
  </circle>
</svg>

Animated Checkmark

动画对勾

svg
<svg viewBox="0 0 52 52">
  <circle cx="26" cy="26" r="24" fill="none" stroke="#4caf50"
          stroke-width="2" class="draw"
          style="stroke-dasharray:150;stroke-dashoffset:150;
                 animation:draw .6s ease forwards" />
  <path fill="none" stroke="#4caf50" stroke-width="3"
        stroke-linecap="round" stroke-linejoin="round"
        d="M14 27l7 7 16-16" class="draw"
        style="stroke-dasharray:50;stroke-dashoffset:50;
               animation:draw .4s ease .5s forwards" />
</svg>
svg
<svg viewBox="0 0 52 52">
  <circle cx="26" cy="26" r="24" fill="none" stroke="#4caf50"
          stroke-width="2" class="draw"
          style="stroke-dasharray:150;stroke-dashoffset:150;
                 animation:draw .6s ease forwards" />
  <path fill="none" stroke="#4caf50" stroke-width="3"
        stroke-linecap="round" stroke-linejoin="round"
        d="M14 27l7 7 16-16" class="draw"
        style="stroke-dasharray:50;stroke-dashoffset:50;
               animation:draw .4s ease .5s forwards" />
</svg>

Morphing Hamburger to X

汉堡菜单转X动画

svg
<svg viewBox="0 0 24 24" id="menu">
  <path id="top" d="M 3,6 L 21,6" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round">
    <animate attributeName="d" to="M 5,5 L 19,19" dur="0.3s" begin="menu.click" fill="freeze" />
  </path>
  <path id="mid" d="M 3,12 L 21,12" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round">
    <animate attributeName="opacity" to="0" dur="0.1s" begin="menu.click" fill="freeze" />
  </path>
  <path id="bot" d="M 3,18 L 21,18" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round">
    <animate attributeName="d" to="M 5,19 L 19,5" dur="0.3s" begin="menu.click" fill="freeze" />
  </path>
</svg>
svg
<svg viewBox="0 0 24 24" id="menu">
  <path id="top" d="M 3,6 L 21,6" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round">
    <animate attributeName="d" to="M 5,5 L 19,19" dur="0.3s" begin="menu.click" fill="freeze" />
  </path>
  <path id="mid" d="M 3,12 L 21,12" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round">
    <animate attributeName="opacity" to="0" dur="0.1s" begin="menu.click" fill="freeze" />
  </path>
  <path id="bot" d="M 3,18 L 21,18" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round">
    <animate attributeName="d" to="M 5,19 L 19,5" dur="0.3s" begin="menu.click" fill="freeze" />
  </path>
</svg>

Gradient Animation (Color Shift)

渐变动画(颜色切换)

svg
<defs>
  <linearGradient id="shift" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%">
      <animate attributeName="stop-color"
               values="#e63946;#457b9d;#2a9d8f;#e63946"
               dur="4s" repeatCount="indefinite" />
    </stop>
    <stop offset="100%">
      <animate attributeName="stop-color"
               values="#457b9d;#2a9d8f;#e63946;#457b9d"
               dur="4s" repeatCount="indefinite" />
    </stop>
  </linearGradient>
</defs>
<rect width="200" height="100" fill="url(#shift)" rx="8" />
svg
<defs>
  <linearGradient id="shift" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%">
      <animate attributeName="stop-color"
               values="#e63946;#457b9d;#2a9d8f;#e63946"
               dur="4s" repeatCount="indefinite" />
    </stop>
    <stop offset="100%">
      <animate attributeName="stop-color"
               values="#457b9d;#2a9d8f;#e63946;#457b9d"
               dur="4s" repeatCount="indefinite" />
    </stop>
  </linearGradient>
</defs>
<rect width="200" height="100" fill="url(#shift)" rx="8" />

Breathing / Pulsing Glow

呼吸/脉冲发光效果

svg
<circle cx="100" cy="100" r="30" fill="#e63946">
  <animate attributeName="r" values="30;35;30" dur="2s"
           calcMode="spline" keySplines="0.4 0 0.6 1;0.4 0 0.6 1"
           repeatCount="indefinite" />
  <animate attributeName="opacity" values="1;0.6;1" dur="2s"
           calcMode="spline" keySplines="0.4 0 0.6 1;0.4 0 0.6 1"
           repeatCount="indefinite" />
</circle>
svg
<circle cx="100" cy="100" r="30" fill="#e63946">
  <animate attributeName="r" values="30;35;30" dur="2s"
           calcMode="spline" keySplines="0.4 0 0.6 1;0.4 0 0.6 1"
           repeatCount="indefinite" />
  <animate attributeName="opacity" values="1;0.6;1" dur="2s"
           calcMode="spline" keySplines="0.4 0 0.6 1;0.4 0 0.6 1"
           repeatCount="indefinite" />
</circle>

Wave / Liquid Effect

波浪/液体效果

svg
<path fill="#457b9d" opacity="0.7">
  <animate attributeName="d" dur="5s" repeatCount="indefinite"
    values="M 0,40 C 30,35 70,45 100,40 L 100,100 L 0,100 Z;
            M 0,40 C 30,50 70,30 100,40 L 100,100 L 0,100 Z;
            M 0,40 C 30,35 70,45 100,40 L 100,100 L 0,100 Z"
    calcMode="spline" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
</path>

svg
<path fill="#457b9d" opacity="0.7">
  <animate attributeName="d" dur="5s" repeatCount="indefinite"
    values="M 0,40 C 30,35 70,45 100,40 L 100,100 L 0,100 Z;
            M 0,40 C 30,50 70,30 100,40 L 100,100 L 0,100 Z;
            M 0,40 C 30,35 70,45 100,40 L 100,100 L 0,100 Z"
    calcMode="spline" keySplines="0.4 0 0.6 1;0.4 0 0.6 1" />
</path>

Best Practices

最佳实践

  1. Use
    viewBox
    , never hardcode
    width
    /
    height
    in the SVG
    — let the container size it. This keeps it resolution-independent.
  2. <defs>
    for reusable definitions
    — gradients, filters, masks, clipPaths, and reusable shapes belong in
    <defs>
    .
  3. Prefer SMIL for self-contained SVGs (icons, logos loaded via
    <img>
    ) — CSS/JS won't work there. Use CSS animations when the SVG is inlined and you want to coordinate with the rest of the page.
  4. Shape morphing requires matching commands — same number of path commands, same types, same order. If shapes differ, add invisible intermediate points to equalize.
  5. stroke-linecap="round"
    makes line animations look polished.
  6. fill="freeze"
    in SMIL keeps the final animation state. Without it, the element snaps back.
  7. transform-origin: center
    in CSS — SVG transforms default to the origin (0,0), not the element center. Always set this explicitly.
  8. Use
    getTotalLength()
    in JS to get exact path lengths for stroke animations instead of guessing.
  9. Layer animations with
    <g>
    groups
    — animate the group transform separately from individual element properties for complex choreography.
  10. Performance: SVG animations are GPU-composited when animating
    transform
    and
    opacity
    . Animating
    d
    ,
    points
    , or layout attributes triggers repaints — use sparingly on complex SVGs.
  11. will-change: transform
    on animated SVG elements helps the browser optimize compositing.
  12. Accessibility: Add
    role="img"
    and
    <title>
    /
    <desc>
    elements. Use
    prefers-reduced-motion
    media query to disable animations for users who request it:
css
@media (prefers-reduced-motion: reduce) {
  svg * {
    animation: none !important;
    transition: none !important;
  }
}
  1. 使用
    viewBox
    ,切勿在SVG中硬编码
    width
    /
    height
    —— 让容器控制尺寸。这样可保持SVG的分辨率无关性。
  2. 使用
    <defs>
    存放可复用定义
    —— 渐变、滤镜、蒙版、裁剪路径和可复用形状都应放在
    <defs>
    中。
  3. 独立SVG优先使用SMIL(如图标、通过
    <img>
    加载的标志)—— 此时CSS/JS无法生效。当SVG内联到页面中且需要与页面其他内容协同动画时,使用CSS动画。
  4. 形状变形需要匹配命令 —— 路径命令的数量、类型和顺序必须完全相同。如果形状不同,添加不可见的中间点来统一结构。
  5. stroke-linecap="round"
    让线条动画更流畅美观。
  6. SMIL中使用
    fill="freeze"
    保持动画的最终状态。如果不设置,元素会跳回初始状态。
  7. CSS中设置
    transform-origin: center
    —— SVG变换默认以原点(0,0)为中心,而非元素中心。始终显式设置此属性。
  8. 使用JS的
    getTotalLength()
    获取精确的路径长度,而非手动估算,用于描边动画。
  9. 使用
    <g>
    分组管理动画
    —— 单独为组设置变换动画,同时为组内元素设置属性动画,实现复杂的动画编排。
  10. 性能优化: 动画
    transform
    opacity
    时,SVG动画会由GPU合成。动画
    d
    points
    或布局属性会触发重绘——复杂SVG中应尽量避免。
  11. 在动画元素上添加
    will-change: transform
    帮助浏览器优化合成过程。
  12. 无障碍访问: 添加
    role="img"
    <title>
    /
    <desc>
    元素。使用
    prefers-reduced-motion
    媒体查询为需要的用户禁用动画:
css
@media (prefers-reduced-motion: reduce) {
  svg * {
    animation: none !important;
    transition: none !important;
  }
}