如何将<use>引用的SVG对象约束到指定rect的尺寸与位置?
解决SVG
核心问题分析
<use>的x/y属性是相对被引用元素原始位置的偏移量,而非绝对定位,因此无法直接复用rect的x/y属性- 直接使用
transform: scale()会以元素原始左上角为锚点缩放,导致位置偏移,必须将锚点改为元素中心再执行缩放
解决方案步骤
1. 获取被引用元素的原始边界盒(BBox)
先确定复用对象的原始尺寸与位置(可通过浏览器控制台element.getBBox()或Illustrator直接查看):
- #fish: x≈449, y≈57.81, width≈133.6, height≈54.4
- #bat: x≈704, y≈13.8, width≈95.7, height≈67.5
2. 为每个rect生成匹配的<use>
使用transform组合translate和scale,先将元素锚点移到自身中心,缩放后再定位到rect的中心,公式为:
transform: translate(rect中心X, rect中心Y) scale(rect宽/原始宽, rect高/原始高) translate(-原始中心X, -原始中心Y)
修正后的完整代码
<?xml version="1.0" encoding="utf-8"?> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1366 768" enable-background="new 0 0 1366 768" xml:space="preserve"> <g id="fish"> <path fill="#66BB6A" d="M579.41,70.53c-1.91-1.08-4.32-0.96-6.12,0.3l-8.7,5.76l-3,2.28c-2.58-1.2-5.82-2.4-9-3.6V63.81 c0-3.3-2.7-6-6-6c-6.3,0-11.04,1.8-13.92,5.28c-1.37,1.44-2.34,3.24-3,5.28c-12.06-2.64-26.34-4.56-43.08-4.56 c-11.28,0-22.5,7.92-23.88,8.88c-0.06,0.06-0.12,0.12-0.12,0.12l12,15l-9.6,9.6c4.86,8.34,15.6,8.4,15.6,8.4h12v6 c0,2.4,1.44,4.62,3.72,5.52c0.72,0.36,1.5,0.48,2.28,0.48c1.56,0,3.12-0.6,4.26-1.74l10.2-10.26h3.54c4.44,0,8.76-0.36,13.02-0.96 c2.22,8.1,8.28,12.96,16.98,12.96c3.3,0,6-2.7,6-6c0,0-0.06-12.48-0.12-12.72l9.12-2.28l11.7,7.98c0.96,0.66,2.16,1.02,3.3,1.02 c0.96,0,1.92-0.24,2.82-0.72c1.98-1.02,3.18-3.06,3.18-5.28v-24C582.59,73.59,581.39,71.55,579.41,70.53z" /> <path opacity="0.2" enable-background="new " d="M561.59,78.87v8.94h-87l-12-15c0,0,0.06-0.06,0.12-0.12 c1.38-0.96,12.6-8.88,23.88-8.88c16.74,0,31.02,1.92,43.08,4.56c8.88,1.98,16.56,4.44,22.92,6.9 C555.77,76.47,559.01,77.67,561.59,78.87z" /> <path opacity="0.3" enable-background="new " d="M488.09,72.81c0,2.48-2.02,4.5-4.5,4.5s-4.5-2.02-4.5-4.5s2.02-4.5,4.5-4.5 S488.09,70.32,488.09,72.81z M552.48,99.12c0.03,0.23,0.1,0.45,0.1,0.69v12c0,3.32-2.68,6-6,6c-8.7,0-14.75-4.85-16.99-12.97 C537.94,103.67,545.73,101.51,552.48,99.12z M513.07,105.81l-10.24,10.24c-1.15,1.15-2.68,1.76-4.24,1.76 c-0.77,0-1.55-0.14-2.3-0.46c-2.24-0.92-3.7-3.12-3.7-5.54v-6H513.07z M582.59,75.81v24c0,2.21-1.22,4.25-3.17,5.29 c-0.89,0.47-1.86,0.71-2.83,0.71c-1.16,0-2.33-0.34-3.33-1.01l-11.67-7.99V78.87l11.67-8.05c1.84-1.23,4.21-1.34,6.16-0.3 C581.37,71.56,582.59,73.59,582.59,75.81z M546.59,57.81c-9,0-14.7,3.66-16.92,10.56c8.88,1.98,16.56,4.44,22.92,6.9V63.81 C552.59,60.51,549.89,57.81,546.59,57.81z" /> </g> <g id="bat"> <path fill="#616161" d="M799.29,87.2l9.87,28.43l-29.37-9.4c-7.35,1.29-16.53,5.6-16.53,19.19c0,0-28.9-15.71-35.7,9.79v-34.27 c18.83,0,29.91-5.56,35.67-9.84l-10.17-14.64h10.2l5.1-4.9v-9.79l15.25,9.76c4.46-5.53,10.25-16.17,10.25-34.24h35.7 c-26.77,6.12-10.2,34.27-10.2,34.27C805.1,71.56,800.61,80.19,799.29,87.2z" /> <path opacity="0.3" enable-background="new " d="M799.29,87.2l9.87,28.43l-29.37-9.4c-6.91-2.23-12.83-9.45-16.56-15.12 l-10.17-14.64h10.2l5.1-4.9v-9.79l15.25,9.76C788.89,74.25,795.52,79.52,799.29,87.2z" /> </g> <!-- 占位rect保留,用于Illustrator编辑位置与尺寸 --> <rect id="placeholder-fish2" x="502" y="174" fill="#CCCCCC" width="36" height="36" /> <rect id="placeholder-fish3" x="486" y="258" fill="#CCCCCC" width="68" height="68" /> <rect id="placeholder-fish4" x="464" y="395" fill="#CCCCCC" width="114" height="114" /> <rect id="placeholder-fish5" x="449" y="583" fill="#CCCCCC" width="142" height="142" /> <rect id="placeholder-bat2" x="757" y="174" fill="#CCCCCC" width="36" height="36" /> <rect id="placeholder-bat3" x="741" y="258" fill="#CCCCCC" width="68" height="68" /> <rect id="placeholder-bat4" x="719" y="395" fill="#CCCCCC" width="114" height="114" /> <rect id="placeholder-bat5" x="704" y="583" fill="#CCCCCC" width="142" height="142" /> <!-- 修正后的<use>元素,精准匹配对应rect的位置与尺寸 --> <!-- fish系列 --> <use xlink:href="#fish" id="fish2" transform="translate(520, 192) scale(0.27, 0.66) translate(-515.8, -84.01)" /> <use xlink:href="#fish" id="fish3" transform="translate(520, 292) scale(0.51, 1.25) translate(-515.8, -84.01)" /> <use xlink:href="#fish" id="fish4" transform="translate(521, 452) scale(0.85, 2.1) translate(-515.8, -84.01)" /> <use xlink:href="#fish" id="fish5" transform="translate(520, 654) scale(1.06, 2.61) translate(-515.8, -84.01)" /> <!-- bat系列 --> <use xlink:href="#bat" id="bat2" transform="translate(775, 192) scale(0.38, 0.53) translate(-751.85, -47.55)" /> <use xlink:href="#bat" id="bat3" transform="translate(775, 292) scale(0.71, 1.01) translate(-751.85, -47.55)" /> <use xlink:href="#bat" id="bat4" transform="translate(776, 452) scale(1.19, 1.69) translate(-751.85, -47.55)" /> <use xlink:href="#bat" id="bat5" transform="translate(775, 654) scale(1.48, 2.11) translate(-751.85, -47.55)" /> </svg>
关键说明
- 所有
<use>不再设置x/y属性,完全通过transform控制位置与缩放 - 先执行
translate(-原始中心)将元素锚点移到自身中心,再缩放,最后translate(rect中心)定位到目标位置,彻底解决缩放移位问题 - 占位rect可在Illustrator中直接修改
x/y/width/height,之后重新计算对应的transform参数即可更新复用对象的位置与尺寸
内容的提问来源于stack exchange,提问作者Kalaschnik
相关产品推荐
相关产品推荐

