SVG Morph Animation Reference

Just a guy who loves to write code and watch anime.
Search for a command to run...

Just a guy who loves to write code and watch anime.
No comments yet. Be the first to comment.
Qualities that make outstanding builders.

Bipedal vs quadrupedal: how many legs This is about the number of legs the creature walks on. Bipedal. Two legs. Humans, ostriches, T-rex, kangaroos, most fantasy humanoids. Quadrupedal. Four legs. Do

Intro You hear "lerp" and "smoothstep" everywhere in game dev. They sound like math jargon. They're not. Both are small tools that do the same job: smoothly move from one value to another. The problem

What is Kinematics Kinematics is the math field. It's the study of how things move without worrying about forces (which would be dynamics). FK and IK are the two branches: forward kinematics and inver

Intro Textures are usually the biggest cost in a 3D scene. Memory, bandwidth, and load time all get eaten by them. Resizing them is the obvious lever. There's more. This post is about the less obvious

Morph = animate attributes of the SAME element, not between different elements
<!-- ❌ Wrong: Different elements -->
<circle r="25" />
<rect width="50" height="50" />
<!-- ✅ Right: Same element, animate attributes -->
<rect width="50" height="50" rx="25">
<animate attributeName="rx" to="0" dur="1s" />
</rect>
Identify start/end shapes
Choose ONE element type that can represent both
Find attributes that change between the shapes
Animate those attributes
Use <rect> with rx attribute
<!-- Circle: rx = half of width/height -->
<rect x="25" y="25" width="50" height="50" rx="25" />
<!-- Rectangle: rx = 0 -->
<rect x="25" y="25" width="50" height="50" rx="0" />
<!-- Animation -->
<rect x="25" y="25" width="50" height="50" rx="25">
<animate attributeName="rx" to="0" dur="1s" />
</rect>
Use <polygon> with same point count
<!-- Triangle: 3 distinct points -->
<polygon points="12 4, 20 16, 4 16" />
<!-- Line: collapse top point to baseline -->
<polygon points="12 16, 20 16, 4 16" />
<!-- Animation -->
<polygon points="12 16, 20 16, 4 16">
<animate attributeName="points" to="12 4, 20 16, 4 16" dur="1s" />
</polygon>
Use <polygon> with 4 points (overlap for triangle)
<!-- Rectangle: 4 corners -->
<polygon points="0 0, 24 0, 24 24, 0 24" />
<!-- Triangle: move one point to overlap another -->
<polygon points="0 0, 24 24, 24 24, 0 24" />
<!-- Animation -->
<polygon points="0 0, 24 0, 24 24, 0 24">
<animate attributeName="points" to="0 0, 24 24, 24 24, 0 24" dur="1s" />
</polygon>
CRITICAL: Same number of points in start and end states
<!-- ❌ Breaks: 4 points → 3 points -->
<animate
attributeName="points"
from="0 0, 24 0, 24 24, 0 24"
to="0 0, 24 24, 0 24"
/>
<!-- ✅ Works: 4 points → 4 points -->
<animate
attributeName="points"
from="0 0, 24 0, 24 24, 0 24"
to="0 0, 24 24, 24 24, 0 24"
/>
Solution: Overlap points
Want 3 points? Make 2 points share same coordinates
"12 4, 20 16, 20 16, 4 16" = triangle with 4 points
Use <path> with same command structure
<!-- Both paths need same commands -->
<path d="M10 10 L50 10 L50 50 L10 50 Z">
<animate attributeName="d" to="M10 10 L30 30 L50 50 L10 50 Z" dur="1s" />
</path>
| Morph Type | Best Element | Animate |
| Circle ↔ Rectangle | <rect> | rx attribute |
| Simple shapes | <polygon> | points attribute |
| Complex curves | <path> | d attribute |
| Size changes | Any element | width, height, r, etc. |
<rect rx="25">
<animate attributeName="rx" to="0" dur="1s" fill="freeze" />
</rect>
/* Only works for simple numeric attributes */
rect {
rx: 25;
transition: rx 1s;
}
rect:hover {
rx: 0;
}
<!-- Coordinates must fit viewBox -->
<svg viewBox="0 0 24 24">
<polygon points="12 4, 20 16, 4 16" />
<!-- ✅ Fits -->
<polygon points="120 40, 200 160, 40 160" />
<!-- ❌ Outside viewBox -->
</svg>
<!-- Points animate in order: 1→1, 2→2, 3→3, 4→4 -->
<animate
attributeName="points"
from="0 0, 24 0, 24 24, 0 24"
to="12 0, 24 12, 12 24, 0 12"
/>
<!-- ❌ Different commands don't morph smoothly -->
<animate attributeName="d" from="M10 10 L50 50" to="M10 10 Q30 20 50 50" />
<!-- ✅ Same commands work better -->
<animate
attributeName="d"
from="M10 10 Q30 30 50 50"
to="M10 10 Q30 20 50 50"
/>
<rect rx="0" class="button-bg">
<animate attributeName="rx" to="8" dur="0.3s" begin="button.mouseenter" />
<animate attributeName="rx" to="0" dur="0.3s" begin="button.mouseleave" />
</rect>
<!-- Play button → Pause button -->
<polygon points="8 5, 8 19, 19 12">
<animate attributeName="points" to="8 5, 10 5, 10 19, 8 19" dur="0.3s" />
</polygon>
<circle r="5">
<animate attributeName="r" values="5;8;5" dur="1s" repeatCount="indefinite" />
</circle>
<!-- Circle to square -->
<rect rx="25"><animate attributeName="rx" to="0" /></rect>
<!-- Line to triangle -->
<polygon points="12 16, 20 16, 4 16">
<animate attributeName="points" to="12 4, 20 16, 4 16" />
</polygon>
<!-- Complex path morph -->
<path d="start-path">
<animate attributeName="d" to="end-path" />
</path>
Remember: You're not changing shapes, you're moving points!