svg-animations
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseThis 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 . The viewBox is your canvas — all coordinates are relative to it, making SVGs resolution-independent.
viewBox="minX minY width height"svg
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<!-- 200x200 unit canvas, scales to any size -->
</svg>SVG使用由定义的坐标系。viewBox相当于你的画布——所有坐标都相对于它,使SVG具备分辨率无关性。
viewBox="minX minY width height"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><path>
元素——核心工具
<path>The attribute defines a path using commands. Uppercase = absolute, lowercase = relative.
d| Command | Purpose | Syntax |
|---|---|---|
| M/m | Move to | |
| L/l | Line to | |
| H/h | Horizontal line | |
| V/v | Vertical line | |
| C/c | Cubic bézier | |
| S/s | Smooth cubic bézier | |
| Q/q | Quadratic bézier | |
| T/t | Smooth quadratic | |
| A/a | Elliptical arc | |
| Z/z | Close path | |
Cubic Bézier (): Two control points define the curve. The first control point sets the departure angle, the second sets the arrival angle.
Csvg
<path d="M 10 80 C 40 10, 65 10, 95 80" stroke="#000" fill="none" stroke-width="2" />Smooth Cubic (): Reflects the previous control point automatically — perfect for chaining fluid S-curves.
Ssvg
<path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="#000" fill="none" />Arc ():
Arx ry x-rotation large-arc-flag sweep-flag x y- : 0 = small arc, 1 = large arc (>180°)
large-arc-flag - : 0 = counterclockwise, 1 = clockwise
sweep-flag
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 | 移动到 | |
| L/l | 画线到 | |
| H/h | 水平线 | |
| V/v | 垂直线 | |
| C/c | 三次贝塞尔曲线 | |
| S/s | 平滑三次贝塞尔曲线 | |
| Q/q | 二次贝塞尔曲线 | |
| T/t | 平滑二次贝塞尔曲线 | |
| A/a | 椭圆弧 | |
| Z/z | 闭合路径 | |
三次贝塞尔曲线 ():两个控制点定义曲线。第一个控制点设置离开角度,第二个设置到达角度。
Csvg
<path d="M 10 80 C 40 10, 65 10, 95 80" stroke="#000" fill="none" stroke-width="2" />平滑三次贝塞尔曲线 ():自动反射前一个控制点——非常适合连接流畅的S型曲线。
Ssvg
<path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="#000" fill="none" />椭圆弧 ():
Arx ry x-rotation large-arc-flag sweep-flag x y- :0 = 小弧,1 = 大弧(>180°)
large-arc-flag - :0 = 逆时针,1 = 顺时针
sweep-flag
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 to group elements for collective transforms, styling, and animation targets.
<g>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: , , , , , , etc.
fillstrokeopacitytransformstroke-dasharraystroke-dashoffset许多SVG属性都是有效的CSS属性:、、、、、等。
fillstrokeopacitytransformstroke-dasharraystroke-dashoffsetBasic 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 and to make a path appear to draw itself.
stroke-dasharraystroke-dashoffsetHow it works:
- Set to the path's total length (one giant dash + one giant gap)
stroke-dasharray - Set to the same length (shifts the dash off-screen)
stroke-dashoffset - Animate to 0 (slides the dash into view)
stroke-dashoffset
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-dasharraystroke-dashoffset实现原理:
- 将设置为路径的总长度(一个长虚线+一个长间隙)
stroke-dasharray - 将设置为相同的长度(将虚线移出可视区域)
stroke-dashoffset - 动画变为0(将虚线滑入可视区域)
stroke-dashoffset
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
dCSS d
属性动画
dModern browsers support animating the attribute directly in CSS:
dcss
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中动画属性:
dcss
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 or CSS — where CSS and JS can't reach.
<img>background-imageSMIL动画直接在SVG标记中声明。即使SVG以或CSS形式加载(此时CSS和JS无法生效),SMIL动画仍能正常工作。
<img>background-image<animate>
— Animate Any Attribute
<animate><animate>
——动画任意属性
<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><animateTransform>
——变换动画
<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: , , , ,
translatescalerotateskewXskewYsvg
<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>变换类型:、、、、
translatescalerotateskewXskewY<animateMotion>
— Move Along a Path
<animateMotion><animateMotion>
——沿路径移动
<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"rotate="auto-reverse"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"<set>
— Discrete Value Changes
<set><set>
——离散值变化
<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:
- — on click
begin="click" - — after 2 seconds
begin="2s" - — when another animation ends
begin="other.end" - — 1s after another ends
begin="other.end + 1s" - — on 2nd repeat of another
begin="other.repeat(2)"
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" - —— 2秒后
begin="2s" - —— 另一个动画结束时
begin="other.end" - —— 另一个动画结束1秒后
begin="other.end + 1s" - —— 另一个动画重复第2次时
begin="other.repeat(2)"
Easing with calcMode
and keySplines
calcModekeySplines使用calcMode
和keySplines
设置缓动
calcModekeySplinessvg
<animate attributeName="cx" values="50;150" dur="1s"
calcMode="spline" keySplines="0.42 0 0.58 1" />calcModelineardiscretepacedsplinekeySplines- 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" />calcModelineardiscretepacedsplinekeySplines- 缓入缓出:
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
最佳实践
-
Use, never hardcode
viewBox/widthin the SVG — let the container size it. This keeps it resolution-independent.height -
for reusable definitions — gradients, filters, masks, clipPaths, and reusable shapes belong in
<defs>.<defs> -
Prefer SMIL for self-contained SVGs (icons, logos loaded via) — 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.
<img> -
Shape morphing requires matching commands — same number of path commands, same types, same order. If shapes differ, add invisible intermediate points to equalize.
-
makes line animations look polished.
stroke-linecap="round" -
in SMIL keeps the final animation state. Without it, the element snaps back.
fill="freeze" -
in CSS — SVG transforms default to the origin (0,0), not the element center. Always set this explicitly.
transform-origin: center -
Usein JS to get exact path lengths for stroke animations instead of guessing.
getTotalLength() -
Layer animations withgroups — animate the group transform separately from individual element properties for complex choreography.
<g> -
Performance: SVG animations are GPU-composited when animatingand
transform. Animatingopacity,d, or layout attributes triggers repaints — use sparingly on complex SVGs.points -
on animated SVG elements helps the browser optimize compositing.
will-change: transform -
Accessibility: Addand
role="img"/<title>elements. Use<desc>media query to disable animations for users who request it:prefers-reduced-motion
css
@media (prefers-reduced-motion: reduce) {
svg * {
animation: none !important;
transition: none !important;
}
}-
使用,切勿在SVG中硬编码
viewBox/width—— 让容器控制尺寸。这样可保持SVG的分辨率无关性。height -
使用存放可复用定义 —— 渐变、滤镜、蒙版、裁剪路径和可复用形状都应放在
<defs>中。<defs> -
独立SVG优先使用SMIL(如图标、通过加载的标志)—— 此时CSS/JS无法生效。当SVG内联到页面中且需要与页面其他内容协同动画时,使用CSS动画。
<img> -
形状变形需要匹配命令 —— 路径命令的数量、类型和顺序必须完全相同。如果形状不同,添加不可见的中间点来统一结构。
-
让线条动画更流畅美观。
stroke-linecap="round" -
SMIL中使用保持动画的最终状态。如果不设置,元素会跳回初始状态。
fill="freeze" -
CSS中设置—— SVG变换默认以原点(0,0)为中心,而非元素中心。始终显式设置此属性。
transform-origin: center -
使用JS的获取精确的路径长度,而非手动估算,用于描边动画。
getTotalLength() -
使用分组管理动画 —— 单独为组设置变换动画,同时为组内元素设置属性动画,实现复杂的动画编排。
<g> -
性能优化: 动画和
transform时,SVG动画会由GPU合成。动画opacity、d或布局属性会触发重绘——复杂SVG中应尽量避免。points -
在动画元素上添加帮助浏览器优化合成过程。
will-change: transform -
无障碍访问: 添加和
role="img"/<title>元素。使用<desc>媒体查询为需要的用户禁用动画:prefers-reduced-motion
css
@media (prefers-reduced-motion: reduce) {
svg * {
animation: none !important;
transition: none !important;
}
}