对SVG组应用缩放变换



作为示例,我提供了一个使用Sketch创建的灯的SVG。当光标悬停在上方时,我打算将灯的头部按一个因子(例如这里的1.2)进行缩放,以指示交互性。然而,问题是,当悬停在灯头上时,它的位置也会发生变化。首先,我想知道尺度是用什么来基于它的变换-它是其他变换,在椭圆/路径的位置值?

其次,我如何确保缩放发生在我感兴趣的组()的原点附近?

我尝试将元素上的x,y位置的翻译交换出来,以及嵌套svg,但无济于事。我相信svg框架的一个基本部分我还没有完全掌握。

.interactive:hover {
scale: 1.2;
}
<svg viewBox="0 0 1920 1080" version="1.1" xmlns="http://www.w3.org/2000/svg">
<svg>
<g fill="none" fill-rule="evenodd" transform="translate(0 .832)">
<path fill="#FCFC30" fill-opacity=".35"
d="M283.589311,155.632129 L373.36705,522.838236 C377.564302,540.005704 367.049864,557.325232 349.882396,561.522484 C347.399779,562.129455 344.853386,562.436827 342.297648,562.438029 L162.3966,562.522631 C144.72349,562.530942 130.389866,548.210793 130.381555,530.537683 C130.380345,527.962942 130.689882,525.397465 131.303454,522.896901 L221.426762,155.606192 C225.638338,138.442233 242.966634,127.942251 260.130594,132.153828 C271.714734,134.996266 280.756541,144.04562 283.589311,155.632129 Z"
transform="rotate(32 252.31 295.631)"></path>
/* This following group is the one to be made interactive */
<g fill-rule="nonzero" transform="translate(264.313 121.836)" class="interactive" cursor="pointer">
<ellipse fill="#EFCF6A" rx="17.298" ry="17.28" cx="41.1" cy="90.717"></ellipse>
<path fill="#E5DBDA"
d="M0,68.8755609 C0,68.8755609 23.9403854,39.015945 48.4343057,32.3804748 L89.5342738,57.6782049 C89.5342738,57.6782049 95.6231579,89.4731662 76.9413543,118.641587 L0,68.8755609 Z"></path>
<path fill="#E5DBDA"
d="M89.5342738,0.585513479 L97.5605301,5.2856382 C97.5605301,5.2856382 102.127193,8.32689537 100.88174,15.2388435 C97.8157022,29.5668288 94.0284052,43.7312658 89.5342738,57.6782049 L48.4343057,32.3804748 C48.4343057,32.3804748 73.6201447,6.52978886 79.0171102,2.52085895 C81.9461562,0.0899965767 85.9303942,-0.643174192 89.5342738,0.585513479 L89.5342738,0.585513479 Z"></path>
</g>
<polygon fill="#BFBEBA" fill-rule="nonzero"
points="351.731 188.715 524.683 188.65 524.678 200.692 351.726 200.757"
transform="rotate(22.9 438.204 194.704)"></polygon>
<polygon fill="#BFBEBA" fill-rule="nonzero"
points="400.402 312.102 586.898 312.149 586.902 328.477 400.406 328.43"
transform="rotate(104.4 493.652 320.29)"></polygon>
<ellipse cx="516.376" cy="230.602" fill="#E5DBDA" fill-rule="nonzero" rx="11.624"
ry="11.612"></ellipse>
<path fill="#BFBEBA" fill-rule="nonzero"
d="M391.968793,463.396323 L508.764661,463.396323 C512.968159,463.396323 516.375767,466.800366 516.375767,470.999466 L516.375767,482.611539 L384.219304,482.611539 L384.219304,470.999466 C384.219304,468.958805 385.039816,467.003668 386.497246,465.573761 C387.954677,464.143853 389.926333,463.35922 391.968793,463.396323 Z"></path>
<polygon fill="#BFBEBA" fill-rule="nonzero"
points="453.273 466.714 461.299 419.022 476.521 419.022 483.164 466.714"></polygon>
<ellipse cx="469.879" cy="414.321" fill="#E5DBDA" fill-rule="nonzero" rx="16.606"
ry="16.589"></ellipse>
</g>
</svg>
</svg>

首先是一个小例子。红色矩形的行为就像你的灯——从0,0(左上角)开始缩放。"right"解决方案是绿色。你可以看到,我通过设置x和y为负值将(0,0)移动到矩形的中间。这只是一种形状——你有多种形状。因此,蓝色矩形嵌套在更多的组和悬停/缩放发生在一个组,没有转换(重要)。因此,除了改变所有形状(这里只有一个蓝色矩形)的所有x,y值之外,你可以分组并将该分组向负方向平移,使0,0成为分组的中间位置。

