使用组的子元素剪辑或覆盖其他元素 [英] Use child element of group to clip or cover other element

查看:99
本文介绍了使用组的子元素剪辑或覆盖其他元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我相信这个问题出现了,因为我不得不将其组合起来两个半透明的元素,这样当它们重叠时,就好像它们是一个实体单元一样。

这是一个MCVE,应该在Chrome浏览器中查看,因为我没有对一个元素的转换原点使用绝对值。

  leftRoomFill.style.fill ='#fff'; 
leftRoomDoorFill.style.fill ='#fff';
leftRoomFill.style.opacity ='1';
leftRoomDoorFill.style.opacity ='1';
console.log(window.getComputedStyle(leftRoomFill).opacity);
console.log(window.getComputedStyle(leftRoomDoorFill).opacity);

问题是,即使记录到控制台的元素的不透明度设置为1,它看起来好像元素的不透明度根本不会改变,并且仍然是0。



我尝试了以下内容,这进一步巩固了我相信问题是不透明的问题。

  rightRoomFill.style.zIndex ='1'; 
leftRoomFill.style.zIndex ='2';
leftRoomDoorFill.style.zIndex ='2';

有人知道为什么上面的代码看起来没有任何影响吗?



我要做的是使用门的填充元素来裁剪房门的填充物。



我知道我可以简单地取消组合填充元素并使用不带不透明的颜色,但我真的很想保持使用半透明填充的灵活性。



任何想法

解决方案 zIndex 属性不会重新排列SVG元素(至少现在还没有)。



好像你想让一个左房组当鼠标悬停在右侧房间的地板上时,覆盖右侧房间的地板。但是,您只需要填写一份门的填充副本,在这种情况下,该填充项与该门打开的地板即左侧地板组合在一起。看起来你并不想在< defs> 部分创建一个主门,然后用< use>多次复制它。 元素。虽然我不确定这是否是最好的策略,但如果您确实想要这样做,一种方法是将当前可见的地板(即被挖出的地板)移动到SVG地板堆栈的可见底部,即到楼层父节点的代码顶部。您可以使用下面的代码来执行此操作:每当特定楼层被隐藏时: myFloorNode.parentNode.insertBefore(myFloorNode,myFloorNode.parentNode.firstChild); 。然后,任何其他门重叠,那个楼层就会覆盖它,切掉该楼层的一部分。



我觉得这件事有点麻烦方法是它需要不断地洗牌你的地板元素。这不一定是致命的。不过,这确实让我有点不安,因为如果重新洗牌变得更加复杂,它可能会造成一些混乱。它还要求您将门的填充设置为完全不透明,这可能会或可能不会被接受。无论如何,这只是我的直觉,而且将取决于你如何实现它。



你可以通过修改你的代码来简单的实现这个策略,如下所示:

 函数setFillOpacity(){
this.style.opacity ='0.5';

// ***添加以下行:
this.parentNode.insertBefore(this,this.parentNode.firstChild);

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

但是,请注意,即使这一次改变,即使门行程处于打开位置,有时门的填充似乎仍处于关闭位置。它似乎最终通过一个动态的关门动画结束开放,然后重新开放而自行完成。不过,我认为你必须处理代码,以确保门开始处于正确的位置。我会把这个问题留给你。


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.

leftRoomFill.style.fill = '#fff';
leftRoomDoorFill.style.fill = '#fff';
leftRoomFill.style.opacity = '1';
leftRoomDoorFill.style.opacity = '1';
console.log(window.getComputedStyle(leftRoomFill).opacity);
console.log(window.getComputedStyle(leftRoomDoorFill).opacity);

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.

rightRoomFill.style.zIndex = '1';
leftRoomFill.style.zIndex = '2';
leftRoomDoorFill.style.zIndex = '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?

解决方案

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(){
  this.style.opacity = '0.5';

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

  if (this.id === '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.

这篇关于使用组的子元素剪辑或覆盖其他元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