Anthony Anthony -4 years ago 114
HTML Question

Use child element of group to clip or cover other element

I'm working on an SVG blueprint and I've run into a bit of an issue.

I believe the issue arises because I've had to group two, semi-translucent elements so that when they overlap it appears as if they are one solid unit.

Here is an MCVE, which should be viewed in Chrome since I didn't use "absolute" values for one element's transform-origin. = '#fff'; = '#fff'; = '1'; = '1';

The issue is that, even though it's logging to console that the elements' opacities are set to 1, it appears as if the elements' opacities don't change at all and are still 0.

I've tried the following which further cements my belief that the issue is an issue of opacity. = '1'; = '2'; = '2';

Does anybody know why the code above has seemingly no effect whatsoever?

What I'm trying to do is use the door fill element to crop the fill of the room into which the door extends.

I know I could simply ungroup the fill elements and use colors without an opacity, but I'd really like to maintain the flexibility of being able to use semi-translucent fills.

Any ideas?

Answer Source

The zIndex property does not rearrange SVG elements (at least not yet).

It seems like you want to make the door fill from a left-room group "cover" the right-room floor upon mousing over the right room floor. However, you want to do so only having a single copy of the door fill which in this case is grouped together with the floor that that door opens out of, i.e. the left floor. It seems that you do not want to create a master door fill in a <defs> section and then copy it multiple times with <use> elements. While I'm not sure this is the best strategy, if you really want to do this, one way is to move the floor that is currently visible (i.e. the one moused over) to the visible bottom of the stack of SVG floors, i.e. to the code-top of the floor's parent node. You can do this with the following code that is run whenever a particular floor is moused over: myFloorNode.parentNode.insertBefore(myFloorNode, myFloorNode.parentNode.firstChild);. Then any other door fills that overlap that floor will "cover" it, "cutting out" that section of the floor.

The thing that I find a little messy about this approach is that it requires constantly shuffling your floor elements around. That's not necessarily lethal. However it does make me a little uneasy, as it might create some confusion if the re-shuffling ever gets any more complicated. It also requires you to set that door fill to be completely opaque which may or may not be acceptable. In any case, that's just my gut feeling, and will depend on exactly how you implement it.

You can do a simple implementation of this strategy by modifying your code as follows:

function setFillOpacity(){ = '0.5';

  // *** add the following line:
  this.parentNode.insertBefore(this, this.parentNode.firstChild);

  if ( === 'right-room-fill'){...

Note, however, that with just this one change, sometimes your door fill seems to be in the "closed" position even if the door stroke is in the "open" position. It seems to eventually work itself out, by "open"ing by the end of a dynamic animation of a door closing and then re-opening. However, I think you'll have to work on the code to ensure that the door fill starts in the correct position. I'll leave working through that problem to you.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download