使用javascript动态修改SVG过滤器

时间:2013-10-02 02:56:09

标签: javascript svg svg-filters

我正在尝试创建动态模糊效果,可以使用javascript动态修改。

首先,我正在使用这个非常简单的svg过滤器:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="blur">
<feGaussianBlur stdDeviation="0" />
</filter>
</svg>

stdDeviation从0开始,我希望能够使用javascript更改它。我尝试了一些不同的东西,但我还没能完全解决它。

首先,(我应该注意到我使用的是jQuery)我试着简单地选择feGaussianBlur元素并修改它的属性:

$('feGaussianBlur').attr('stdDeviation',5);

这并没有像我预期的那样取代现有的属性,而是添加了另一个属性,留给我<feGaussianBlur stdDeviation="0" stdDeviation="5" /> 从HTML中删除原始stdDeviation使得在更改后只有一个属性,但它没有效果。

接下来,我尝试用新的内容替换过滤器的内容:

$('filter#blur').html('<feGaussianBlur stdDeviation="5" />');

这一次,它不仅没有成功改变,而且导致应用此滤镜的元素完全消失(我假设滤镜已损坏,或者某些东西)。

对于之前的两种情况,我甚至尝试重新应用过滤器的css声明。

我尝试DID工作的一件事是构建10个不同的过滤器,有10个不同的值,然后我不是用javascript更改SVG,而是简单地将css重新分配给不同的过滤器ID。说实话,这种方法似乎更合适......但最大的缺点是它不是非常通用,并且需要做很多工作来改变事物。另外,我更喜欢使用带小数位的值,这需要100个过滤器声明才能完成。

所以,我的问题是......是否有一种很好的方法可以使用javascript动态修改SVG过滤器(在我的情况下,具体是模糊过滤器)?如果存在,在语义和标准方面是否是一种可敬的方法?如果不出意外,我更愿意回到我的解决方案,即使用一些(我可以不带小数)过滤器并将它们交换掉,但我想首先探索我的选择。

或者,如果你没有解决方案,但至少可以向我解释为什么我的第一对夫妇尝试不起作用,请告诉我!我很好奇原因是什么。

2 个答案:

答案 0 :(得分:9)

使用普通DOM而不是jquery来做这个会更简单。将id移动到feGaussianBlur元素

<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter>
<feGaussianBlur id="blur" stdDeviation="0" />
</filter>
</svg>

然后

document.getElementById("blur").setAttribute("stdDeviation", "5");

或者

document.getElementById("blur").setStdDeviation(5, 5);

答案 1 :(得分:2)

这个问题很旧,但是值得回答。

使用SVG元素上的jQuery设置/获取属性可能不起作用的原因有两个:

1。字母大小写

jQuery在其attr()实现中具有以下代码:

if ( .... || !jQuery.isXMLDoc( elem ) ) {
   name = name.toLowerCase();

换句话说,它读取/设置属性stddeviation,而不是 stdDeviation

2。属性与属性

在旧的jQuery版本中,使用属性而不是属性。如果该属性不是简单的字符串值(例如"For an SVG element, className is not a string, but an instance of SVGAnimatedString"。例如There isn't really a stdDeviation property at all, but X and Y ones),则会导致失败。有关更多信息,请参见prop()attr()的文档。

那该怎么办?

这是xattr()的一种实现,它在attr()失败的地方起作用,因为它没有尝试变得聪明。使用它代替attr()

jQuery.fn.xattr = function(name, val) {
  if (val !== undefined) {
    this.each(function() {
      this.setAttribute(name, val);
    });
    return this;
  }
  else {
    if (this.length)
      return this[0].getAttribute(name);
  }
};
相关问题