使用CSS过渡来动画化动态SVG属性

6
我正在尝试使用JavaScript和CSS过渡来动画化各种SVG形状的属性。
例如:
HTML:
<svg width="400" height="400">
    <circle id="circle" cx="200" cy="200" r="15" stroke="none" fill="blue" />
    <rect id="rect" x="100" y="100" height="30" width="30" stroke="none" fill="red" />
</svg>
<button id="button">Animate</button>

JavaScript:
document.getElementById("button").addEventListener("click", function () {
    var circle = document.getElementById("circle");
    var cx = 50 + Math.round(Math.random() * 300);
    var cy = 50 + Math.round(Math.random() * 300);
    // using 'setAttribute'
    circle.setAttribute("cx", cx);
    circle.setAttribute("cy", cy);

    var rect = document.getElementById("rect");
    var x = 50 + Math.round(Math.random() * 300);
    var y = 50 + Math.round(Math.random() * 300);
    // using 'setAttributeNS'
    rect.setAttributeNS(null, "x", x);
    rect.setAttributeNS(null, "y", y);
}, false);

CSS:
circle, rect {
    -webkit-transition: all 0.7s ease-in-out;
    -moz-transition: all 0.7s ease-in-out;
    transition: all 0.7s ease-in-out;
}

这里有一个完整的JSFiddle:http://jsfiddle.net/kkhvzyjq/ 在Chrome中,这个代码可以很好地运行。然而,在Safari和Firefox中,虽然新的属性得到应用(形状移动),但没有过渡/动画。
是否有一种方法可以在这些浏览器中实现这个效果?

用SMIL完成整个事情。 - Robert Longson
@RobertLongson - 我尝试过了,但无法使其工作。具体来说,如果我向一个圆形添加两个“animation”元素,并使用JavaScript修改“from”和“to”属性,则不起作用(即每次更改属性时动画不会重新开始)。我还尝试删除旧的动画元素并添加具有新“from”和“to”属性的新元素,但也不起作用。换句话说,只有在作者时间添加SMIL动画时才能使其工作,而不能在运行时动态修改。 - mattstuehler
你不会这样做的,你只需要在点击时开始动画。 - Robert Longson
1个回答

2

Safari和Firefox不会对位置属性的更改进行过渡。

transform CSS属性在这方面效果更好:

http://jsfiddle.net/kkhvzyjq/7/

document.getElementById("button").addEventListener("click", function() {
  var circle = document.getElementById("circle");
  var cx = 50 + Math.round(Math.random() * 300);
  var cy = 50 + Math.round(Math.random() * 300);
  circle.style.transform = "translate(" + cx + "px," + cy + "px)";

  var rect = document.getElementById("rect");
  var x = 50 + Math.round(Math.random() * 300);
  var y = 50 + Math.round(Math.random() * 300);
  rect.style.transform = "translate(" + x + "px," + y + "px)";
}, false);
circle,
rect {
  -webkit-transition: all 0.7s ease-in-out;
  -moz-transition: all 0.7s ease-in-out;
  transition: all 0.7s ease-in-out;
}
<svg width="400" height="400">
  <circle id="circle" r="10" stroke="none" fill="blue" style="transform:translate(200px,200px);" />
  <rect id="rect" height="10" width="10" stroke="none" fill="red" style="transform:translate(100px,100px);" />
</svg>
<button id="button">Animate</button>


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