马黑黑 发表于 2023-11-2 08:33

svg : pattern 标签(二)

本帖最后由 马黑黑 于 2023-11-2 08:40 编辑 <br /><br /><style>
.ma p, .ma pre { 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; }
</style>

<div class="ma">

<p>上一讲的pattern动画演示,pattern图案放大或缩小时,只要图案个体完整在目标区域,三角形都保持原本的形状。这得益于 viewBox 属性在pattern中的应用。viewBox 属性的宽高应是pattern图案边界宽高尺寸的(正整数)倍数,比如我们下面的图案,它是一个 40*40 的矩形(rect)和充当矩形对角线的两根直线(line)组成:</p>
<pre>
&lt;rect x="0" y="0" width="40" height="40" fill="none" stroke="navy" /&gt;
&lt;line x1="0" y1="0" x2="40" y2="40" stroke="purple" /&gt;
&lt;line x1="40" y1="0" x2="0" y2="40" stroke="purple" /&gt;
</pre>
<p>
      <svg width="40" height="40">
                <rect x="0" y="0" width="40" height="40" fill="none" stroke="navy" />
                <line x1="0" y1="0" x2="40" y2="40" stroke="purple" />
                <line x1="40" y1="0" x2="0" y2="40" stroke="purple" />
      </svg>
</p>
<p>现在,我们的预期是,用上面这样的图案去填充另一个 200*200 的矩形,且放大缩小图案时保持图案形状不改变。如此,我们需要将上面的图案组合放入pattern标签内,给pattern一个id,然后通过该id填充大矩形。pattern的 viewBox属性,min-x、min-y 为 0,width、height 为 40(即考虑pattern图案的rect和line得出的边界尺寸 40,这里 viewBox 的宽高用了 40 的一倍):</p>
<pre>
&lt;defs&gt;
       &lt;pattern id="pat1" width="20%" height="20%" viewBox="0 0 40 40"&gt;
                &lt;rect x="0" y="0" width="40" height="40" fill="none" stroke="navy" /&gt;
                &lt;line x1="0" y1="0" x2="40" y2="40" stroke="purple" /&gt;
                &lt;line x1="40" y1="0" x2="0" y2="40" stroke="purple" /&gt;
        &lt;/pattern&gt;
&lt;/defs&gt;

&lt;rect x="0" y="0" width="200" height="200" fill="url(#pat1)" /&gt;
</pre>
<p>上面的代码,pattern的宽高属性决定的是pattern图案在 200*200 大矩形中的个体比例,20% 也可以表示为 0.2,表示每一个 pattern 图案在去平铺大矩形时的尺寸是大矩形宽高各 20%,即纵横方向都放下 5 个pattern图案。效果如下:</p>
<p>
      <svg width="200" height="200" style="border: 1px solid tan;">
                <defs>
                        <pattern id="pat1" width="20%" height="20%" viewBox="0 0 40 40">
                              <rect x="0" y="0" width="40" height="40" fill="none" stroke="navy" />
                              <line x1="0" y1="0" x2="40" y2="40" stroke="purple" />
                              <line x1="40" y1="0" x2="0" y2="40" stroke="purple" />
                        </pattern>
                </defs>

                <rect x="0" y="0" width="200" height="200" fill="url(#pat1)" />
      </svg>
</p>
<p>上面的效果,图案正好是满当当的,这是因为 pattern 的尺寸在上面代码规范下,平铺大矩形的每一个图案正好是 40*40 的尺寸。这种情形我们不要 viewBox 属性也是可以的,但图案一旦放大或缩小,没有 viewBox 属性的约束,pattern图案个体可能会因为被剪裁而变形。</p>
<p>下面,提供两个案例,第一个带有 viewBox 属性,第二个没有,开始时它们一模一样,调整 pattern 的 width 和 height 百分比,看看情况如何:</p>
<p style="display: flex; gap: 60px;">
      <svg width="200" height="200">
                <defs>
                        <pattern id="pat2" width="0.2" height="0.2" viewBox="0 0 40 40">
                              <rect x="0" y="0" width="40" height="40" fill="none" stroke="navy" />
                              <line x1="0" y1="0" x2="40" y2="40" stroke="purple" />
                              <line x1="40" y1="0" x2="0" y2="40" stroke="purple" />
                        </pattern>
                </defs>
                <rect x="0" y="0" width="200" height="200" fill="url(#pat2)" />
      </svg>

      <svg width="200" height="200">
                <defs>
                        <pattern id="pat3" width="0.2" height="0.2">
                              <rect x="0" y="0" width="40" height="40" fill="none" stroke="navy" />
                              <line x1="0" y1="0" x2="40" y2="40" stroke="purple" />
                              <line x1="40" y1="0" x2="0" y2="40" stroke="purple" />
                        </pattern>
                </defs>
                <rect x="0" y="0" width="200" height="200" fill="url(#pat3)" />
      </svg>
