# 【Day14】SVG應用
## SVG是甚麼
SVG為==可縮放的向量圖形==
在縮放時,它的像素都不會變,也就是說,放多大都會很清楚;
而一般的圖片為點陣圖,放大時會變得模糊。
## SVG常用元素與其屬性
- line 直線
x1,y1,x2,y2 (起點,終點)
- rect 矩形
x,y,w,h (起點,寬高)
- circle 圓圈
cx,cy,r (起點,終點,半徑)
- ellipse 橢圓
cx,cy,rx,ry
- polyline 折線
points="x,y;x,y"
## 繪製向量圖片
### 座標概念圖

*圖片來源: https://developer.mozilla.org/zh-TW/docs/Web/SVG/Tutorial/Positions/canvas_default_grid.png*
### 實際簡易演練---圓圈
問題:為何只出現一小部分的圓呢

答:因為觀景窗預設起點為(0,0)

*圖片來源:https://hahow.in/courses/56189df9df7b3d0b005c6639/discussions?item=5a1e1745a2c4b000589dd22c*
解決方法:
改變觀景窗起點位置。(如下圖)

## CSS/SVG比較表格
SVG屬性值與CSS不同

*圖片來源:https://hahow.in/courses/56189df9df7b3d0b005c6639/discussions?item=5a1e1745a2c4b000589dd22c*
## 初階繪製SVG參考範例
**程式碼**
HTML(jade)
```htmlmixed=
svg#pic1(viewbox="-50 -50 100 100")
line(x1=-20 y1=0 x2=20 y2=0)
line(x1=-0 y1=-20 x2=0 y2=20)
circle(cx=0 cy=0 r=10)
svg#pic2(viewbox="-50 -50 100 100")
circle(cx=0 cy=0 r=10)
line(x1=-20 y1=0 x2=20 y2=0)
line(x1=-0 y1=-20 x2=0 y2=20)
rect(x=-20 y=-20 width=40 height=40)
svg#pic3(viewbox="0 0 200 200")
circle(cx=0 cy=50 r=3)
circle(cx=50 cy=80 r=3)
circle(cx=100 cy=60 r=3)
circle(cx=150 cy=20 r=3)
circle(cx=200 cy=40 r=3)
polyline(points="0,50 50,80 100,60 150,20 200,40")
svg#pic4(viewbox="0 0 200 200")
rect(x=0 y=0 width=20 height=100)
rect(x=30 y=0 width=20 height=120)
rect(x=60 y=0 width=20 height=140)
rect(x=90 y=0 width=20 height=160)
rect(x=120 y=0 width=20 height=120)
rect(x=150 y=0 width=20 height=80)
rect(x=180 y=0 width=20 height=60)
svg#pic5(viewbox="-50 -40 100 100")
rect(x=-30 y=-20 width=60 height=40)
rect(x=-25 y=-15 width=50 height=30)
rect(x=-2 y=20 width=4 height=10)
rect(x=-10 y=30 width=20 height=5)
line(x1=-20 y1=0 x2=-8 y2=0)
line(x1=-20 y1=5 x2=-5 y2=5)
circle(cx=10 cy=0 r=7 )
text(x=-30 y=50) My computer
```
CSS(sass)
```css=
svg
width: 240px
border: solid 2px
#pic1
stroke: black
stroke-width: 3px
& circle
fill: white
#pic2
stroke: black
stroke-width: 2px
& circle
fill: white
& rect
fill: none
#pic3
stroke: black
stroke-width: 2px
& polyline
fill: none
#pic5
stroke: black
stroke-width: 2px
fill: none
& circle
fill: red
stroke: none
& text
fill: black
stroke: none
font-family: 微軟正黑體
font-size: 10px
```
**呈現**

