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">
<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);
<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>
</script>
</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> 这个路径是从阿里巴巴icon图标站那里拿到的,它设计于靠近 1024*1024 的平面范围。 阿里巴巴矢量图标库:https://www.iconfont.cn/ 点预览就是一个几何图形呀,看不到svg路径设计坐标及宽高数据呀 马黑黑 发表于 2025-8-26 12:28
这个路径是从阿里巴巴icon图标站那里拿到的,它设计于靠近 1024*1024 的平面范围。
就是原来1024*1024大小的SVG盾牌图案,通过这个函数自动调整大小适用于400*400的窗口
很智能。。。{:4_199:} 花飞飞 发表于 2025-8-26 12:54
就是原来1024*1024大小的SVG盾牌图案,通过这个函数自动调整大小适用于400*400的窗口
很智能。。。{:4_1 ...
这是实现适配的思路之一 杨帆 发表于 2025-8-26 12:46
点预览就是一个几何图形呀,看不到svg路径设计坐标及宽高数据呀
你可以打印出来。获取到 ww 和 hh 后:
console.log(ww, hh);
这就在控制台打印出结果 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:} <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 12:29
阿里巴巴矢量图标库:https://www.iconfont.cn/
这个素材网站收了,需要登陆。
刚试了一个兔子形状的。 马黑黑 发表于 2025-8-26 13:00
这是实现适配的思路之一
思路是统帅,然后再具体实现。。效果完美
看来只是思路之一,还有别的思路 本帖最后由 杨帆 于 2025-8-26 14:25 编辑 <br /><br />马黑黑 发表于 2025-8-26 13:02
你可以打印出来。获取到 ww 和 hh 后:
console.log(ww, hh);
不是太明白,但感觉挺好玩呢 本帖最后由 杨帆 于 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> 这个好,可以获取视口数据并得到视口宽高,这样就可以按事先设置的宽高尺寸进行适配了{:4_187:} 红影 发表于 2025-8-26 14:06
这个好,可以获取视口数据并得到视口宽高,这样就可以按事先设置的宽高尺寸进行适配了
这是很巧妙的做法 杨帆 发表于 2025-8-26 14:06
本帖最后由 杨帆 于 2025-8-26 14:51 编辑 哇,终于显示出来了~
多尝试,并多多体会。 杨帆 发表于 2025-8-26 14:00
本帖最后由 杨帆 于 2025-8-26 14:25 编辑
不是太明白,但感觉挺好玩呢
要善用各种现有的工具。console.log(变量名1, 变量名2) 可以得到变量值,有了值就等于有了钱,你还不懂怎么用那也没办法了。
console.log() 可以只打印一个值,多个值时各值有都好隔开 花飞飞 发表于 2025-8-26 13:21
思路是统帅,然后再具体实现。。效果完美
看来只是思路之一,还有别的思路
千对万对不如思路对 花飞飞 发表于 2025-8-26 13:19
这个素材网站收了,需要登陆。
刚试了一个兔子形状的。
登录才能收藏、下载和管理。一切免费。 花飞飞 发表于 2025-8-26 13:17
import Dr from 'https://638183.freep.cn/638183/web/mod/svgdr.js';
var dr = Dr.dr(msvg);
...
很漂亮