SVG
Jump to navigation
Jump to search
Compatibility of Browsers
| Chrome | Edge | Firefox | Safari | |
|---|---|---|---|---|
| <text alignment-baseline="..."> | O | ? | X | ? |
| <use href="..."> | O | ? | O | X |
| <use xlink:href="...."> | O | O | O | O |
https://stackoverflow.com/questions/43961807/svg-use-not-working-in-safari
Better approach to trigger an event
<template lang="pug">
<svg>
<g @click="onClickShape">
<!-- shape to receive click event -->
</g>
</svg>
</template>
<script>
export default {
methods: {
onClickShape (e) {
// TODO: Do something ...
}
}
}
</script>常用換算
| TODO | Code |
|---|---|
| Get width of <text> element. |
Math.max.apply(null, d3.selectAll("text").nodes().map((e) => { return e.getBBox().width; }))
|
常用濾鏡
| 濾鏡效果 | 濾鏡 code |
|---|---|
| 陰影特效 |
<filter id="dropShadow">
<feGaussianBlur in="SourceAlpha" stdDeviation="3" />
<feOffset dx="4" dy="4" />
<feBlend in="SourceGraphic" />
</filter>
|
常用座標轉換
| 轉換效果 | 轉換 code |
|---|---|
| 相對定位 |
<g transform="translate(X Y)"></g>
|
| 以 (X, Y) 為原點,轉換笛卡兒座標系 |
<g transform="translate(X Y) scale(1 -1)"></g>
|
| 在笛卡兒座標系中的指定位置顯示文字 (用 x, y 屬性會上下顛倒) |
<!-- 方法 1 -->
<text transform="translate(X Y) scale(1 -1)">fuck</text>
<!-- 方法 2 -->
<text transform="scale(1 -1) translate(X -Y)">fuck</text>
<!-- 方法 3: 適用於多組文字 -->
<g transform="scale(1 -1)">
<text transform="translate(X1 -Y1)">fuck 1</text>
<text transform="translate(X2 -Y2)">fuck 2</text>
</g>
|
扇形繪圖法
<path d="m 160 160 l 0 -150 a 150 150 0 0 1 150 150 z" />
<path d="m 160 160 l 0 -150 a 150 150 0 1 0 150 150 z" />
這個畫法從圓心出發,畫直線到第一個點,再順時針畫弧線,最後畫一直線回圓心,其中 a 指令的部分比較難
| a | 150 | 150 | 0 | 0 | 1 | 150 | 150 |
|---|---|---|---|---|---|---|---|
| a | 150 | 150 | 0 | 1 | 0 | 150 | 150 |
| 弧線指令 (相對座標) |
半徑X | 半徑Y | X軸旋轉角度 | 0 小弧線 1 大弧線 |
0 逆時針 1 順時針 |
X 偏移 | Y 偏移 |
以 d3.js 畫任意角度扇形
| 參數說明 | File:ArcPathDemo.png | |
|---|---|---|
| start | 起點角度 | |
| end | 終點角度 | |
| r | 半徑 (圓心 ~ 0度角長度) | |
| ratio | 半徑寬高比 | |
// 畫扇形
var r = 120;
var ratio = 2;
var start = -90;
var end = 180;
var rx = r;
var ry = Math.floor(r / ratio);
var dtpl = "m 160 160 l {X1} {Y1} a {RX} {RY} 0 {LA} 1 {X2} {Y2} z";
var deg = Math.PI/180;
var x1 = Math.floor(rx * Math.cos(start * deg));
var y1 = Math.floor(ry * Math.sin(start * deg));
var x2 = Math.floor(rx * Math.cos(end * deg)) - x1;
var y2 = Math.floor(ry * Math.sin(end * deg)) - y1;
var la = (end-start)>180 ? "1" : "0";
dtpl = dtpl
.replace("{X1}", x1).replace("{Y1}", y1)
.replace("{X2}", x2).replace("{Y2}", y2)
.replace("{LA}", la)
.replace("{RX}", rx).replace("{RY}", ry);
rsvg.append("path").attr({
"d": dtpl,
"style": "stroke:#ffffff; stroke-width:2; fill: #000077"
});
立體扇形製圖技巧
除了扇形本身以外,需要畫些立體面,製圖邏輯如下:
| 立體元素 | 可見範圍 | 先後次序 |
|---|---|---|
| 起點矩形 | 90 < 起點角 < 270 | 1 |
| 終點矩形 | -90 < 終點角 < 90 | 1 |
| 曲面 | 0 < 起點角 < 180 or 0 < 終點角 < 180 | 2 |
畫圓餅圖時,多個立體扇形間需要輻射性拆散,圓心要稍作修正: TODO
注意事項
- 設定優先權 CSS Attribute > Tag Attribute
- <g> 無法繼承 x, y, cx, cy, r, x1, x2, y1, y2 等屬性
- SVG Animation 有部分瀏覽器不支援
- 目前主流的瀏覽器支援到 SVG 1.1
- Firefox 透過 d3 觸發 mousemove 事件時,子圖的座標不是相對座標
- 外部 SVG 有五種載入方式,其中 <embed> 與 <object> 比較理想 Embedding SVG Examples