我正在尝试使用给定参数rotateX和rotateY刷新动画:
$(document).ready(function() {
var svg = document.getElementById("DC");
var x = 10;
var y = 0;
for (j = 0; j<8 ; j++) {
svg.setAttribute('style', 'transform: perspective(30em) rotateX(' + x + 'deg) rotateY(' + y + 'deg) scale(0.6, 0.6); perspective: 30em;');
x = x + 10;
}
});
但它没有用。如何顺利刷新动画?
以下是HTML代码:
<body><svg id="DC" version="1.0" viewBox="0 0 500 408" class="sim" x="0px" y="0px" width="100%" height="100%" style="transform: perspective(30em) rotateX(0deg) rotateY(0deg) scale(0.6, 0.6); perspective: 30em;"><style></body>
答案 0 :(得分:2)
问题在于,每次执行动画时,都需要为浏览器提供绘制更改的机会。你不是那样做的。您的for
循环只是不断更改style
属性,并且永远不会将控制权返回给浏览器。它永远没有机会更新页面。
有几种方法可以解决这个问题。曾几何时,通常使用window.setTimeout()
调用返回浏览器并让它调用您的代码以更新动画。现在,首选的方式是requestAnimationFrame()
电话。
var svg = document.getElementById("DC");
var x = 10;
var y = 0;
function step(timestamp)
{
svg.setAttribute('style', 'transform: perspective(30em) rotateX(' + x + 'deg) rotateY(' + y + 'deg) scale(0.6, 0.6); perspective: 30em;');
x = x + 10;
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
svg {
background-color: red;
}
<body>
<svg id="DC" version="1.0" viewBox="0 0 500 408" class="sim" x="0px" y="0px" width="100%" height="100%" style="transform: perspective(30em) rotateX(0deg) rotateY(0deg) scale(0.6, 0.6); perspective: 30em;"></svg>
</body>
此处动画的每个步骤都在step()
函数中计算。然后,在您退回此功能之前,您必须再次致电requestAnimation()
,要求其再次致电step()
。
最后的调用是从头开始动画。
答案 1 :(得分:1)
一个简单的解决方案是使用CSS过渡 这样您就可以轻松定义速度,甚至可以使用定时功能。
var svg = document.getElementById("DC");
function update(x)
{
svg.setAttribute('style', 'transform: perspective(30em) rotateX('+x+'deg) rotateY(0deg) scale(0.6, 0.6); perspective: 30em;');
}
svg.parentNode.offsetWidth;
update(80);
num.onchange = e => update(num.value);
&#13;
svg {
background-color: red;
transition: transform 2s ease-out;
}
&#13;
<label>x rotation<input type="number" value="80" id="num"></label>
<svg id="DC" version="1.0" viewBox="0 0 500 408" class="sim" x="0px" y="0px" width="100%" height="100%" style="transform: perspective(30em) rotateX(0deg) rotateY(0deg) scale(0.6, 0.6); perspective: 30em;"></svg>
&#13;
如果您需要循环播放,可以收听transitionend
事件:
var svg = document.getElementById("DC");
x = 0;
function loop()
{
x += 180;
svg.setAttribute('style', 'transform: perspective(30em) rotateX('+x+'deg) rotateY(0deg) scale(0.6, 0.6); perspective: 30em;');
}
svg.addEventListener('transitionend', loop);
svg.parentNode.offsetWidth;
loop();
&#13;
svg {
background-color: red;
transition: transform .5s linear;
}
&#13;
<svg id="DC" version="1.0" viewBox="0 0 500 408" class="sim" x="0px" y="0px" width="100%" height="100%" style="transform: perspective(30em) rotateX(0deg) rotateY(0deg) scale(0.6, 0.6); perspective: 30em;"></svg>
&#13;
答案 2 :(得分:0)
尝试一些建议: 1.使用绝对定位和静态维度隔离在DOM中转换的元素 2.设置css属性will-change: transform;
<body>
<div class="viewport" style="position: relative; width: 500px; height: 408px;">
<svg id="DC" version="1.0" viewBox="0 0 500 408" class="sim" width="500px" height="408px" style="transform: perspective(30em) rotateX(0deg) rotateY(0deg) scale(0.6, 0.6); transform-origin: 0px 0px 0px; will-change: transform;">
</svg>
</div>
3.使用转换计时功能,例如jquery.animate而不是for循环,它指示浏览器立即渲染所有帧。我不确定jquery可以为复杂变换设置动画,但是D3确定可以。您也可以这样做以将动画放入动画队列,但仍然可以使用具有计时功能的库:
function animate(frames,x) {
if(frames > 0) {
svg.setAttribute('style', 'transform: perspective(30em) rotateX(' + x + 'deg) rotateY(' + y + 'deg) scale(0.6, 0.6); perspective: 30em;');
requestAnimationFrame(function() { animate(--frames,x+= 10); });
}
return;
}