首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SVG <use>上的动画不适用于FireFox & Safari

SVG <use>上的动画不适用于FireFox & Safari
EN

Stack Overflow用户
提问于 2020-02-05 14:48:57
回答 3查看 932关注 0票数 2

我有一个转换动画,我想触发一个SVG元素的宽度在一个组元素。动画似乎只在Chrome浏览器上工作。

代码语言:javascript
复制
<!-- works -->
<svg width="400" height="100">
  <rect id="rect-1" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>

<!-- only works in Chrome -->
<svg width="400" height="400">
  <defs>
    <g id="my-rect">
      <rect id="rect-2" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
    </g>
  </defs>

  <use xlink:href="#my-rect" y="0"/>
  <use xlink:href="#my-rect" y="110"/>
</svg>
代码语言:javascript
复制
.grow {
  -webkit-transition: 1.5s;
  -moz-transition: 1.5s;
  -o-transition: 1.5s;
  transition: 3s;
  width: 10px;
}
代码语言:javascript
复制
(() => {
  setTimeout(() => {
    const rect1 = document.getElementById('rect-1');
    rect1.classList.add('grow');

    const rect2 = document.getElementById('rect-2');
    rect2.classList.add('grow');
  }, 1000);
})();

若要复制此小提琴,请在Safari或Firefox中打开。您将看到第二个矩形的转换不能正常工作。

有什么解决办法可以让转换动画在SVG组中为特定元素工作吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-02-06 10:27:45

总之,解决办法是回到SMIL SVG动画,而不是使用CSS。

请看我最初问题的改编版小提琴

代码语言:javascript
复制
<svg width="400" height="100">
  <rect id="rect-1" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>

<svg width="400" height="400">
  <defs>
    <g id="my-rect">
      <rect id="g-rect" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)"/>
    </g>
  </defs>

  <use xlink:href="#my-rect" y="0"/>
  <use xlink:href="#my-rect" y="110"/>
</svg>
代码语言:javascript
复制
(() => {
  setTimeout(() => {
    const rect1 = document.getElementById('rect-1');
    rect1.classList.add('grow');

    const groupRect = document.getElementById('g-rect');

    const growAnimation = document.createElementNS('http://www.w3.org/2000/svg', 'animate')
    growAnimation.setAttribute('attributeName', 'width');
    growAnimation.setAttribute('from', '400');
    growAnimation.setAttribute('to', '10');
    growAnimation.setAttribute('dur', '3s');
    growAnimation.setAttribute('fill', 'freeze');
    growAnimation.setAttribute('begin', 'indefinite');
    groupRect.appendChild(growAnimation);

    growAnimation.beginElement();
  }, 1000);
})();
票数 0
EN

Stack Overflow用户

发布于 2020-02-05 15:46:01

用途:

元素从SVG文档中获取节点,并在其他地方复制它们。- mdn

因此,使用use是不需要的,因为您没有复制它。

代码语言:javascript
复制
(() => {
  setTimeout(() => {
    const rect1 = document.getElementById('rect-1');
    rect1.classList.add('grow');

    const rect2 = document.getElementById('rect-2');
    rect2.classList.add('grow');

  }, 1000);
})();
代码语言:javascript
复制
.grow {
  -webkit-transition: 1.5s;
  -moz-transition: 1.5s;
  -o-transition: 1.5s;
  transition: width 3s;
  width: 10px;
}
代码语言:javascript
复制
<!-- works -->
<svg width="400" height="100">
  <rect id="rect-1" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>

<svg width="400" height="100">
  <rect id="rect-2" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>

更新1

当元素被复制时,即使SVG <animate>也不能在FireFox中工作。不过,如果不使用,则在refrensed元素中使用。这是一个众所周知的问题。关于堆栈溢出有多个未回答的问题,例如这一个

代码语言:javascript
复制
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use -->

<svg viewBox="0 0 30 10" xmlns="http://www.w3.org/2000/svg">
  <circle id="myCircle" cx="5" cy="5" r="4" stroke="blue"/>
  <use href="#myCircle" x="10" fill="blue"/>
  <use href="#myCircle" x="20" fill="white" stroke="red"/>
  <!--
stroke="red" will be ignored here, as stroke was already set on myCircle. 
Most attributes (except for x, y, width, height and (xlink:)href)
do not override those set in the ancestor.
That's why the circles have different x positions, but the same stroke value.
  -->
  
      <animate 
           xlink:href="#myCircle"
           attributeName="r"
           from="4"
           to="2" 
           dur="5s"
           begin="0s"
           repeatCount="1"
           fill="freeze" 
           id="circ-anim"/>
           
           
</svg>

更新2

引用元素上的动画将导致实例也被动画化。使用- w3

根据文档,如果您动画化了折射元素(`my环状),那么它的所有副本也应该是不正确的。所以我想,它在Firefox & Safari中不起作用是一个错误。

更新3-解决办法

使用svg <animate>标记并将其封装在<rect>中。

代码语言:javascript
复制
<svg width="400" height="400">
  <defs>
    <g id="my-rect">
      <rect id="rect-2" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
        <animate 
                 attributeName="width"
                 from="400"
                 to="10" 
                 dur="3s"
                 begin="1s"
                 repeatCount="1"
                 fill="freeze" 
                 id="rect-2"/>

      </rect>
    </g>
  </defs>

  <use xlink:href="#my-rect" y="0"/>
  <use xlink:href="#my-rect" y="110"/>
</svg>

票数 2
EN

Stack Overflow用户

发布于 2020-02-06 09:56:18

在圆圈内嵌套动画标签怎么样?

代码语言:javascript
复制
<svg width="400" height="350">
    <rect id="my-rect" width="400" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)">
        <animate 
               attributeName="width"
               from="0"
               to="400" 
               dur="5s"
               begin="0s"
               repeatCount="1"
               fill="freeze" 
               id="rect-anim"/>
    </rect>

    <use xlink:href="#my-rect" y="110"/>
    <use xlink:href="#my-rect" y="220"/>
     
</svg>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60078402

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档