目錄
什麼是SVG?
- SVG 指可伸縮矢量圖形 (Scalable Vector Graphics)
- SVG 用來定義用於網絡的基於矢量的圖形
- SVG 使用 XML 格式定義圖形
- SVG 圖像在放大或改變尺寸的情況下其圖形質量不會有所損失
- SVG 是萬維網聯盟的標準
- SVG 與諸如 DOM 和 XSL 之類的 W3C 標準是一個整體
viewport和viewBox
學好svg需要先了解svg中的viewport和viewBox這兩個概念。
- viewpart是整個svg的可見區域即svg標籤的寬高。
- viewBox是svg在繪圖過程中使用的座標系,viewBox存在於viewPort中。可以通過viewBox屬性設置viewBox的大小和在viewPort中的相對位置。如:下面的標籤表是svg畫布的大小爲200px*200px,view Box位於viewpart座標中的(0, 0)位置並且大小爲100*100。
<svg width='200px' height='200px' viewBox='0 0 100 100'></svg>
preserveAspectRatio
svg除了viewport和viewBox外還有一個比較重要的參數preserveAspectRatio主要是用在viewport和viewBox寬高比不一致的情況,寬高比會影響svg的渲染。
默認情況下preserveAspectRatio="xMidYMid meet"表示viewBox位於viewport的中心位置,並且採用viewport和viewBox最小的寬高比。
Mid,Min,Max
對於x軸Mid表示viewBox位於viewport橫向位置的中間,Min表示位於viewport的最左邊,Max表示位於viewport的最右邊
對於y軸Mid表示viewBox位於viewport橫向位置的中間,Min表示位於viewport的最上邊,Max表示位於viewport的最下邊
meet,slice
meet代表選擇viewport和viewBox寬高比例較小的一個圖形可以按照比例縮小顯示。
slice代表選擇viewport和viewBox寬高比例較大的一個這可能會造成svg圖形過大最終超出viewport圖形被裁切。
demo案例
在瞭解完preserveAspectRatio和viewBox、viewport後基本上對svg的佈局就可以大致理解svg的佈局原理了,下面是幾個demo
svg.vue
<template>
<div>
<svg
width="100"
height="100"
style="display: none"
viewBox="0 0 100 100"
preserveAspectRatio="xMidYMid meet"
>
<defs>
<g id='more'>
<line x1='40' y1='25' x2='90' y2='25' stroke-width='8' stroke='currentColor'></line>
<line x1='40' y1='50' x2='80' y2='50' stroke-width='8' stroke='currentColor'></line>
<line x1='40' y1='75' x2='90' y2='75' stroke-width='8' stroke='currentColor'></line>
<circle r='5' cx='20' cy='25' fill='currentColor'></circle>
<circle r='5' cx='20' cy='50' fill='currentColor'></circle>
<circle r='5' cx='20' cy='75' fill='currentColor'></circle>
</g>
<symbol id='more1' viewBox='0 0 100 100'>
<line x1='40' y1='25' x2='90' y2='25' stroke-width='8' stroke='currentColor'></line>
<line x1='40' y1='50' x2='80' y2='50' stroke-width='8' stroke='currentColor'></line>
<line x1='40' y1='75' x2='90' y2='75' stroke-width='8' stroke='currentColor'></line>
<circle r='5' cx='20' cy='25' fill='currentColor'></circle>
<circle r='5' cx='20' cy='50' fill='currentColor'></circle>
<circle r='5' cx='20' cy='75' fill='currentColor'></circle>
</symbol>
<symbol id='filledArrowRight' viewBox='0 0 100 100'>
<polyline points='20 10, 80 50, 20 90' fill='currentColor'></polyline>
</symbol>
<symbol id='arrowRight' viewBox='0 0 100 100'>
<polyline points='20 10, 60 50, 20 90' fill='transparent' stroke-width='8' stroke='currentColor'></polyline>
</symbol>
</defs>
</svg>
<span :style="{color: 'green'}">
<svg width='100' height='100' viewBox='0 0 100 100'>
<use href='#more'></use>
</svg>
<Icon :style="{width: 100, height: 100, color: 'red'}" :svgId="'more1'" />
<Icon :style="{width: 100, height: 100, color: 'blue'}" :svgId="'arrowRight'" />
<Icon :style="{width: 100, height: 100, color: 'yellow'}" :svgId="'filledArrowRight'" />
</span>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import Icon from '@src/components/icon.vue'
export default defineComponent({
name: "SVG",
components: {
Icon
},
setup: () => {
return {};
},
});
</script>
<style scoped>
</style>
icon.vue
<template>
<svg :style="style">
<use :href="`#${svgId}`"></use>
</svg>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "icon",
props: {
svgId: {
type: String,
required: true,
},
style: {
type: CSSStyleDeclaration, // CSSStyleDeclaration
require: false
}
}
});
</script>
demo中用到了幾個比較常用的svg基本圖形
line線
rect矩形
circle圓型
defs可以將寫好的svg組件隱藏起來
g可以設置id屬性即這是一個svg組合
symbol和g類似但是可以傳遞viewBox屬性這樣在使用的時候就不用再寫viewbox去適應圖標(實現的原理就是在套一層svg標籤)
use可以使用定義好的svg組合(通過href='#id'使用)
polyline多邊形
幾個值的注意的地方
1.對線來說填充顏色不能用fill來填充需要用stroke來填充顏色,並且如果將顏色設置成currentColor即爲繼承父元素的顏色(css中的color屬性)
2.當我們自己想要寫svg樣式庫的時候可以使用defs將svg庫隱藏起來但是這裏仍然會佔用文檔流的位置,可以將display:none將其隱藏掉
3.封裝svg圖形的時候儘量使用symbol代替g(這也是iconfont建議的),因爲爲了在使用編輯好的svg圖標時g標籤還要額外去寫viewBox去適應圖標的縮放大小而symbol可以直接設置viewBox,這樣我們使用封裝好的svg組合時就可以直接通過組合的id使用圖標並且保證圖標的正常顯示。
4.viewport是可以繼承父元素的寬高的只要將svg標籤的width和height設置成100%即可