# 【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://hackmd.io/_uploads/BkKmDGsTh.png) *圖片來源: https://developer.mozilla.org/zh-TW/docs/Web/SVG/Tutorial/Positions/canvas_default_grid.png* ### 實際簡易演練---圓圈 問題:為何只出現一小部分的圓呢 ![](https://hackmd.io/_uploads/SyjVYfiT2.png) 答:因為觀景窗預設起點為(0,0) ![](https://hackmd.io/_uploads/S1ahKfiT2.png) *圖片來源:https://hahow.in/courses/56189df9df7b3d0b005c6639/discussions?item=5a1e1745a2c4b000589dd22c* 解決方法: 改變觀景窗起點位置。(如下圖) ![](https://hackmd.io/_uploads/HkdDcGjpn.png) ## CSS/SVG比較表格 SVG屬性值與CSS不同 ![](https://hackmd.io/_uploads/SJHwhzjan.png) *圖片來源: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 ``` **呈現** ![](https://hackmd.io/_uploads/SkB-IXsp2.png) ## 讓圖像動起來! 製作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 :::