# SVG Morph Animation Reference

# Core Principle

**Morph = animate attributes of the SAME element, not between different elements**

```html
<!-- ❌ 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>
```

# The Process

1. **Identify start/end shapes**
    
2. **Choose ONE element type** that can represent both
    
3. **Find attributes that change** between the shapes
    
4. **Animate those attributes**
    

# Common Morph Patterns

## Circle ↔ Rectangle

Use `<rect>` with `rx` attribute

```html
<!-- 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>
```

## Line ↔ Triangle

Use `<polygon>` with same point count

```html
<!-- 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>
```

## Rectangle ↔ Triangle

Use `<polygon>` with 4 points (overlap for triangle)

```html
<!-- 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>
```

# Point Count Rule

**CRITICAL: Same number of points in start and end states**

```html
<!-- ❌ 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
    

# Path Morphing

Use `<path>` with same command structure

```html
<!-- 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>
```

# Element Choice Guide

| 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. |

# CSS vs SMIL Animation

## SMIL (recommended for morphing)

```html
<rect rx="25">
  <animate attributeName="rx" to="0" dur="1s" fill="freeze" />
</rect>
```

## CSS (limited support for morphing)

```css
/* Only works for simple numeric attributes */
rect {
  rx: 25;
  transition: rx 1s;
}
rect:hover {
  rx: 0;
}
```

# Common Gotchas

## Coordinate System

```html
<!-- 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>
```

## Point Order Matters

```html
<!-- 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"
/>
```

## Path Command Compatibility

```html
<!-- ❌ 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"
/>
```

# Practical Examples

## Button State Changes

```html
<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>
```

## Icon Transformations

```html
<!-- 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>
```

## Loading States

```html
<circle r="5">
  <animate attributeName="r" values="5;8;5" dur="1s" repeatCount="indefinite" />
</circle>
```

# Quick Reference

```html
<!-- 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**!
