SVG:使用symbol封装现成路径
<style>.artBox { font: normal 18px/1.5 sans-serif; overflow: auto; position: relative; }
.artBox p { margin: 10px 0; }
.artBox code, .artBox pre { background: #f7f4f3; padding: 2px 6px; tab-size: 4; }
.artBox pre { padding: 10px 20px; white-space: pre-wrap; word-wrap: break-word; }
.artBox pre code { padding: 0; background: none; }
.artBox blockquote { margin: 10px 20px; padding: 2px 15px; border-left: 3px solid skyblue; background: #e7e5e3; }
.showBox { margin: 20px; padding: 20px; }
svg { border: 1px solid red; }
</style>
<div class="artBox">
<p>很多时候现成的路径并不能完美适配当前的工作场景,这种情形我们需要对路径做一些必要的处理。更改路径 d 属性数据无异于重新设计路径,对之进行简单封装更经济划算。symbol 可以拥有自己的 viewBox,非常合适用于此类需求的路径封装。</p>
<p>假设我们有如下包含 path 路径的 svg 代码:</p>
<pre><code class="codeBox"><svg id="msvg" width="24" height="24">
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" fill="darkred"></path>
</svg>
</code></pre>
<p>从中我们得知 path 路径建立于宽高为 <code>24*24</code> 的画布。现在,我们想将路径应用于其它尺寸的工作场景,例如 <code>400*400</code> 外加 viewBox 设置为 <code>-200 -200 400 400</code> 的 SVG 画布。以下是实现代码:</p>
<pre><code class="codeBox"><svg width="400" height="400" viewBox="-200 -200 400 400">
<symbol id="sb1" viewBox="0 0 24 24">
<path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" fill="pink"></path>
</symbol>
<use href="#sb1" x="-200" y="-200" width="400" height="400"></use>
</svg>
</code></pre>
<p>上述实现代码的核心在于:在新的工作场景,<strong>先将路径原始的绘制范围设置为 symbol 的 viewBox 属性值,然后将原始路径置入 symbol 中,最后使用 use 实例化 symbol 图案</strong>。各主要步骤描述如下:</p>
<p><strong>其一</strong>:原始画布工作区域转 symbol viewBox 属性</p>
<p>通常,路径设计的时候都基于某一个尺寸以及视口进行,自己设计的心中有数,别人设计的需要分析一下。如果 path 路径没有额外封装,那么,凡带有 svg 标签的 path 路径,先检查 svg 标签有没有 viewBox 属性,若有,viewBox 属性就是路径的绘制视口,若没有,路径的绘制区域就是 svg 的宽高;如果 path 路径额外封装于其它标签,则观察路径直接父元素是什么,是 symbol 就将整个 symbol+path 一同移植,是别的就遵循 svg 的绘制视口或宽高尺寸去构造新场景 symbol 的 viewBox 属性。</p>
<p>有时候仅拿到了 path 路径的 d 属性值,这时候就需要更强大的分析能力,依据路径数据分析其绘制范围,并通过简单尝试校准路径的原始绘制视口。</p>
<p><strong>其二</strong>:使用 use 标签实例化 symbol 图案</p>
<p>symbol 内部包裹的路径不会自动渲染,需要使用 use 标签将其实例化后才能将图案呈现于 svg 画布中。use 标签通过 href 属性指明实例化哪一个 symbol,同时拥有一些常用属性。下面列举几个经常用到的 use 标签的属性:</p>
<blockquote>
<p>href : 实例化对象 【例】<code>href="#sb1"</code><br>x : 图案渲染的 x 坐标 【例】<code>x ="-200"</code><br>y :图案渲染的 y 坐标 【例】<code>y="-200"</code><br>width : 图案的宽度 【例】<code>width="400"</code><br>height :图案的高度 【例】<code>height="400"</code></p>
</blockquote>
<p>其中的 width 和 height 需要一个前提,即 <strong>href 所引用的对象具有 viewBox 属性设置</strong>,否则 use 的宽高设置无效(此时 use 渲染的实例效果为 symbol 或其他对象的实际内部尺寸)。</p>
<p>最后看一下前边路径例子的渲染效果:</p>
<p>(一)原始心形图案:</p>
<div class="showBox"></div>
<p>(二)封装后的心形图案:</p>
<div class="showBox"></div>
</div>
<script>
var codeBoxes = document.querySelectorAll('.codeBox');
var showBoxes = document.querySelectorAll('.showBox');
showBoxes.forEach((box,key) => {
console.log(box)
box.innerHTML = codeBoxes.innerText;
});
</script> 本帖最后由 也曾年轻 于 2026-5-8 13:22 编辑 <br /><br /><svg viewBox="0 0 400 400" style="border:none;">
<symbol id="sb2" viewBox="0 0 50 50">
<path d="m11.96269,19.10082c2.91706,5.60117 3.48654,7.30217 2.52206,7.53317c-1.88406,0.45126 -1.50545,3.03206 1.1316,7.71368c3.30714,5.87126 9.78483,9.47676 15.86937,8.83292c2.36167,-0.2499 5.03164,-0.76563 5.93327,-1.14609c0.90162,-0.38046 0.34835,0.32829 -1.22949,1.575c-7.8933,6.23672 -17.64187,5.80228 -25.41912,-1.13278c-3.10093,-2.76515 -7.36734,-10.84413 -7.36734,-13.95103c0,-0.88016 -0.70338,-1.733 -1.56307,-1.89519c-1.40592,-0.26525 -1.21711,-0.96365 1.87796,-6.94653c1.89257,-3.65841 3.67411,-6.91406 3.95898,-7.2348c0.28488,-0.32073 2.21348,2.67251 4.2858,6.65164l0,0zm25.07463,10.79837c-2.91706,-5.60117 -3.48654,-7.30217 -2.52206,-7.53317c1.88406,-0.45125 1.50545,-3.03206 -1.13159,-7.71368c-3.30715,-5.87127 -9.78483,-9.47676 -15.86937,-8.83293c-2.36167,0.2499 -5.03163,0.76564 -5.93326,1.1461c-0.90163,0.38045 -0.34836,-0.3283 1.22949,-1.575c7.8933,-6.23672 17.64188,-5.80228 25.41912,1.13278c3.10093,2.76514 7.36733,10.84413 7.36733,13.95102c0,0.88017 0.70339,1.733 1.56307,1.89519c1.40593,0.26525 1.21711,0.96365 -1.87795,6.94654c-1.89257,3.6584 -3.67411,6.91406 -3.95898,7.2348c-0.28488,0.32073 -2.21348,-2.6725 -4.2858,-6.65164l0,0z" />
</symbol>
<use href="#sb2" x="150" y="10" width="40" height="40" fill='red'></use>
<use href="#sb2" x="40" y="40" width="100" height="100" fill='blue'></use>
</svg>
很实用的知识与方法,谢谢马老师深度讲授与演示使用symbol封装SVG现成路径{:4_190:} 谢谢黑黑老师的无私奉献,学习了。 纯不懂就学习了一下,感谢黑黑分享{:4_187:} 小辣椒 发表于 2026-5-8 22:23
纯不懂就学习了一下,感谢黑黑分享
{:4_190:} 梦江南 发表于 2026-5-8 17:33
谢谢黑黑老师的无私奉献,学习了。
{:4_190:} 杨帆 发表于 2026-5-8 13:36
很实用的知识与方法,谢谢马老师深度讲授与演示使用symbol封装SVG现成路径
{:4_190:} 也曾年轻 发表于 2026-5-8 13:10
本帖最后由 也曾年轻 于 2026-5-8 13:22 编辑
{:4_191:}
页:
[1]