---
# System prepended metadata

title: SVG Note
tags: [svg]

---

# SVG Note

{%hackmd @RintarouTW/About %}

SVG Editor
https://editor.method.ac/

- [x] Event
- [x] Morphing
- [x] Path
- [x] Along Path
- [x] Filter
- [x] Embed $\LaTeX$
- [x] Mask
- [x] Clipping
- [ ] Pattern

## DOM

### Header

```javascript!
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 100" style="background-color:#111">
</svg>
```

### Defs

Definitions of the resources that could be "reused".

```javascript!
<defs>
...
</defs>
```

#### Style

almost the same with CSS.

```css!
<style>
...
</style>
```

##### Animation(Keyframes)

```css!
@keyframes animation_name {
    from { ... }
    to { ... }
}
```

**Example**

Rotate360

```css!
@keyframes rotate360 {
  to { 
    transform: rotate(-360deg); 
  }
}
```
#### Element

- `<line x1 y1 x2 y2 />`
- `<circle x y r />`
- g(group)
- `<polygon points= .../>`
- `<path d=path commands />`
    path commands:
    - M: move(x y)
    - H: line to horizontally (dx)
    - V: line to vertically (dy)
    - C: curve to (x1 y1 x2 y2 x y)
    - Q: curve to (x1 y1 x y)
- marker
    - marker-start
    - marker-mid
    - marker-end

#### Filter

**Gaussian Blur**

```javascript!
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="1" />
<rect filter="url(#blurMe)">
</filter>
```

**Custom Shadow**

```javascript!
  <filter id="dropShadow">
    <feGaussianBlur in="SourceAlpha" stdDeviation="3" />
    <feOffset dx="2" dy="4" />
    <feMerge>
        <feMergeNode />
        <feMergeNode in="SourceGraphic" />
    </feMerge>
  </filter>

  <circle cx="60"  cy="60" r="50" fill="green"
          filter="url(#dropShadow)" />
```

- [feDropShadow](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feDropShadow)

**Lightings**

- [feDiffuseLighting](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feDiffuseLighting)
- [feDistantLight](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feDistantLight)
- [feSpotLight](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feSpotLight)
- [fePointLight](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/fePointLight)
- [feSpecularLighting](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feSpecularLighting)

### Use

