为什么<feDropShadow>没有显示?

3

编辑:尝试创建一个mcve,但无法重现该问题。现在我完全懵了。在CodeSandbox中可以正常工作,在我的项目中不能。


初始问题
我想创建一个动态的内联SVG元素,并将其旋转映射到[(ngModel)]。没有什么花哨的东西。

花哨的部分是我想使用一个带有<feDropShadow><filter>。而且我希望阴影是动态的(始终指向上方,而不管指针的旋转如何)。这是我之前在Vue中做过的事情。

这里有一个演示效果的fiddle:https://jsfiddle.net/websiter/y4ghan0k/

但是,千真万确地说,当<svg>嵌入模板时,我就不能让<feDropShadow>在Angular中工作。它只是不显示。没有错误或警告。如果我将其插入为<img src="path/to/svg">,它像预期的那样工作(阴影被显示),但是我就无法再旋转路径了,因为需要将被转换的元素作为带有过滤器的元素的子元素。

请注意,这并不是因为这个url()过滤器问题 - 我正在使用this.location.path()前缀来设置过滤器。

这是我的Angular代码要点:

component.ts:

import { Location } from '@angular/common';

export class SomeComponent {
  constructor(private location: Location) {}
  dsLink = `url(${this.location.path()}#drop-shadow)`;
}

component.html:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="180" y="100"
     viewBox="0 0 180 100" xml:space="preserve">
  <defs>
    <filter xmlns="http://www.w3.org/2000/svg" id="drop-shadow" height="130%">
      <feDropShadow dx="0" dy="-4" flood-color="rgba(0,0,0,.65)"/>
    </filter>
  </defs>
  <g [attr.filter]="dsLink">
    <path fill="#fff" d="M102.2,89.5c0-0.1,0-0.1,0-0.2c0-0.2,0-0.4-0.1-0.6L92.9,6.8c-0.1-0.8-3.2-0.9-3.3,0
      L78.7,88.5c-0.1,0.2-0.1,0.4-0.1,0.6c0,0.1,0,0.1,0,0.2l0,0.1c0,0,0,0.1,0.1,0.1c0.5,2.4,5.6,4.4,11.7,4.4
      c6.2,0.1,11.2-1.8,11.8-4.2c0,0,0.1-0.1,0.1-0.1L102.2,89.5z">
    </path>
  </g>
</svg>

为简单起见,我已从应该旋转指针的路径中删除了[(ngModel)]

url() 过滤器似乎是正确的,没有错误。但是阴影未显示。

我需要做/知道什么特殊的事情才能使 Angular 内联处理 <svg> 元素?

我漏掉了什么?

1个回答

2

我终于破解了它,所以我在这里发布它,希望能帮助其他人。

简而言之:在每个组件实例中为过滤器使用唯一的ID。否则,每个实例将使用在DOM中找到的第一个具有该ID的过滤器,并且如果该过滤器恰好位于具有display:nonevisibility:hiddenopacity:0的父级内部,则应用该过滤器将使您应用它的任何内容也变得不可见。


问题与我在不同选项卡中使用相同组件有关。这会创建组件的单独实例,每个实例都使用相同的ID(#drop-shadow)。虽然具有重复的ID显然是无效的HTML,但如果我们没有处理过滤器,这实际上不会成为问题。因为,由于<defs>是相同的,如果第4个选项卡上的组件使用第一个选项卡上定义的<defs>,那么这并不重要。

除非涉及<filter>,因为它们实际上是动态计算像素渲染结果的。这意味着当未呈现定义<filter><svg>时,使用过滤器将使浏览器计算(逐像素)应用过滤器的结果,并且它始终会导致所有像素变为不可见。

因此,解决方案是在每个单独的组件实例中分配唯一的ID。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接