简体   繁体   English

在一组 SVG 元素上选择性地应用 CSS 效果

[英]Selectively apply a CSS effect on a group of SVG elements

I draw a group of 3 svg elements: a blue square, a red circle and a green ellipse (see code below).我画了一组 3 个 svg 元素:一个蓝色正方形、一个红色圆圈和一个绿色椭圆(见下面的代码)。 At the moment when one of these elements is mouse overed, the 3 elements scale up.当鼠标悬停其中一个元素时,这三个元素会按比例放大。

I am trying to apply a slightly more complicated behaviour, but without success so far:我正在尝试应用稍微复杂一点的行为,但到目前为止没有成功:

. . when mouse overing the blue square, then all 3 elements should scale up (this part works),当鼠标悬停在蓝色方块上时,所有 3 个元素都应该按比例放大(这部分有效),

. . when mouse overing the red circle, only the red circle and the blue square should scale up (the green ellipse should not move),当鼠标悬停在红色圆圈上时,只有红色圆圈和蓝色方块应该放大(绿色椭圆不应该移动),

. . when mouse overing the green ellipse, only the green ellipse and the blue square should scale up (the red circle should not move).当鼠标悬停在绿色椭圆上时,只有绿色椭圆和蓝色方块应该按比例放大(红色圆圈不应该移动)。

Is it possible to achieve this behaviour?是否有可能实现这种行为?

 .zoom * { transition: all.4s; transform-box: fill-box; }.zoom:hover * { transform: scale(1.2); transform-origin: 50% 50%; }
 <svg width="500" height="500"> <g id="all_shapes" class="zoom"> <rect id="square" x="20" y="20" width="100" height="100" fill="blue"/> <circle id="circle" cx="170" cy="45" r="25" fill="red" /> <ellipse id="ellipse" cx="170" cy="100" rx="40" ry="25" fill="green" /> </g> </svg>

EDIT编辑

The use of CSS only is not mandatory.仅使用 CSS 不是强制性的。 JavaScript could also be used if easier, maybe by following these steps?如果更容易,也可以使用 JavaScript,也许按照这些步骤?

(1) get all elements'id from the group 'all_shapes', (1)从组'all_shapes'中获取所有元素'id,

(2) create an array with the id 'square' by default, (2) 默认创建一个id为'square'的数组,

(3) append the id of the element being hover, (3) append 元素的 id 为 hover,

(4) apply the CSS '.zoom' to the elements of the array. (4) 将 CSS '.zoom' 应用于数组的元素。

This is possible with CSS only.这仅适用于 CSS。

 .zoom * { transition: all.4s; transform-box: fill-box; }.zoom:hover *:not(#circle), .zoom #square:hover ~ *, .zoom #square:hover, .zoom #circle:hover { transform: scale(1.2); transform-origin: 50% 50%; }.zoom #circle:hover ~ * { transform: scale(1); transform-origin: 50% 50%; }
 <svg width="500" height="500"> <g id="all_shapes" class="zoom child"> <rect id="square" x="20" y="20" width="100" height="100" fill="blue"/> <circle id="circle" cx="170" cy="45" r="25" fill="red" /> <ellipse id="ellipse" cx="170" cy="100" rx="40" ry="25" fill="green" /> </g> </svg>

Since Sanjay Choudhary posted an imo perfect CSS only answer, here is a Javascript way to do it.由于 Sanjay Choudhary 发布了一个 imo 完美的 CSS 唯一答案,这里有一个 Javascript 方法来做到这一点。


plain Javascript平原 Javascript

You just have to toggle a class (here .zoom ) with Javascript, your CSS stays nearly the same:您只需将 class (此处.zoom )与 Javascript 切换,您的 CSS 几乎保持不变:

#all_shapes * {
  transition: all .4s;
  transform-box: fill-box;
}

.zoom {
  transform: scale(1.2);
  transform-origin: 50% 50%;
}

You first store all elements inside of the group #all_shapes with an ID in a var (here elems ).您首先将具有 ID 的组内的所有元素存储在 var(此处elems #all_shapes中。 Then you need two event listeners, one for mouseover and one for mouseleave .然后你需要两个事件监听器,一个用于mouseover ,一个用于mouseleave