现在,去看看我对你的画的编辑。我加了两组。一个是群的比例,另一个是0 0在中间。这些值是整个组的宽度和高度的一半。如果您使用编辑器,您可以选择组/元素并查看宽度和高度,或者像我在浏览器中打开开发工具并在元素/组上使用getBBox()函数(它返回宽度= 101.09695434570312和高度= 118.64158630371094 ~ 50,60)。我还必须在原始组中添加相反的值,以便灯在适当的位置。

PS我还移动了将手臂拉到灯组上方的多边形,以便在缩放时保持在灯的后面。

.hover:hover {
scale: 1.2;
}
<svg viewBox="0 0 100 100" width="200">
<rect class="hover" width="20" height="20" x="0" y="10" fill="red" />
<g transform="translate(40 20)">
<rect class="hover" width="20" height="20" x="-10" y="-10" fill="green" />
</g>
<g transform="translate(70 20)">
<g class="hover">
<g transform="translate(-10 -10)">
<rect width="20" height="20" x="0" y="0" fill="blue" />
</g>
</g>
</g>
</svg>

.interactive:hover > g {
scale: 1.2;
}
<svg viewBox="0 0 1920 1080" version="1.1" xmlns="http://www.w3.org/2000/svg">
<svg>
<g fill="none" fill-rule="evenodd" transform="translate(0 .832)">
<path fill="#FCFC30" fill-opacity=".35"
d="M283.589311,155.632129 L373.36705,522.838236 C377.564302,540.005704 367.049864,557.325232 349.882396,561.522484 C347.399779,562.129455 344.853386,562.436827 342.297648,562.438029 L162.3966,562.522631 C144.72349,562.530942 130.389866,548.210793 130.381555,530.537683 C130.380345,527.962942 130.689882,525.397465 131.303454,522.896901 L221.426762,155.606192 C225.638338,138.442233 242.966634,127.942251 260.130594,132.153828 C271.714734,134.996266 280.756541,144.04562 283.589311,155.632129 Z"
transform="rotate(32 252.31 295.631)"></path>
<polygon fill="#BFBEBA" fill-rule="nonzero"
points="351.731 188.715 524.683 188.65 524.678 200.692 351.726 200.757"
transform="rotate(22.9 438.204 194.704)"></polygon>
/* This following group is the one to be made interactive */
<g fill-rule="nonzero" transform="translate(264.313 121.836) translate(50 60)" class="interactive" cursor="pointer">
<g>
<g transform="translate(-50 -60)">
<ellipse fill="#EFCF6A" rx="17.298" ry="17.28" cx="41.1" cy="90.717"></ellipse>
<path fill="#E5DBDA"
d="M0,68.8755609 C0,68.8755609 23.9403854,39.015945 48.4343057,32.3804748 L89.5342738,57.6782049 C89.5342738,57.6782049 95.6231579,89.4731662 76.9413543,118.641587 L0,68.8755609 Z"></path>
<path fill="#E5DBDA"
d="M89.5342738,0.585513479 L97.5605301,5.2856382 C97.5605301,5.2856382 102.127193,8.32689537 100.88174,15.2388435 C97.8157022,29.5668288 94.0284052,43.7312658 89.5342738,57.6782049 L48.4343057,32.3804748 C48.4343057,32.3804748 73.6201447,6.52978886 79.0171102,2.52085895 C81.9461562,0.0899965767 85.9303942,-0.643174192 89.5342738,0.585513479 L89.5342738,0.585513479 Z"></path>
</g>
</g>
</g>

<polygon fill="#BFBEBA" fill-rule="nonzero"
points="400.402 312.102 586.898 312.149 586.902 328.477 400.406 328.43"
transform="rotate(104.4 493.652 320.29)"></polygon>
<ellipse cx="516.376" cy="230.602" fill="#E5DBDA" fill-rule="nonzero" rx="11.624"
ry="11.612"></ellipse>
<path fill="#BFBEBA" fill-rule="nonzero"
d="M391.968793,463.396323 L508.764661,463.396323 C512.968159,463.396323 516.375767,466.800366 516.375767,470.999466 L516.375767,482.611539 L384.219304,482.611539 L384.219304,470.999466 C384.219304,468.958805 385.039816,467.003668 386.497246,465.573761 C387.954677,464.143853 389.926333,463.35922 391.968793,463.396323 Z"></path>
<polygon fill="#BFBEBA" fill-rule="nonzero"
points="453.273 466.714 461.299 419.022 476.521 419.022 483.164 466.714"></polygon>
<ellipse cx="469.879" cy="414.321" fill="#E5DBDA" fill-rule="nonzero" rx="16.606"
ry="16.589"></ellipse>
</g>
</svg>
</svg>

最新更新