【问题标题】:Use child element of group to clip or cover other element使用组的子元素剪辑或覆盖其他元素
【发布时间】:2017-07-17 11:11:16
【问题描述】:

我正在制作 SVG 蓝图,但遇到了一些问题。

我认为问题的出现是因为我必须将两个半透明的元素组合在一起,这样当它们重叠时,就好像它们是一个实体单元。

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);

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

我尝试了以下方法,这进一步巩固了我的信念,即问题是不透明的问题。

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

有人知道为什么上面的代码似乎没有任何效果吗?

我要做的是使用门填充元素来裁剪门延伸到的房间的填充。

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

有什么想法吗?

【问题讨论】:

  • 当 Chrome 修复他们的 transform-origin 错误时,你可能会再次遇到麻烦。
  • @RobertLongson ??

标签: javascript html xml svg opacity


【解决方案1】:

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

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

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

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

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

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

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

但是请注意,仅通过这一更改,有时即使门冲程处于“打开”位置,您的门填充似乎也处于“关闭”位置。它似乎最终会自行解决,通过在门关闭然后重新打开的动态动画结束时“打开”。但是,我认为您必须处理代码以确保门填充开始 在正确的位置。我将把解决这个问题的工作留给你。

【讨论】:

  • 我只是牺牲了不透明度并将门填充与房间填充分开。另外,有人告诉我,使用带有动画的深度嵌入 <defs><use/><defs> 确实需要大量的处理能力,尤其是当你有半百个不同的元素时,这就是我不费心去做的原因。
【解决方案2】:

不清楚你在问什么。为什么你认为房间不透明度是 0?它们在 Chrome 中对我来说变得可见(绿色)。所以“1”的值对我来说似乎是正确的。不应该发生的应该是什么?

关于您的 zIndex 问题:您可能不得不使用不同的方法。 z-index 目前不适用于 SVG 元素。它已被添加到 SVG 2 中,但我认为还没有任何浏览器支持它。

【讨论】:

  • 每个填充的不透明度在 CSS 中设置为 0,当您悬停一个房间时,that particular room's 填充设置为 0.51 或其他。我想要做的是将门填充(属于左侧房间)设置为opacity: 1z-index: 99,当您将鼠标悬停在右侧房间时,这样门填充会掩盖右侧房间的填充部分。没关系,我只是牺牲了不透明度
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 2013-10-19
  • 2018-10-18
  • 2023-03-24
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多