On mouseover you add the class .zoom to all elements that are stored in elems if the square is hovered ( if (event.target.id == 'square') ).mouseover时,如果square悬停( if (event.target.id == 'square') ),则将 class .zoom添加到存储在elems中的所有元素。 Otherwise you add that class only to the event target and the square.否则,您仅将 class 添加到事件目标和正方形。 On mouseleave you remove the class .zoom from all elements that are stored in elems .mouseleave上,您从存储在elems中的所有元素中删除 class .zoom

Working example:工作示例:

 let elems = document.querySelectorAll('#all_shapes *[id]'); document.querySelector('#all_shapes').addEventListener('mouseover', function(event) { if (event.target.id == 'square') { for (i = 0; i < elems.length; i++) { elems[i].classList.add('zoom'); } } else if (..event.target.id) { document.querySelector('#square');classList.add('zoom'). event.target;classList;add('zoom'). } }). document,querySelector('#all_shapes');addEventListener('mouseleave'. function() { for (i = 0; i < elems.length. i++) { elems[i];classList;remove('zoom'); } });
 #all_shapes * { transition: all.4s; transform-box: fill-box; }.zoom { transform: scale(1.2); transform-origin: 50% 50%; }
 <svg width="500" height="500"> <g id="all_shapes"> <rect id="square" x="20" y="20" width="100" height="100" fill="blue"/> <circle id="circle" cx="170" cy="45" r="25" fill="red" /> <ellipse id="ellipse" cx="170" cy="100" rx="40" ry="25" fill="green" /> </g> </svg>


jQuery jQuery

If you are using jQuery the code gets far simpler.如果您使用的是 jQuery,则代码会变得简单得多。 You only need one event listener hover() and can omit the detour over the var elems , because it is needed only two times and $('#all_shapes *[id]') is pretty short so you can use it directly.您只需要一个事件监听器hover()并且可以省略 var elems的绕行,因为它只需要两次并且$('#all_shapes *[id]')非常短,因此您可以直接使用它。

Working example:工作示例:

 $('#all_shapes *[id]').hover(function() { if ($(this).is('#square')) { $('#all_shapes *[id]').toggleClass('zoom'); } else { $('#square').toggleClass('zoom'); $(this).toggleClass('zoom'); } });
 #all_shapes * { transition: all.4s; transform-box: fill-box; }.zoom { transform: scale(1.2); transform-origin: 50% 50%; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <svg width="500" height="500"> <g id="all_shapes"> <rect id="square" x="20" y="20" width="100" height="100" fill="blue"/> <circle id="circle" cx="170" cy="45" r="25" fill="red" /> <ellipse id="ellipse" cx="170" cy="100" rx="40" ry="25" fill="green" /> </g> </svg>

multiple groups多组

Refering to the comments here is another example for multiple groups with the same elements and independent hover effect for each group.参考这里的注释是具有相同元素的多个组的另一个示例,并且每个组具有独立的 hover 效果。

The difference is that you select the groups by class (here .all_shapes ) and the elements by a small detour over the parent of the hover target:不同之处在于您 select 由 class (此处.all_shapes )组和元素通过 hover 目标的父级绕道而行:

$(this).parent().find('...

To select the square of the group you could use a class .square or an attribute selector like [id^="square"] (which means the ID begins with "square").对于 select 组的正方形,您可以使用 class .square或类似[id^="square"]的属性选择器(这意味着 ID 以“square”开头)。

Working example:工作示例:

 $('.all_shapes *[id]').hover(function() { if ($(this).is('[id^="square"]')) { $(this).parent().find('*[id]').toggleClass('zoom'); } else { $(this).parent().find('[id^="square"]').toggleClass('zoom'); $(this).toggleClass('zoom'); } });
 .all_shapes * { transition: all.4s; transform-box: fill-box; }.zoom { transform: scale(1.2); transform-origin: 50% 50%; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <svg width="500" height="500"> <g id="all_shapes1" class="all_shapes"> <rect id="square1" x="20" y="20" width="100" height="100" fill="blue"/> <circle id="circle1" cx="170" cy="45" r="25" fill="red" /> <ellipse id="ellipse1" cx="170" cy="100" rx="40" ry="25" fill="green" /> </g> <g id="all_shapes2" class="all_shapes"> <rect id="square2" x="220" y="20" width="100" height="100" fill="blue"/> <circle id="circle2" cx="370" cy="45" r="25" fill="red" /> <ellipse id="ellipse2" cx="370" cy="100" rx="40" ry="25" fill="green" /> </g> </svg>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM