马黑黑 发表于 2025-8-26 12:25

JS:获取svg路径设计坐标及宽高数据

<style>
        .artBox { font-size: 18px; }
        .artBox > p { margin: 10px 0; line-height: 30px; }
        .artBox mark { padding: 4px 6px; background: lightblue; }
        .artBox h5 { font-size: 18px; margin: 6px 0; }
</style>

<div id="prevBox"></div>
<div class="artBox">
        <p>对复杂的svg路径,我们可能很难一眼瞧出它的实际占位情况,而我们总是希望路径的应用应该能适应svg的尺寸。为此,我们有必要事先获取svg路径是在什么宽高范围内进行设计,即弄懂path路径的x、y、width 和 height 的实值。JS内置的 getBBox() 函数能帮我们做到这一点,其语法非常简单:</p>
        <div class="codebox" data-title="getBBox语法">SVGElement.getBBox();</div>
        <p>任意拥有空间占位属性的svg内的元素,都可以使用 getBBox() 函数获取到类似于对象集合<mark>{x: x, y: y, width: width, height: height}</mark>的数据。通常,x、y 的值要分别考虑其右、其下的占位以寻求边界的均衡,在计算路径占位的时候 x、y 的值应乘以 2,这才是路径的实际占位情况。下面的例子,使用 svgdr 绘制一个路径图案,获取路径的起点坐标和宽高,然后依据坐标和宽高值给 svg 设置 viewBox 属性,这样所绘制的图像能够依据 svg 事先设置的宽高尺寸进行适配。</p>
        <div class="codebox" data-prev="1">
&lt;svg id="msvg" width="400" height="400"&gt;&lt;/svg&gt;

&lt;script type="module"&gt;
        import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
        var dr = Dr.dr(msvg);
       
        <txt-green>// 路径</txt-green>
        var d = 'M88.618667 570.794667q18.645333 250.624 409.045333 403.925333l14.72 4.096 14.72-4.096q390.357333-153.301333 409.045333-403.925333l0.085334-1.578667-0.981334-388.565333h-40.149333q-187.904 0-359.466667-121.088l-23.253333-15.530667-23.296 15.530667Q317.525333 180.650667 129.621333 180.650667h-40.149333l-0.981333 388.565333 0.128 1.578667z m80.384-4.522667q15.744 194.858667 343.381333 327.637333 327.594667-132.778667 343.338667-327.637333l-0.810667-306.346667q-178.773333-10.837333-342.528-118.784Q348.586667 249.088 169.813333 259.925333l-0.810666 306.346667z m252.501333 40.96L330.965333 516.693333l60.373334-60.330666 90.496 90.496 150.869333-150.826667 60.330667 60.330667-211.2 211.2-60.330667-60.330667z';
       
        dr.path(d, 'silver').id('path1'); <txt-green>// 绘制 id="path1" 的 path标签</txt-green>
        var od = path1.getBBox(); <txt-green>// 获取 path 标签数据</txt-green>
        var ww = od.x * 2 + od.width, hh = od.y * 2 + od.height; <txt-green>// 计算视口宽高</txt-green>
       
        dr.setsvg({viewBox: `0 0 ${ww} ${hh}`}); <txt-green>// 设置视口</txt-green>
&lt;/script&gt;
        </div>
        <p>如果追求绝对的适配,可以参考上述代码获得 ww 和 hh 的实际数值,根据此数值重新考虑 svg 标签的 width、height 属性如何设置,并将 viewBox 一并写好,后面的JS就无需 dr.setsvg 指令了。</p>
</div>

<script type="module">
        import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
        linenumber();
</script>

马黑黑 发表于 2025-8-26 12:28

这个路径是从阿里巴巴icon图标站那里拿到的,它设计于靠近 1024*1024 的平面范围。

马黑黑 发表于 2025-8-26 12:29

阿里巴巴矢量图标库:https://www.iconfont.cn/

杨帆 发表于 2025-8-26 12:46

点预览就是一个几何图形呀,看不到svg路径设计坐标及宽高数据呀

花飞飞 发表于 2025-8-26 12:54

马黑黑 发表于 2025-8-26 12:28
这个路径是从阿里巴巴icon图标站那里拿到的,它设计于靠近 1024*1024 的平面范围。

就是原来1024*1024大小的SVG盾牌图案,通过这个函数自动调整大小适用于400*400的窗口
很智能。。。{:4_199:}

马黑黑 发表于 2025-8-26 13:00

花飞飞 发表于 2025-8-26 12:54
就是原来1024*1024大小的SVG盾牌图案,通过这个函数自动调整大小适用于400*400的窗口
很智能。。。{:4_1 ...

这是实现适配的思路之一

马黑黑 发表于 2025-8-26 13:02

杨帆 发表于 2025-8-26 12:46
点预览就是一个几何图形呀,看不到svg路径设计坐标及宽高数据呀

你可以打印出来。获取到 ww 和 hh 后:

console.log(ww, hh);

这就在控制台打印出结果

花飞飞 发表于 2025-8-26 13:12

ww = od.x * 2 + od.width,
hh = od.y * 2 + od.height;
这样看比较好比较,
视窗的宽度ww,除了路径本身宽度width之外,还要加上原来2个x边距,才能保证左右两边都距离一样。

viewBox: `0 0 ${ww} ${hh}`});就是从原点开始,到之前设置好的视窗宽ww高hh大小。{:4_173:}

花飞飞 发表于 2025-8-26 13:17

<svg id="msvg" width="400" height="400"></svg>

<script type="module">
        import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
        var dr = Dr.dr(msvg);
       
        // 路径
        var d = 'm304.31434,369.84367c-11.93396,-4.81103 3.63894,-14.42992 9.53473,-18.68486c3.97132,-3.27686 -22.75991,0.45967 -11.47422,-10.91562c12.38205,-9.293 7.70476,-25.01469 -4.67193,-32.32272c-17.03291,-10.28139 -38.88723,-19.08083 -45.17981,-38.27899c-6.36274,-11.95768 8.7266,-24.55156 -0.97878,-35.34966c-7.81196,-14.02019 1.31463,-28.64032 6.98746,-41.62785c2.6088,-17.96561 -13.37221,-32.17299 -22.16078,-46.93274c-10.88225,-14.10475 -17.15527,-30.54002 -18.05669,-47.66753c-2.3666,-7.31075 0.25244,-18.66413 9.70272,-8.80777c19.7903,14.16642 41.51673,27.60865 55.36761,46.99907c2.62183,7.00398 13.12013,27.3035 13.70636,8.92112c0.27456,-25.26529 8.9064,-52.82088 31.02482,-69.75183c15.04456,-12.25504 23.15803,9.20304 23.86,20.10722c3.91582,21.45485 -2.57512,42.73083 -9.80829,62.99786c-2.65537,9.41874 -9.57063,35.22951 10.15178,25.71264c45.43336,-15.68101 100.47925,0.78827 130.07259,34.47441c13.6038,16.31041 19.56139,37.26549 19.42689,57.38591c-7.00489,11.82065 19.02203,-0.22144 9.59114,13.41603c-5.55187,15.10706 -21.23807,23.30433 -32.2258,34.70706c-11.18091,9.13716 -2.88501,28.6728 -21.37501,31.55135c-26.97914,7.43515 -55.30946,10.69202 -83.3957,12.58774c-15.71697,2.87856 -23.3445,-13.18782 -8.28034,-19.86702c7.22217,-9.95308 27.8846,-10.65057 34.02381,-12.22732c-14.67072,1.28324 -32.76338,-4.0698 -45.12562,4.05265c-7.48673,10.8651 -13.48294,25.16593 -29.18269,28.26716c-7.05544,1.75177 -14.30969,3.15656 -21.53425,1.2537l-0.00001,0.00001z';
       
        dr.path(d, 'green').id('path1'); // 绘制 id="path1" 的 path标签
        var od = path1.getBBox(); // 获取 path 标签数据
        var ww = od.x * 2 + od.width, hh = od.y * 2 + od.height; // 计算视口宽高
       
        dr.setsvg({viewBox: `0 0 ${ww} ${hh}`}); // 设置视口
</script>

花飞飞 发表于 2025-8-26 13:19

马黑黑 发表于 2025-8-26 12:29
阿里巴巴矢量图标库:https://www.iconfont.cn/

这个素材网站收了,需要登陆。
刚试了一个兔子形状的。

花飞飞 发表于 2025-8-26 13:21

马黑黑 发表于 2025-8-26 13:00
这是实现适配的思路之一

思路是统帅,然后再具体实现。。效果完美
看来只是思路之一,还有别的思路

杨帆 发表于 2025-8-26 14:00

本帖最后由 杨帆 于 2025-8-26 14:25 编辑 <br /><br />马黑黑 发表于 2025-8-26 13:02
你可以打印出来。获取到 ww 和 hh 后:

console.log(ww, hh);


不是太明白,但感觉挺好玩呢

杨帆 发表于 2025-8-26 14:06

本帖最后由 杨帆 于 2025-8-26 14:51 编辑 <br /><br />哇,终于显示出来了~

<svg id="msvg1" width="280" height="280"></svg>

<script type="module">
        import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
        var dr = Dr.dr(msvg1);
       
        // 路径
        var d = 'M853.32992 494.92992L921.6 307.2 648.52992 443.72992 716.8 170.67008l-136.52992 68.25984L512 102.4l-68.27008 136.52992L307.2 170.67008l68.27008 273.05984L102.4 307.2l68.27008 187.72992L102.4 580.27008 326.69696 692.4288l-53.62688 160.90112 204.8-58.50112V921.6h68.25984V794.8288l204.8 58.50112-53.62688-160.90112L921.6 580.27008z';
       
        dr.path(d, 'green').id('path12'); // 绘制 id="path1" 的 path标签
        var od = path12.getBBox(); // 获取 path 标签数据
        var ww = od.x * 2 + od.width, hh = od.y * 2 + od.height; // 计算视口宽高
       
        dr.setsvg({viewBox: `0 0 ${ww} ${hh}`}); // 设置视口
</script>

红影 发表于 2025-8-26 14:06

这个好,可以获取视口数据并得到视口宽高,这样就可以按事先设置的宽高尺寸进行适配了{:4_187:}

马黑黑 发表于 2025-8-26 18:31

红影 发表于 2025-8-26 14:06
这个好,可以获取视口数据并得到视口宽高,这样就可以按事先设置的宽高尺寸进行适配了

这是很巧妙的做法

马黑黑 发表于 2025-8-26 18:31

杨帆 发表于 2025-8-26 14:06
本帖最后由 杨帆 于 2025-8-26 14:51 编辑 哇,终于显示出来了~




多尝试,并多多体会。

马黑黑 发表于 2025-8-26 18:33

杨帆 发表于 2025-8-26 14:00
本帖最后由 杨帆 于 2025-8-26 14:25 编辑

不是太明白,但感觉挺好玩呢

要善用各种现有的工具。console.log(变量名1, 变量名2) 可以得到变量值,有了值就等于有了钱,你还不懂怎么用那也没办法了。

console.log() 可以只打印一个值,多个值时各值有都好隔开

马黑黑 发表于 2025-8-26 18:34

花飞飞 发表于 2025-8-26 13:21
思路是统帅,然后再具体实现。。效果完美
看来只是思路之一,还有别的思路

千对万对不如思路对

马黑黑 发表于 2025-8-26 18:34

花飞飞 发表于 2025-8-26 13:19
这个素材网站收了,需要登陆。
刚试了一个兔子形状的。

登录才能收藏、下载和管理。一切免费。

马黑黑 发表于 2025-8-26 18:34

花飞飞 发表于 2025-8-26 13:17
import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
        var dr = Dr.dr(msvg);
       
...

很漂亮
页: [1] 2 3
查看完整版本: JS:获取svg路径设计坐标及宽高数据