</p>
<p style="display: flex; align-items: center; gap: 10px;">
      <label for="wh">调整pattern宽高:</label>
      <input id="wh" type="range" min="0" max="1" step="0.1" value="0.2" />
      <output id="opMsg">0.2</output>
</p>

</div>

<script>

wh.oninput = () => {
      opMsg.innerText = wh.value;
      pat2.setAttribute('width',wh.value);
      pat2.setAttribute('height',wh.value);
      pat3.setAttribute('width',wh.value);
      pat3.setAttribute('height',wh.value);
};

</script>

红影 发表于 2023-11-2 09:10

忍不住又回头去看了看前面一个帖子里的三角形,原来那个动画里也有viewBox,怪不得能一直充满{:4_173:}

红影 发表于 2023-11-2 09:17

“没有 viewBox 属性的约束,pattern图案个体可能会因为被剪裁而变形。”
没有 viewBox 时,当pattern宽高取得小,会被剪裁,但仍充满。取得大会由空档充满。
有 viewBox 时,无论pattern宽高怎么取,都会有不同比例的完整图去充满。

红影 发表于 2023-11-2 09:20

要保留图案,必须得有 viewBox啊。当然 viewBox的取值也有讲究,当取值小于一倍也会被切,大于一倍也出现空档。

马黑黑 发表于 2023-11-2 12:03

红影 发表于 2023-11-2 09:20
要保留图案,必须得有 viewBox啊。当然 viewBox的取值也有讲究,当取值小于一倍也会被切,大于一倍也出现空 ...

一切需要配套

马黑黑 发表于 2023-11-2 12:05

红影 发表于 2023-11-2 09:10
忍不住又回头去看了看前面一个帖子里的三角形,原来那个动画里也有viewBox,怪不得能一直充满

是的

红影 发表于 2023-11-2 14:30

马黑黑 发表于 2023-11-2 12:03
一切需要配套

嗯嗯,设置的数值都会产生影响。

红影 发表于 2023-11-2 14:32

马黑黑 发表于 2023-11-2 12:05
是的

前面弄错了,没想到那个动态里有viewBox。还好看完这个帖子才知道了。{:4_173:}

马黑黑 发表于 2023-11-2 19:48

红影 发表于 2023-11-2 14:32
前面弄错了,没想到那个动态里有viewBox。还好看完这个帖子才知道了。

对知识的理解,可能是循序渐进的

马黑黑 发表于 2023-11-2 19:49

红影 发表于 2023-11-2 14:30
嗯嗯,设置的数值都会产生影响。

所以配套是很重要的

小辣椒 发表于 2023-11-2 19:53

这个好像有点难度,小辣椒纯飘过

马黑黑 发表于 2023-11-2 19:54

小辣椒 发表于 2023-11-2 19:53
这个好像有点难度,小辣椒纯飘过

有难度是因为没有入门

小辣椒 发表于 2023-11-2 19:55

马黑黑 发表于 2023-11-2 19:54
有难度是因为没有入门

是的,感觉脑子里面一点没有感念

马黑黑 发表于 2023-11-2 19:57

小辣椒 发表于 2023-11-2 19:55
是的,感觉脑子里面一点没有感念

对,就是酱紫。svg与HTML其实是相同性质的东东,但各有所长,svg以文本代码的形式组织矢量图形,可以独立使用,也可以用于HTML

红影 发表于 2023-11-2 21:10

马黑黑 发表于 2023-11-2 19:48
对知识的理解,可能是循序渐进的

是啊,好像好几次了,看了后面的课程,才理解了前面的呢。

红影 发表于 2023-11-2 21:11

马黑黑 发表于 2023-11-2 19:49
所以配套是很重要的

这个需要配套设置,所以还是有些难度的呢。

马黑黑 发表于 2023-11-2 21:29

红影 发表于 2023-11-2 21:11
这个需要配套设置,所以还是有些难度的呢。

所有的东西都需要配套,包括简单到服装设计

马黑黑 发表于 2023-11-2 21:29

红影 发表于 2023-11-2 21:10
是啊,好像好几次了,看了后面的课程,才理解了前面的呢。

这很正常

红影 发表于 2023-11-2 22:13

马黑黑 发表于 2023-11-2 21:29
所有的东西都需要配套,包括简单到服装设计

有些只要一个设置就完了,这个是要配套设置的。

红影 发表于 2023-11-2 22:13

马黑黑 发表于 2023-11-2 21:29
这很正常

说明理解得太慢了{:4_173:}
页: [1] 2 3 4 5 6
查看完整版本: svg : pattern 标签(二)