【问题标题】:Dynamically modifying an SVG filter with javascript使用 javascript 动态修改 SVG 过滤器
【发布时间】:2013-10-08 09:17:08
【问题描述】:

我正在尝试创建动态模糊效果,可以使用 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);

这并没有像我预期的那样替换已经存在的属性,而是添加了另一个属性,给我留下了&lt;feGaussianBlur stdDeviation="0" stdDeviation="5" /&gt; 从HTML中去掉原来的stdDeviation使得修改后只有一个属性,但是没有效果。

接下来,我尝试简单地将过滤器的内容替换为新的:

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

这一次,它不仅没有成功改变,而且还导致应用此过滤器的元素完全消失(我假设过滤器已损坏,或类似情况)。

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

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

所以,我的问题是... 有没有一种使用 javascript 动态修改 SVG 过滤器(在我的情况下,特别是模糊过滤器)的好方法?如果有,就语义和标准而言,这是一种值得尊敬的方法吗?如果不出意外,我非常愿意退回到使用一些(我可以不用小数)过滤器并将它们换掉的解决方案,但我想先探索我的选择。

或者,如果您没有解决方案,但至少可以向我解释为什么我的前几次尝试没有成功,请告诉我!我很好奇是什么原因。

【问题讨论】:

    标签: javascript svg svg-filters


    【解决方案1】:

    使用普通 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);
    

    【讨论】:

    • 效果很好!我很好奇为什么 jQuery 似乎不能做完全相同的事情?无论如何,它本质上不是归结为这个吗?
    • 疯狂猜测 - 我猜这是因为您已将过滤器元素放在 svg 命名空间中。如果你不使用命名空间声明,我猜它会起作用
    • 这在 IE 10+ 中不起作用。您需要在 IE 10 或更高版本中使用 stdDeviationX 和 stdDeviationY。 msdn.microsoft.com/en-us/library/hh773246(v=vs.85).aspx
    【解决方案2】:

    这个问题很老了,但值得回答。

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

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

    【讨论】:

    • 谢谢,很高兴最终得到“为什么”的答案,而不仅仅是解决方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-12
    • 2013-12-17
    • 2023-01-29
    • 1970-01-01
    • 2023-01-19
    相关资源
    最近更新 更多