2017-07-19 194 views
2

我试图刷新了动画与给定参数rotateX和旋转Y:平滑SVG动画

$(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> 

+1

你为什么不尝试使用使用GreenSock为这:https://greensock.com/另外我不确定是一个非常好的主意,为SVG标签设置动画效果,更好se组或其他显示元素。 – Rodrigo

回答

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可以制作复杂变换的动画,但确实可以。你也可以这样做是为了把你的动画转换为动画队列中,虽然使用的图书馆,具有定时功能仍优选:

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; 
} 
+0

感谢您的建议。如果我想每次移动鼠标时设置X值并增加10,我该怎么做?该动画不能使用该功能。 – user3736228

+0

然后,您应该监听mousemove事件,并将您的动画代码放在那里。一旦你得到一个mousemove事件,requestAnimationFrame(function(){animate(...);});所有这些使用框架更容易 - 我喜欢[D3](https://d3js.org/),它拥有大量容易复制的示例。 –

1

的问题是,每次你一步动画的时候,你需要给浏览器一个绘制变化的机会。你没有这样做。您的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()

最后的调用是从开始时的动画开始。

0

一个简单的解决方案是使用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);
svg { 
 
    background-color: red; 
 
    transition: transform 2s ease-out; 
 
}
<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>

如果你需要它循环,你可以听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();
svg { 
 
    background-color: red; 
 
    transition: transform .5s linear; 
 
}
<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>