我有一个转换动画,我想触发一个SVG元素的宽度在一个组元素。动画似乎只在Chrome浏览器上工作。
<!-- 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>.grow {
-webkit-transition: 1.5s;
-moz-transition: 1.5s;
-o-transition: 1.5s;
transition: 3s;
width: 10px;
}(() => {
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组中为特定元素工作吗?
发布于 2020-02-06 10:27:45
总之,解决办法是回到SMIL SVG动画,而不是使用CSS。
请看我最初问题的改编版小提琴。
<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>(() => {
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);
})();发布于 2020-02-05 15:46:01
用途:
元素从SVG文档中获取节点,并在其他地方复制它们。- mdn
因此,使用use是不需要的,因为您没有复制它。
(() => {
setTimeout(() => {
const rect1 = document.getElementById('rect-1');
rect1.classList.add('grow');
const rect2 = document.getElementById('rect-2');
rect2.classList.add('grow');
}, 1000);
})();.grow {
-webkit-transition: 1.5s;
-moz-transition: 1.5s;
-o-transition: 1.5s;
transition: width 3s;
width: 10px;
}<!-- 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元素中使用。这是一个众所周知的问题。关于堆栈溢出有多个未回答的问题,例如这一个。
<!-- 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>中。
<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>
发布于 2020-02-06 09:56:18
在圆圈内嵌套动画标签怎么样?
<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>
https://stackoverflow.com/questions/60078402
复制相似问题