TP Notes
全部
CSS
SVG
資源收集
HTML
其它
關於我
2020年11月27日 星期五
SVG 的文字
以前自己開發繪圖函式庫時,字都是自己畫,一開始是抓倚天中文的字形檔,後來用自己的方式產生自己的字形檔,並加上 alpha 來做反鋸齒,當時還為了開發泰國版本,自行設計泰文輸入法,雖然可以使用 truetype 字形,但是當時硬體規格太差,為了速度,還是要自己寫效率比較高,現在看到 SVG 文字相關的定義,真的覺得當初自己所想到的功能太陽春,SVG 的規劃要完整多了。 ## text 的參數如下: ```css x,y 座標 dx,dy 偏移 rotate 旋轉 lengthAdjust spacing (預設) 字與字之間以空白做間隔 spacingAndGlyphs 字與字之間以變形填滿 textLength 字串長度 text-anchor start , middle , end 文字定位 以下參數也可以做為 CSS 的參數 dominant-baseline auto (預設) text-bottom alphabetic ideographic middle central mathematical hanging text-top writing-mode horizontal-tb vertical-rl vertical-lr ``` 先來一個簡單範例 ``` $mmcode(r1) ```
1a
1a
可以發現,SVG 的字完全就是用畫的,像多邊形一樣,所以右邊的文字有加上 `stroke-linejoin="round"` 在角落的地方就成了圓角 文字處理另一個麻煩的就是基準線,這裡使用的是 dominant-baseline ,可以當作參數,也可以當作 CSS 使用
auto
測試1a
CSS 的文字有個很特別的設計,利用類似陣列的方式為每一個字設定屬性 ``` $mmcode(r3) ```
abcde
也可以用 dx 和 dy 做偏移 ``` $mmcode(r4) ```
abcde
可以用 rotate 旋轉, 而旋轉預設的中心點在左下角 ``` $mmcode(r5) ```
abcde ddd
textLength 和 lengthAdjust 搭配,設定字串長度後,看要用空白還是變形的方式填空間 ``` $mmcode(r6) ```
abcde
abcde
abcde
直寫測試123
# tspan 當一段文字想要有不同設定時,可以用 tspan ,就如同 css 的 span 一樣,搭配 dominant-baseline 就可以做到上標字和下標字的效果,
*經實測結果 Firefox 會不正常顯示
,以下正確結果應該顯示為
X₂+Y²=Z⁽²ⁿ⁺¹⁾
``` $mmcode(r7) ```
abc
123
def
def
ghi
X
2
+Y
2
=Z
(2n+1)
如果要完全相容的上標和下標字,似忽只有利用 dy 來實作,但是這個缺點就是,沒辦法單純用 css 來完成,而且 `
` 的定義很奇怪,一但 dy 改變了,就是改變了,並不會在 `
` 時變回來,所以在使用上標字(dy 減去某個值) ,必須在下一個顯示的字把 dy 的值加回來。 ``` $mmcode(r8) ```
X
2
+Y
2
=Z
(2n+1)
為了處理上標和下標問題,只好利用 javascript 來協助,加上 svgsup 和 svgsub 兩個 class ,由 javascript 來處理 dy 的問題,程式碼很簡單,效果也不錯 ``` $mmcode(svgsup) ```
X
2
+Y
2
=Z
(2n+1)
# textPath SVG 有個有趣的東西叫 textPath ,文字可以隨著路徑跑,這個功能當初我在設計網頁上的向量地圖時曾經用來顯示路名 當初在寫導航程式顯示路名時,字隨路徑走是用比較偷懶的方式,計算出每個字的座標,但是字不會旋轉,隨著現在硬體規格越來越強,加上 SVG 有這麼方便的指令,要開發 2D 地圖真的簡單多了。 ``` $mmcode(r9) ```
文字可以隨著路徑跑
startOffset="100"
可以使用
tspan
來做效果
這個設定在 iPhone 及 safari 沒用
dominant-baseline="central"
直式書寫 writing-mode:vertical-lr;
文字可以隨著路徑跑,那麼是不是可以取得路徑長度後,計算每個字的間距,讓字平均分布呢 ? 方法如下 : ``` let pp = document.getElementById("[path 的 ID]"); let len = pp.getTotalLength(); //取得路徑總長度 let xy = pp.getPointAtLength(500); //取得距離 500 的點位 , return {x:n,y:m} let box = pp.getBBox(); //取得路徑範圍 , return {x:n,y:n,width:n,height:n} ``` 取得長度後就可以計算平均分布的位置 ``` $mmcode(r10) ```
文字可以隨著路徑跑喲
2020年11月25日 星期三
SVG 材質貼圖
對於 2D 的圖形,材質貼圖相當實用,可以讓畫面更美觀,當初自己在設計繪圖函式庫時也花了不少時間在處理貼圖的部份,而現在 SVG 的貼圖做得更加完善 ``` pattern 參數 : viewBox "x,y,width,height" width 貼圖範圍 height patternUnits objectBoundingBox (預設) userSpaceOnUse patternTransform 接 transform 參數 preserveAspectRatio 預設 xMidYMid meet ``` 先來一個最常用的範例 用 pattern 建立一個材質,使用 fill="url(#ID)" 來使用這個材質 ``` $mmcode(r1) ```
## 詳細說明如下 : ### 圖1 當設定viewBox 以及 width 和 height 必須用 % (百分比) 表示時,材質大小會跟著縮放 ``` viewBox="0,0,40,40" width="20%" height="20%" ```
### 圖2 圖1 加上 preserveAspectRatio="none" 後,材質比例也跟著變形 ``` viewBox="0,0,40,40" width="20%" height="20%" preserveAspectRatio="none" ```
### 圖3 設定 patternUnits ="userSpaceOnUse" 後,材質變成以整個 svg 為底,大小位置也固定了 ``` viewBox="0,0,40,40" width="20%" height="20%" patternUnits ="userSpaceOnUse" ```
### 圖4 不設定 viewBox 只設定 patternUnits ="userSpaceOnUse" 時,width 和 height 如果用數字就是材質大小 ,如果是百分比 (%)就是百分比 ``` width="40" height="40" patternUnits ="userSpaceOnUse" ```
2020年11月22日 星期日
SVG 的 marker
SVG 對於線段有個有用的設定是 marker , 可以用來設定線段的起點、中間點,和終點的圖示 ``` marker 的參數 : viewBox 設定 icon 大小,格式為 "x y 寬 高" refX 設定 icon 的原點座標 refY markerWidth 設定 icon 要縮放的大小 markerHeight orient 設定 icon 旋轉角度,設 auto 的話會自動隨者線段旋轉,auto-start-reverse 則起點會反過來 ``` 使用時只要加上
marker-start(#ID) , marker-mid(#ID) , marker-end(#ID)
即可 ``` $mmcode(r0) ```
``` $mmcode(r1) ```
圖1:marker 的箭頭,一個長寬都是20方向向右的三角形
圖2:由 markerWidth 和 markerHeight 把箭頭設為 15x15
圖3:加上 orient="45",箭頭角度向右旋轉 45 度
圖4:加上 orient="auto" 後,箭頭角度會隨著線旋轉
圖5:加上 orient="auto-start-reverse" 後,起點的箭頭角度會旋轉 180 度
圖6:當線條寬度設為 2 時 (stroke-width="2") 箭頭也隨著增大兩倍
2020年11月20日 星期五
SVG 的 mask
SVG 的 mask 和 CSS 有一點不同,用的是黑白來代表透明度,白色是不透明,黑色是透明,如以下範例,圖1是 mask 用的圖,圖2是 rect 套用 mask 後,由黃色部份可以看到,中間的那個心是透明的。 clip-path 是直接裁切,mask 似忽可以取代 clip-path,而且還可以加上透明度 ``` $mmcode(r1) ```
圖1
圖2
## mask 的有趣範例 直接把圖檔當成 mask ,可以把彩色圖片變成黑白 ``` $mmcode(r2) ```
圖片套用文字當 mask,可以做出不錯的文字特效 ``` $mmcode(r3) ```
ASDF
ASDF
2020年11月18日 星期三
CSS 狀態改變動畫
之前寫了一篇 [CSS 動畫](https://yhtpnotes.blogspot.com/2020/05/css.html) 時,忘了應該先寫這個狀態變化的動畫,大部份的應用都是用在滑鼠移到上面時的用動畫方式改變狀態,實際上,這個功能對於所有狀態變化都可以變成動畫 參數說明: ``` transition [動畫持續時間] [delay 多久開始] [timing-function] transition-delay [delay 多久開始] transition-duration [動畫持續時間] transition-property [指定改變的屬性] transition-timing-function [動畫 timing] ``` 我個人偏好不使用 transition-property ,這樣可以更自由的使用這個功能 首先先來一個最簡單的範例: 在 **#a11181_div:hover** 裡頭加了 **transition: 1s** 後 ,滑鼠移過去時,顏色會慢慢的變成黃色,同時長度從 100px 慢慢變成 200px, 當滑鼠移開時,因為在 **#a11181_div** 加上了 **transition: 0.2s;** ,會以動畫方式很快的恢復原狀,如果沒有加上 **transition** ,狀態會瞬間改變,不會有動畫效果,另外還有加上 **transition-delay** , 所以會等 0.5 秒後才開始動畫 而下面的 [SET] 和 [UNSET] 是利用 javascript 去做設定,結果一樣會以動畫顯示, 當用 javascript 設定時,是直接寫在元件上,所以 hover 改變 width 就沒作用了,而 [CSS SET] 和 [CSS UNSET] 的是直接修改本來的 CSS 設定,所以不影響 hover 。 ``` $mmcode(r1) ```
SET
UNSET
CSS SET
CSS UNSET
2020年11月14日 星期六
戲說線段
線段有很多屬性,無意間看到有人利用這些屬性做動畫相當有意思,決定先來整理線段的屬性 # stroke-linecap
圖1:
polyline
圖2:(預設)
stroke-linecap="butt"
圖3:
stroke-linecap="round"
圖4:
stroke-linecap="square"
# stroke-linejoin
圖1:(預設)
stroke-linejoin="miter"
圖2:
stroke-linejoin="round"
圖3:
stroke-linejoin="bevel"
圖4:(可能無作用)
stroke-linejoin="miter-clip"
圖5:(可能無作用)
stroke-linejoin="arcs"
# stroke-dasharray 這是一個陣列型態,奇數為要顯示的點數,偶數為不顯示的點數
[10,20] 等於 [10,20,10,20,....] 換言之如果陣列是基數 [10,20,30] 等於 [10,20,30,10,20,30,....]
圖1:
stroke-dasharray="10"
圖2:
stroke-dasharray="10,20"
圖3:
stroke-dasharray="10,20,30"
# stroke-dashoffset 虛線起始的點數
圖1:
stroke-dashoffset="0"
圖2:
stroke-dashoffset="10"
圖3:
stroke-linecap="round"
利用 stroke-dashoffset 來產生動畫 ``` $mmcode(r1) ```
搭配 path 可以做出相當有意思的動畫 ``` $mmcode(r3) ```
也可以用在滑鼠移動時的動態效果 ``` $mmcode(r4) ```
2020年11月13日 星期五
Inline SVG
SVG 本身被視為圖檔,那麼能不能畫好一個 SVG 後,即時拿來用在 html 中的 img 或 background-image 呢 ? 方法還是有的,只是必須透過 javascript 才行 主要用的技巧是 **
data:image/svg+xml;base64,[data]
**
那麼如果不用 base64 呢 ? 也可以用 **
data:image/svg+xml;charset=UTF-8,[data]
** 或 **
data:image/svg+xml;utf8,[data]
** 而這個 **[data]** 必須用 escape 轉換 在實測過程中發現,平常使用 SVG 時並沒有加上完整檔頭,以致於花了些時間才找到圖片出不來的原因 SVG 檔頭宣告 : **
xmlns="http://www.w3.org/2000/svg"
** ```
``` 範例如下 : ``` $mmcode(r1) ```
SVG 的 clipPath
SVG 有超強的 path 可以設定路徑,也可以用這個路徑來做一些應用,最實用的功能之一就是裁切, 而且在 SVG 的 defs 中定義的 clipPath 可以直接在 CSS 裡面用,在 MAC 的 safari 以及 iphone 上要使用 -webkit-clip-path ,但是也不完全正常,使用方式在 style 裡頭加上 ```clip-path:url(#ID);-webkit-clip-path:url(#ID);``` 即可 如以下範例,圖四是使用 img + clip-path 做裁切,因為在 clipPath 使用了多個 path ,在 safari 以及 iphone 上無法正常顯示,而圖六是用 svg 的 image 顯示圖片,並且使用 clip-path 裁切,在所有瀏覽器都可以正常顯示。 範例如下: ``` $mmcode(r1) ```
圖一
圖二
圖三
圖四
圖五
圖六
clipPath 裡頭的路徑都是 OR 運算,要做 AND 運算的話,可以在 clipPath 再加上 clip-path **(圖三)** 在這個範例中畫了一個星星,通常在繪圖時要挖空重疊的部份用的是 **fill-rule="evenodd"** ,然而在 clipPath 中無效,必須用 **clip-rule="evenodd"** 才行 在這邊也發現了一個 chrome 的 bug , clipPath 基本上無法做 XOR 運算,結果圖四在 chrome 卻出現了類似 XOR 的效果,在 firefox 和 safari 沒有問題 ``` $mmcode(r2) ```
圖一
圖二
圖三
圖四
2020年11月12日 星期四
SVG 的 defs 以及漸層填色
SVG 的 defs 可以用來定義各種圖形或路徑,在其它 svg 中只要用 ```
``` 即可引用,範例如下 在這個範例中,第一個 svg 是隱藏的,純脆只定義幾個矩形,下面兩個 svg 引用後繪製圖形,在引用時可以設定裡頭的參數,而這裡設定的座標參數是相對座標 defs 的位置似忽沒有限制,範例中的 a11121_rect5 在前面使用,卻在後面才定義,結果一樣可以正常顯示 ``` $mmcode(r1) ```
x=30
x=200
x=100
x=130
改顏色
新增矩形
# defs 的應用-漸層填色 defs 的第一個應用是漸層填色,和 CSS 的漸層填色很像,一個線性漸層和一個圓形漸層 基本範例 : ``` $mmcode(r2) ```
取消填色
## linearGradient 線性漸層 參數 : ```css x1,y1,x2,y2 從 x1,y1 漸層到 x2,y2 , 可以用 5% 或 0.5 表示 gradientTransform 和 CSS 的 transform 一樣 spreadMethod pad(預設) , reflect , repeat href 引用別處定義的 stop 值 ``` ## radialGradient 圓形漸層 ```css cx,cy,r 圓形漸層的圓心座標和半徑 gradientTransform 和 CSS 的 transform 一樣 spreadMethod pad(預設) , reflect , repeat (經測試,在 MAC的Safari 和 iphone 沒作用) fx,fy,fr 在cx,cy,r的圈圈中,漸層的中心點和半徑 href 引用別處定義的 stop 值 ``` 範例 : ``` $mmcode(r3) ```
既然可以用圓形漸層,就可以做出立體的球囉! ``` $mmcode(r4) ```
‹
›
首頁
查看網路版