svg : pattern 标签(一)
<style>.ma p, .ma pre, .ma svg { margin: 8px 0; }
.rred { color: red; }
.ma > pre { padding: 16px; background: #efefef; font: normal 16px monospace; white-space: pre-wrap; word-wrap: break-word; tab-size: 4; line-height:1.5em; }
.ma > svg { border: 1px solid gray; }
</style>
<div class="ma">
<p>pattern是一种填充类型的svg标签,它包裹在 <defs>...</defs> 标签之内,其内可以组织包括path路径在内的所有svg图形元素,并将这些图形以 fill 或 stroke 方式填充使用对象或给该对象描边。代码结构和运行效果举例如下:</p>
<pre><svg width="200" height="200" style="border: 1px solid;">
<defs>
<pattern id="tri" x="0" y="0" width="20%" height="20%">
<polygon points="20,5 5,30 40,20 20,5" fill="steelblue" />
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#tri)" />
</svg></pre>
<svg width="200" height="200" style="border: 1px solid;">
<defs>
<pattern id="tri" x="0" y="0" width="20%" height="20%">
<polygon points="20,5 5,30 40,20 20,5" fill="steelblue" />
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#tri)" />
</svg>
<p>上面的代码,我们首先创建一个 pattern 元素,它需要放在 <defs>...</defs> 标签的省略号处。pattern 标签拥有 id 标识符,x 和 y 属性定义 pattern 取其内图形的XY坐标位置,width 和 height 属性定义取图形的宽高,注意,<span class="rred">默认情况下 width 和 height 属性使用百分比做单位</span>,不然无效。然后我们使用 polygon 多边形标签绘制一个不规则三角形(如果愿意,我们可以绘制组合式图形)。这样,pattern 图案就准备就绪,可以拿去填充其他图形或给其他图形描边了。</p>
<p>pattern的本意是图案,pattern 标签就是设置一个或一组图案,然后以平铺方式拿去给其他图形做图案,这和贴瓷砖、贴窗花差不多是一个道理。从上面效果看,我们应可以感受到 pattern 的宽高和贴图对象(circle)的宽高尺寸的关系:pattern 定义的图案宽高都是20%,这意味着在贴图对象的纵横两个方向都能贴 5 个pattern内定义的图案;本例我们使用的贴图对象是一个圆,有一些三角形被剪切在圆的外面了,定可以数一数横向和纵向直径的三角形个数以证实上面的说法。</p>
<p>作为首次接触,pattern 标签先说这些,后续还有一些问题需要探讨,敬请期待。最后给出一个有趣的pattern动画,它是在上面示例的基础上略作改动完成的:</p>
</div>
<svg width="200" height="200">
<defs>
<pattern id="mypatt" x="0" y="0" width="10%" height="10%" viewBox="0 0 40 40">
<polygon points="20,5 5,25 30,20 20,5" fill="steelblue" />
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#mypatt)" />
</svg>
<br><br>
<p style="margin-left: 60px;"><input type="button" id="btnplay" value="开始动画" /></p>
<script>
let step = 0.01, base = 10, playId = false, aniId = null;
let whChg = () => {
base += step;
if(base > 20 || base < 4) step = -step;
mypatt.setAttribute('width', base + '%');
mypatt.setAttribute('height', base + '%');
aniId = requestAnimationFrame(whChg);
};
btnplay.onclick = () => {
playId === false ? aniId = (requestAnimationFrame(whChg), playId = true) : (cancelAnimationFrame(aniId), playId = false);
btnplay.value = playId ? '结束动画' : '开始动画';
};
</script>
width 和 height 属性的取值是有限制的吧,对于上面例子,我取到100%就没了,取50%和70%得到的也完全不同。
这个应该是跟polygon配套着用的吧。{:4_203:} 觉得这个很好看也很好玩,但触摸不到它的底线,我用polygon points="50,150 100,50 150,150 50,150"画个正三角,用宽度20%时就看不到了{:4_173:} 红影 发表于 2023-11-1 14:14
width 和 height 属性的取值是有限制的吧,对于上面例子,我取到100%就没了,取50%和70%得到的也完全不同。 ...
我为什么花那么多的精力介绍 viewBox ?这是svg的精髓。当然,在 pattern 还没有使用 viewBox 之前,我们要弄清楚的是pattern的宽高百分比、填充目标的尺寸和pattern内部图案的关系。
pattern内部的图案,默认时,它的尺寸很重要。比方说,单个图案,设置为宽高40*40,则,pattern的宽、高百分比百分比和填充的目标图形的宽、高尺寸的比例,要能保证 40*40 的图案能正常显示,否则就会出现被剪切的区域,例如,填充的目标图形尺寸是 200*200,则 20% 是合适的,40%也是合适的。
但是这一切问题,pattern 引入 viewBox 之后,都将不复存在,因为 viewBox 能让 pattern 内的图案伸缩。 红影 发表于 2023-11-1 14:18
觉得这个很好看也很好玩,但触摸不到它的底线,我用polygon points="50,150 100,50 150,150 50,150"画个正 ...
你可以单独画一个 polygon 看看效果,它很大的 马黑黑 发表于 2023-11-1 19:29
我为什么花那么多的精力介绍 viewBox ?这是svg的精髓。当然,在 pattern 还没有使用 viewBox 之前,我们 ...
哦,在没使用 viewBox 时,这些宽高比有限制,使用了,这些限制就能呗解决了吧。知道了{:4_187:} 马黑黑 发表于 2023-11-1 19:31
你可以单独画一个 polygon 看看效果,它很大的
是的,这个特地弄个大的,感受一下比较大的时候能否被填充。 红影 发表于 2023-11-1 22:42
是的,这个特地弄个大的,感受一下比较大的时候能否被填充。
pattern 的 width 和 height 规定平铺的个体大小,原始设计的边界太大了就会被剪裁,所以需要引入 viewBox 属性,令其可以伸缩时保持形状不变或不变形 马黑黑 发表于 2023-11-2 07:28
pattern 的 width 和 height 规定平铺的个体大小,原始设计的边界太大了就会被剪裁,所以需要引入 viewBo ...
嗯,看到今天的那个介绍,知道了,引入 viewBox 属性的设置也要恰当。 红影 发表于 2023-11-2 10:18
嗯,看到今天的那个介绍,知道了,引入 viewBox 属性的设置也要恰当。
一切属性、参数的设置,都是根据需要来 马黑黑 发表于 2023-11-2 11:57
一切属性、参数的设置,都是根据需要来
设置的时候必须符合实际,否则可能看不到东西。 红影 发表于 2023-11-2 14:07
设置的时候必须符合实际,否则可能看不到东西。
设计师不会在实现自己的设计时让一切都看不到 马黑黑 发表于 2023-11-2 19:59
设计师不会在实现自己的设计时让一切都看不到
设计师不会,只是在自己设置不合适时会。 红影 发表于 2023-11-2 21:38
设计师不会,只是在自己设置不合适时会。
不合适就改改 马黑黑 发表于 2023-11-2 21:47
不合适就改改
是的,这个是必须的。 红影 发表于 2023-11-2 22:22
是的,这个是必须的。
好 马黑黑 发表于 2023-11-2 23:12
好
等遇到不合适时再说{:4_173:} 红影 发表于 2023-11-3 12:53
等遇到不合适时再说
也好 马黑黑 发表于 2023-11-3 21:36
也好
还需要发现不合适才行,发现不了也改不了{:4_173:} 红影 发表于 2023-11-3 23:04
还需要发现不合适才行,发现不了也改不了
那就别改