x, y is the origin(anchor point) of the referenced element(#id), so the referenced elements could be defined in their own local coodinate space.

```javascript!
<use x="50%" y="50%" href="#id" />
```

## Tips

### SVG Background Color

```javascript!
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 100" style="background-color:#111">
```

### Coordinate System

(0, 0) is the top-left of the svg by default.

#### ViewBox

Define the view port rect.

### Transformation

- translate()
- scale()
- rotate()

### Basic Animation

- Animation with @keyframes (CSS animation)
- `<animate>`
- `<animateColor>`
- `<animateTransform>`
- `<animateMotion>`

**calcMode** = discrete | linear | paced | spline
**values**
**keyTimes**
**keySplines**
![](https://i.imgur.com/xmXS6Y9.png)
**from**
**to**
**by**

### Shape Morphing

https://css-tricks.com/svg-shape-morphing-works/

```javascript!
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 100" style="background-color:#111">
<polygon fill="#0f0" points="0 0, 10 0, 10 10, 0 10">
<animate attributeName="points" begin="0s" dur="1s" to="20 20, 30 20, 40 30, 50 50" repeatCount="indefinite" />
</polygon>
</svg>
```

### Path

https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths


| command | function           | parameters                            |
|:------- |:------------------ |:------------------------------------- |
| M(m)    | Move to            | (d)x, (d)y                            |
| L(l)    | Line to            | (d)x, (d)y                            |
| H(h)    | Horizontal line to | (d)x                                  |
| V(v)    | Veritical line to  | (d)y                                  |
| A(a)    | Arc to             | rx ry radius (d)x (d)y                |
| C(c)    | Bezier Curve to    | (d)cx1 (d)cy1 (d)cx2 (d)cy2 (d)x (d)y |
| S(s)    | Bezier Curve to    | (d)cx2 (d)cy2 (d)x (d)y |
| Q(q)    | Bezier Curve to    | (d)cx (d)cy (d)x (d)y |
| T(t)    | Bezier Curve to    | (d)x (d)y |
| Z/z     | Close Path         |                                       |


### animateMotion

Animate along path.
Reuse path via mpath.

```javascript!
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 100" style="background-color:#111">
<defs>
<path id="myPath" d="M150 50 H100 V40 H150 V50 z" />
<rect id="box1" x="0" y="0" width="10" height="10" fill="#0f0" opacity="70%">
<animateMotion id="first" dur="1s" begin="0s;second.end">
<mpath href="#myPath" />
</animateMotion>
</rect>
<rect id="box2" x="0" y="0" width="10" height="10" fill="#ff0" opacity="70%">
<animateMotion id="second" dur="1s" begin="first.end">
<mpath href="#myPath" />
</animateMotion>
</rect>
</defs>
<use x="0" y="0" href="#box1" />
<use x="0" y="0" href="#box2" />
</svg>
```

### Clipping and Masking

https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Clipping_and_masking

**Clipping the element with a clipPath.**

```javascript!
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <clipPath id="cut-off-bottom">
      <rect x="0" y="0" width="200" height="100" />
    </clipPath>
  </defs>

  <circle cx="100" cy="100" r="100" clip-path="url(#cut-off-bottom)" />
</svg>
```

**Alpha Masking**

```javascript!
<svg width="200" height="200" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <linearGradient id="Gradient">
      <stop offset="0" stop-color="black" />
      <stop offset="1" stop-color="white" />
    </linearGradient>
    <mask id="Mask">
      <rect x="0" y="0" width="200" height="200" fill="url(#Gradient)"  />
    </mask>
  </defs>

  <rect x="0" y="0" width="200" height="200" fill="green" />
  <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#Mask)" />
</svg>
```

The color component of the gradient is used as the alpha mask.

## Event

Event can't work when `svg` is emebed by `<img>` tag.
Only `<svg>` tag in raw html would be parsed by the DOM.

### Begin Animate by SVG itself


```javascript!
<polygon id="shape" points=" ... shape 1 points ... ">

  <animate begin="shape.click" attributeName="points" dur="500ms" to=" ... shape 2 points ... />

</polygon>
```

**Animate Chain**

```javascript!
<rect width="10" height="10" x="30" y="10" fill="#00f">
  <animate id="third" attributeName="x" to="40" begin="second.end" dur="1s" />
</rect>
<rect width="10" height="10" x="20" y="10" fill="#0f0">
  <animate id="second" attributeName="x" to="30" begin="first.end" dur="1s" />
</rect>
<rect width="10" height="10" x="10" y="10" fill="#f00">
  <animate id="first" attributeName="x" to="20" begin="0s;third.end" dur="1s" />
</rect>
```


### Begin Animate by JavaScript

**SVG**

```javascript!
<animate id="animation-to-check" begin="indefinite" ... />
```

**Javascript**

```javascript!
<html>
  <body>
    <svg width="300" height="120"  viewBox="0 0 300 120" xmlns="http://www.w3.org/2000/svg">
      <text x="10" y="20">JavaScript Animation Trigger Test</text>
      <!-- animated rectangle -->
      <rect id="box" x="10" y="35" height="15" width="0" class="test">
      <animate id="ani" attributeName="width" from="0" to="100" begin="startButton.click" dur="8s" fill="freeze" />
      </rect>
    </svg>
    <script>
      let ani = document.getElementById('ani')
      ani.beginElement()
    </script>
  </body>
</html>
```

## SVG + $\LaTeX$

```javascript!
<html>
  <head>
    <script type="text/javascript" id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"> </script>
  </head>
  <body>
    <svg viewBox="0 0 300 200">
        <foreignObject width="200" height="110" x="10" y="10" transform="translate(200 0) scale(0.3 0.3)">
        <text> \( \pmatrix{x\\y}\implies\pmatrix{-y\\x} \) </text>
        <text> \( \pmatrix{x\\y}\implies\pmatrix{y\\x}\implies\pmatrix{-y\\x} \) </text>
        </foreignObject>
    </svg>
  </body>
</html>
```



## References

- https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute

###### tags: `svg`