# SVG Animations Reference Notes

# Core Concepts

## Coordinate vs Display Size

* **Coordinate size (viewBox)**: The "drawing paper" dimensions -&gt; `viewBox="0 0 100 100"`
    
* **Display size (width/height)**: How many pixels it takes on screen -&gt; `width="200px"`
    
* **Key insight**: Shapes use viewBox coordinates, SVG scales them to display size
    

## Path Model

All SVG shapes start as paths (outlines) that get filled/stroked:

* `fill` = color inside the shape
    
* `stroke` = outline color
    
* `stroke-width` = outline thickness
    

# Grouping with `<g>`

## Basic Grouping

```xml
<g stroke="red" fill="none" stroke-width="2">
  <rect x="10" y="10" width="50" height="30" />
  <circle cx="50" cy="50" r="20" />
</g>
```

* Shared attributes apply to all children
    
* Like a "config wrapper" (similar to framer-motion patterns)
    
* Transforms applied to groups affect all children
    

# CSS Transforms in SVG

## Basic Transforms

```css
.element {
  transform: translateY(-2px); /* Move up 2 units */
  transform: translateX(10px); /* Move right 10 units */
  transform: rotate(45deg); /* Rotate 45 degrees */
}
```

## CSS Units Requirement

```css
/* ✅ Correct -> CSS requires explicit units */
transform: translateY(-2px);

/* ❌ Invalid -> CSS won't accept unitless values */
transform: translateY(-2);
```

**Note**: `-2px` means "2 units in viewBox coordinates", not screen pixels

# Transform Origins (The Tricky Part)

## Default Behavior

* Default transform-origin in SVG = `0,0` (top-left of viewBox)
    
* NOT relative to the element being transformed!
    

## Manual Coordinates

```css
.lid {
  transform: rotate(120deg);
  transform-origin: 18px 8px; /* Exact viewBox coordinates */
}
```

* Must calculate exact coordinates where you want rotation center
    
* Pain to maintain if elements move
    

## Transform Box (Better but Limited)

```css
.element {
  transform-origin: center;
  transform-box: fill-box; /* Makes origin relative to element */
}
```

**Options:**

* `view-box` (default) -&gt; relative to viewBox
    
* `fill-box` -&gt; relative to element's filled area
    
* `stroke-box` -&gt; includes stroke in calculation
    

**Limitations:**

* Poor browser support (Safari issues, Firefox stroke-box)
    
* Doesn't work with groups -&gt; only individual shapes
    

# CSS Transitions

## Basic Animation

```css
.element {
  transition: transform 0.2s;
}

.element:hover {
  transform: translateY(-5px);
}
```

## Multiple Properties

```css
.element {
  transition: transform 0.2s, fill 0.3s;
}
```

# SVG Styling with CSS

## What Works as CSS Properties

**✅ Presentation attributes:**

* `stroke`, `fill`, `opacity`, `stroke-width`
    

**✅ Some geometry properties:**

* `x`, `y`, `cx`, `cy`, `r` (limited browser support)
    

**❌ Line-specific attributes:**

* `x1`, `y1`, `x2`, `y2` -&gt; NOT valid CSS properties
    

## Workaround for Unsupported Properties

Use transforms instead of direct coordinate changes:

```css
/* Instead of changing y1, y2 coordinates */
.line {
  transform: translateY(-2px);
}
```

# Animation Strategy

## The Hard vs Easy Parts

1. **Hard**: Structuring SVG for animation (grouping, coordinates)
    
2. **Easy**: Adding the actual animation (transitions)
    
3. **Annoying**: Transform origins and coordinate calculations
    

## Best Practices

* Group related elements with `<g>`
    
* Use transforms over direct coordinate changes
    
* Plan transform origins early
    
* Test across browsers (transform-box issues)
    

# ViewBox Camera Effects

## Basic Camera Movements

```xml
<!-- Zoom in: smaller viewBox area -->
<svg viewBox="25 25 50 50">

<!-- Pan right: move starting coordinates -->
<svg viewBox="50 0 100 100">

<!-- Wide shot: larger viewBox area -->
<svg viewBox="0 0 200 100">
```

## Animation Potential

* Zoom effects by changing viewBox dimensions
    
* Pan by changing x,y coordinates
    
* Cinematic effects with smooth transitions
    
* Perfect for React/TS library development
    

# Common Gotchas

1. **Transform origin confusion**: Default is viewBox (0,0), not element center
    
2. **CSS units required**: Must use `px` even for SVG coordinates
    
3. **Browser support**: transform-box has issues
    
4. **Groups vs individuals**: Some properties only work on individual shapes
    
5. **Coordinate calculation**: Manual math required for complex origins