## 讓圖像動起來!
製作SVG動畫大致上可分為三種方式:
1. 針對**屬性**值做動畫
animate(attributeName="屬性x/y/width..." dur="長度" values="影格" repeatCount="次數")
:::info
優點:動畫直接寫在HTML裡,不需要在CSS做調整即完成。
缺點:能設定的東西較少,例如:速度曲線調整。
:::
2. 針對**變形/位移**做動畫
animateTransform(attributeName="transform" type="屬性scale/rotate" dur="長度" values="影格" repeatCount="次數")
:::info
優點:動畫直接寫在HTML裡,不需要在CSS做調整即完成。
缺點:能設定的東西較少,例如:速度曲線調整,在定義一些影格時可能較為麻煩。
:::
3. 使用**CSS**做動畫
transform: translateX/translateY/scale/rotate...(與之前同)
transition-duration: 時長
transition-origin: x位置 y位置 (e.g. center bottom /100% 0%)
animation/keyframes...
:::info
優點:動畫直接寫在HTML裡,不需要在CSS做調整即完成。
缺點:能設定的東西較少,例如:速度曲線調整。
:::
## 進階繪製SVG參考範例---讓圖片動起來
**程式碼**
HTML(jade)
```htmlmixed=
svg#pic1(viewbox="-50 -50 100 100")
line(x1=-20 y1=0 x2=20 y2=0)
line(x1=-0 y1=-20 x2=0 y2=20)
circle(cx=0 cy=0 r=10)
animate(attributeName="r" dur="2s" values="10;20;10" repeatCount="indefinite")
svg#pic2(viewbox="-50 -50 100 100")
circle(cx=0 cy=0 r=10)
g
line(x1=-20 y1=0 x2=20 y2=0)
line(x1=-0 y1=-20 x2=0 y2=20)
rect(x=-20 y=-20 width=40 height=40)
animateTransform(attributeName="transform" type="rotate" dur="2s" values="0;360" repeatCount="indefinite")
svg#pic3(viewbox="0 0 200 200")
circle(cx=0 cy=50 r=3)
animate(attributeName="cy" dur="2s" values="50;60;50" repeatCount="indefinite")
circle(cx=50 cy=80 r=3)
animate(attributeName="cy" dur="2s" values="80;40;80" repeatCount="indefinite")
circle(cx=100 cy=60 r=3)
animate(attributeName="cy" dur="2s" values="60;30;60" repeatCount="indefinite")
circle(cx=150 cy=20 r=3)
animate(attributeName="cy" dur="2s" values="20;70;20" repeatCount="indefinite")
circle(cx=200 cy=40 r=3)
animate(attributeName="cy" dur="2s" values="40;60;40" repeatCount="indefinite")
polyline(points="0,50 50,80 100,60 150,20 200,40")
animate(attributeName="points" dur="2s" values="0,50 50,80 100,60 150,20 200,40;0,60 50,40 100,30 150,70 200,60;0,50 50,80 100,60 150,20 200,40" repeatCount="indefinite")
svg#pic4(viewbox="0 0 200 200")
rect(x=0 y=0 width=20 height=100)
animate(attributeName="height" begin="0s" dur="2s" values="100;200;100" repeatCount="indefinite")
rect(x=30 y=0 width=20 height=120)
animate(attributeName="height" begin="-0.3s" dur="2s" values="100;200;100" repeatCount="indefinite")
rect(x=60 y=0 width=20 height=140)
animate(attributeName="height" begin="-0.6s" dur="2s" values="100;200;100" repeatCount="indefinite")
rect(x=90 y=0 width=20 height=160)
animate(attributeName="height" begin="-0.9s" dur="2s" values="100;200;100" repeatCount="indefinite")
rect(x=120 y=0 width=20 height=120)
animate(attributeName="height" begin="-1.2s" dur="2s" values="100;200;100" repeatCount="indefinite")
rect(x=150 y=0 width=20 height=80)
animate(attributeName="height" begin="-1.5s" dur="2s" values="100;200;100" repeatCount="indefinite")
rect(x=180 y=0 width=20 height=60)
animate(attributeName="height" begin="0s" dur="2s" values="100;200;100" repeatCount="indefinite")
svg#pic5(viewbox="-50 -40 100 100")
rect.frame_outer(x=-30 y=-20 width=60 height=40)
rect.frame_inner(x=-25 y=-15 width=50 height=30)
rect.neck(x=-2 y=20 width=4 height=10)
rect.bottom(x=-10 y=30 width=20 height=5)
g.screen_content
line(x1=-20 y1=0 x2=-8 y2=0)
line(x1=-20 y1=5 x2=-5 y2=5)
circle(cx=10 cy=0 r=7 )
text.text(x=-30 y=50) My computer
```
CSS(sass)
```css=
svg
width: 240px
border: solid 2px
#pic1
stroke: black
stroke-width: 3px
& circle
fill: white
#pic2
stroke: black
stroke-width: 2px
& circle
fill: white
& rect
fill: none
#pic3
stroke: black
stroke-width: 2px
& polyline
fill: none
#pic5
stroke: black
stroke-width: 2px
fill: none
& circle
fill: red
stroke: none
& text
fill: black
stroke: none
font-family: 微軟正黑體
font-size: 10px
.frame_outer, .frame_inner, .neck, .bottom
transform: scale(0)
transform-origin: left center
transition-duration: 0.5s
transition-delay: 0.5s
.screen_content
opacity: 0
transition-duration: 0.5s
transition-delay: 0s
&:hover
.frame_outer, .frame_inner, .neck, .bottom
transform: scale(1)
transition-delay: 0.5s
.neck, .bottom
transition-delay: 0s
.screen_content
opacity: 1
transition-delay: 1s
```
**呈現**
{%youtube zHoTdat4ozc %}
:::warning
內容主要整理自「動畫互動網頁程式入門 (HTML/CSS/JS)」課程,網址:https://hahow.in/courses/56189df9df7b3d0b005c6639/discussions?item=5a1e1745a2c4b000589dd21d
:::