SVG蒙版的使用

起因

最近做需求时发现有个这样的UI图

SVG蒙版的使用

第一眼看到这图时脑子就像着用着几个div加border-radio来实现,仔细一看发现这个图形整体的背景色是带渐变的,那就不能用几个元素去拼凑了,这只能用于单一背景色的图形。

整体带渐变背景色就需要用一个元素去画出这个图形,但是这太麻烦了,还有一种方法就是使用蒙版。前端中蒙版有CSS蒙版,SVG蒙版,Canvas蒙版。CSS蒙版需要引入图片,如果要引入图片那还不如直接叫UI把这每个进度的图给我算了,Canvas又觉得小题大做,所以这里使用SVG蒙版。

代码实现

首先画出蒙版图形
<defs>标签用于自定义形状,它内部的代码不会显示,仅供引用。rx,ry为矩形圆角边框。
<mask>标签为遮罩元素,可将SVG元素当做蒙版显示,白色为全透明,黑色为不透明。

<defs>
    <mask id="small-rect">
        <rect x="0" y="30" height="3" width="240" rx="2" ry="2" style="stroke: #70d5dd;"                 
        fill="white" />
        <circle cx="30"  cy="30" r="6" fill="white"/>
        <circle cx="60"  cy="30" r="6" fill="white"/>
        <circle cx="90"  cy="30" r="6" fill="white"/>
        <circle cx="120"  cy="30" r="6" fill="white"/>
        <circle cx="150"  cy="30" r="6" fill="white"/>
        <circle cx="180"  cy="30" r="6" fill="white"/>
    </mask>
</defs>

再定义下渐变色

<defs>
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
        <stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
        <stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
    </linearGradient>
</defs>

再画个矩形,并引入蒙版

<rect id="front" x="0" y="0" width="200" height="50" fill="url(#grad1)" mask="url(#small-rect)"></rect>

注意该元素的位置要在蒙版元素位置内才能看到效果

效果完成
SVG蒙版的使用

大体上差不多了,在进度显示上只要控制蒙版矩形的宽和圆的个数就可以了。

SVG还有组的概念,试了下在组上加入渐变,结果不行。
<g>标签用于将多个形状组成一个组(group)。

<g fill="url(#grad1)">
    <rect x="0" y="50" height="3" width="240" rx="2" ry="2" style="stroke: #70d5dd;" />
    <circle cx="30"  cy="50" r="6"/>
    <circle cx="60"  cy="50" r="6"/>
</g>

然而不行,相当于在每个元素上加了个渐变。
SVG蒙版的使用