上次介绍了基础图形的绘製,这次介绍一些其他的元素
群组
<g>
是 Group 的意思,其子元素会继承该元素的属性,常用在 transform
<svg width="250" height="250"> <g transform="scale(2, 1.3)"> <rect x="5" y="5" rx="10" ry="10" width="70" height="70" /> <rect x="100" y="5" rx="10" ry="10" width="70" height="70" /> </g></svg>
定义
<defs>
是 definitions 的意思,定义在里面的元素不会在画面上,可以使用 <use>
将其绘製出来,这个标籤让我们可以重複使用里面的元素,使用方法需先在 <defs>
内定义元素,并赋予 id,然后在外侧使用 <use>
,并写入属性 xlink:href="#id"
<svg width="250" height="250"> <defs> <circle id="circle" cx="0" cy="0" r="50" /> </defs> <use x="50" y="50" xlink:href="#circle" /></svg>
渐层
渐层的写法须在 <defs>
内宣告后,再将其使用于外面的元素
<svg width="250" height="250"> <defs> <linearGradient id="linearGradient"> <stop offset="0%" stop-color="red" stop-opacity="1" /> <stop offset="50%" stop-color="yellow" stop-opacity="1" /> <stop offset="100%" stop-color="green" stop-opacity="1" /> </linearGradient> </defs> <rect rx="10" ry="10" width="100" height="100" fill="url(#linearGradient)" /></svg>
首先在 <defs>
内宣告,渐层属性需要加上 id
才可使用,内层使用 stop
操控颜色,最后在图形上以 url(#id)
来调用渐层,这边的 stop
有三个属性可以设定
offset
: 範围为 0% ~ 100% 或是 0 ~ 1,两者皆可stop-color
: 渐层颜色,这边一样可使用 rgba
stop-opacity
: 颜色透明度线性渐层
定义线性渐层使用 linearGradient
,线性渐层方向由两个点控制,範围为 0% ~ 100% 或是 0 ~ 1,两者皆可,预设是由左至右的渐层
x1
: 第一点的 X 位置,预设值为 0y1
: 第一点的 Y 位置,预设值为 0x2
: 第二点的 X 位置,预设值为 1y2
: 第二点的 Y 位置,预设值为 0<svg width="250" height="250"> <defs> <linearGradient id="linearGradient" x1="0" y1="0" x2="0" y2="1"> <stop offset="0%" stop-color="red" /> <stop offset="50%" stop-color="yellow" /> <stop offset="100%" stop-color="green" /> </linearGradient> </defs> <rect rx="10" ry="10" width="300" height="100" fill="url(#linearGradient)" /></svg>
放射性渐层
定义线性渐层使用 radialGradient
,放射性渐层位置与大小由一个点及半径控制,範围为 0% ~ 100% 或是 0 ~ 1,两者皆可
cx
: 渐层範围圆心的 X 位置,预设值为 0.5cy
: 渐层範围圆心的 Y 位置,预设值为 0.5r
: 半径大小,预设值为 0.5fx
: 焦点的 X 位置,预设与 cx 的值一样fy
: 焦点的 Y 位置,预设与 cy 的值一样spreadMethod
: 剩余空间的处理方式pad
: 以最外层的颜色填满repeat
: 重複渐层reflect
: 这个也是重複渐层,但是他会从 0% → 100% → 0%,感觉较滑顺<svg width="250" height="250"> <defs> <radialGradient id="radialGradient" cx="0.7" cy="0.7" r="0.7" fx="0.4" fy="0.4" spreadMethod="pad"> <stop offset="0%" stop-color="red" stop-opacity="1" /> <stop offset="50%" stop-color="yellow" stop-opacity="1" /> <stop offset="100%" stop-color="green" stop-opacity="1" /> </radialGradient> </defs> <rect rx="10" ry="10" width="300" height="100" fill="url(#radialGradient)" /></svg>
渐层单位系统
gradientUnits
这个属性是一个单位系统,部分标籤可使用此属性,主要是切换相对单位与绝对单位
objectBoundingBox
: 相对单位,範围为 0% ~ 100% 或是 0 ~ 1,此为预设值userSpaceOnUse
: 绝对单位,需先知道对象位置// 假设宽高皆为 100px,以下两种方法结果相同<linearGradient id="gradient" x1="0" y1="0" x2="0" y2="1"><linearGradient id="gradient" x1="0" y1="0" x2="0" y2="100" gradientUnits="userSpaceOnUse">
样式
<pattern>
一样须在 <defs>
内宣告后,再将其使用于外面的元素
<svg width="250" height="250"> <defs> <pattern id="pattern" width=".25" height=".25" patternContentUnits="objectBoundingBox"> <rect x="0" y="0" width=".25" height=".25" fill="red" /> <rect x="0" y=".1" width=".25" height=".05" fill="black" /> <rect x=".1" y="0" width=".05" height=".25" fill="black" /> </pattern> </defs> <rect fill="url(#pattern)" width="250" height="250" /></svg>
使用方法一样是在 <defs>
宣告后,在外层以 url(#id)
使用
样式单位系统
同 gradientUnits
一样,在样式内也有 patternContentUnits
可调整单位,需要特别注意的是它的预设值为userSpaceOnUse
,与渐层相反
文字
文字使用 <text>
包裹起来,且内侧可使用 tspan
来建立子元素,属性写法类似于 css
,可参考 MDN
x
: 文字 X 轴的绝对座标y
: 文字 Y 轴的绝对座标dx
: 每个文字距离左侧的距离,可用逗号区隔带入每个文字的距离dy
: 每个文字距离上方的距离,可用逗号区隔带入每个文字的距离text-anchor
: 设定 X 轴方向对齐方式,有 start
、middle
与 end
三种dominant-baseline
: 设定 Y 轴方向对齐方式,有 baseline
、middle
与 hanging
三种rotate
: 旋转文字textLength
: 文字的宽度,每个字的间距会自动分配,只有在绝对座标下才有作用<svg width="250" height="250"> <text x="150" y="20" textLength="300" text-anchor="middle" dominant-baseline="middle" style="fill:red;stroke:blue;font-size:30px;"> Hello <tspan font-weight="bold" fill="yellow" rotate="10">my</tspan> World! </text></svg>
路径文字
将路径定义在 <defs>
以便重複使用,之后在 <text>
内侧创建 <textPath>
,使用 xlink:href="#id"
导入路径,如此一来文字便可顺着路径显示出来
<svg width="250" height="250"> <defs> <path id="path" d="M20 30 Q40 5,60 30 T90 60 L200 80" /> </defs> <text> <textPath xlink:href="#path" style="font-size:25px"> Hello World! </textPath> </text></svg>
transform
基本上用法同 css
的 transform,可参考MDN,建议先将物件群组起来再使用 transform,以确定效果一次套用到所有物件上
裁切
在 <defs>
中宣告 <clipPath>
,并在图形中使用 clip-path="url(#id)"
引用,宣告的範围会保留,其余部份则会被移除
<svg width="250" height="250"> <defs> <clipPath id="cut"> <rect x="0" y="0" width="250" height="125" /> </clipPath> </defs> <circle cx="125" cy="125" r="125" clip-path="url(#cut)" /></svg>
遮蔽
在 <defs>
中宣告 <mask>
,并一样在图形使用 mask="url(#id)"
引用,其概念同遮色片,所有颜色都会被转为灰阶,而越接近白色则越不透明,越接近黑色则越透明
<svg width="250" height="250"> <defs> <linearGradient id="gradient"> <stop offset="0" stop-color="black" /> <stop offset="1" stop-color="white" /> </linearGradient> <mask id="mask"> <rect x="0" y="0" width="250" height="250" fill="url(#gradient)" /> </mask> </defs> <rect x="0" y="0" width="250" height="250" fill="blue" mask="url(#mask)" /></svg>
图片
在 SVG 内亦可使用 <image>
插入图片, 图片放在 xlink:href
内
x
: 图片距离左侧的距离,预设值为 0y
: 图片距离上方的距离,预设值为 0width
: 图片宽度height
: 图片高度<svg width="250" height="250"> <image x="0" y="0" width="250" height="250" xlink:href="https://source.unsplash.com/random/250x250"/></svg>
另外还可使用 filter
特效,这边就不介绍了,有兴趣可以看这里