SVG是一种基于 XML 的图像文件格式,它的英文全称为Scalable Vector Graphics,意思为可缩放的矢量图形。
svg 绘图的流程
- 编写 svg 标签,指定宽高
- 编写 svg 绘图标签
- 编写绘图属性和样式
<svg width="800" height="800">
<rect
width="50"
height="50"
style="fill: red; stroke-width: 1px; stroke: yellow"
/>
<line
x1="100"
y1="100"
x2="250"
y2="75"
style="stroke: blue; stroke-width: 1"
/>
<circle
cx="200"
cy="200"
r="50"
stroke="green"
stroke-width="2"
fill="red"
/>
</svg>
viewport和viewBox
- viewport 是 svg 图像的可见区域,即宽高
- viewBox 是用于在画布上绘制 svg 图形的坐标系统
<svg
width="500"
height="200"
viewBox="0 0 50 20"
style="border: 1px solid #000000"
>
<rect
x="20"
y="10"
width="10"
height="5"
style="stroke: #000000; fill: none"
/>
</svg>
svg可见区域的是width=500px height=200px。如果rect的x=600,超过了宽度500,怎么办呢?这就需要一个坐标系统viewBox来决定。那就是viewBox="0 0 50 20"。这个可以理解为宽50个单位,高20个单位,一个单位是500/50 = 10px,用来均分500px的宽度。
从上面的代码可以知道viewBox 坐标系中 1 = 10px,上述代码相当于:
<svg width="500" height="200" style="border: 1px solid #000000">
<rect x="200" y="100" width="100" height="50" stroke-width="10" style="stroke: #000000; fill:none;"/>
</svg>
svg 组件
SVG 允许我们定义以后需要重复使用的图形元素。
defs标签
可以把所有需要再次使用的引用元素定义在defs元素里面。这样做可以增加SVG内容的易读性和可访问性。在defs元素中定义的图形元素不会直接呈现。 你可以在你的视口的任意地方利用 元素呈现这些元素。
g标签
元素g是用来组合对象容器,添加到g元素上的变换会应用到其所有的子元素上。
symbol
symbol与g标签类似,但symbol可以拥有一个独立的viewBox
// 继承父级的宽高
<svg width="0" height="0">
<defs>
<g id="arrow">
<polyline
points="30 20, 70 50, 30 80"
fill="transparent"
stroke="currentColor"
stroke-width="3"
></polyline>
</g>
<symbol id="more" viewBox="0 0 100 100">
<circle r="5" cx="20" cy="25" fill="currentColor" />
<circle r="5" cx="20" cy="50" fill="currentColor" />
<circle r="5" cx="20" cy="75" fill="currentColor" />
<line
x1="40"
y1="25"
x2="90"
y2="25"
stroke="currentColor"
stroke-width="8"
/>
<line
x1="40"
y1="50"
x2="90"
y2="50"
stroke="currentColor"
stroke-width="8"
/>
<line
x1="40"
y1="75"
x2="90"
y2="75"
stroke="currentColor"
stroke-width="8"
/>
</symbol>
<symbol id="filledArrowRight" viewBox="0 0 100 100">
<polyline fill="currentColor" points="20 10, 80 50, 20 90"></polyline>
</symbol>
<symbol id="arrowRight" viewBox="0 0 100 100">
<polyline
points="20 10, 80 50, 20 90"
stroke-width="3"
stroke="currentColor"
fill="transparent"
></polyline>
</symbol>
</defs>
</svg>
.icon {
width: 300px;
height: 300px;
}
<svg class="icon">
<use href="#arrow"></use>
</svg>
<svg class="icon">
<use href="#more"></use>
</svg>
<svg class="icon">
<use href="#filledArrowRight"></use>
</svg>
<svg class="icon">
<use href="#arrowRight"></use>
</svg>
当我改变.icon的宽高的时候,使用symbol标签的会根据父级的宽高的变化而变大变小,这是因为symbol可以设置viewBox,但是使用g标签的不会,那么如何设置才能使g标签页能随父级宽高变化而变化呢?只需要在使用的时候加上viewBox="0 0 100 100"即可。
<svg class="icon" viewBox="0 0 100 100">
<use href="#arrow"></use>
</svg>