这种在IE9中旋转SVG的方法是否会导致性能下降?

问题描述 投票:1回答:2

我有一个任务是在IE9中进行SVG旋转。

我找到了使它旋转的FakeSmile库,但是在整个DOM准备好之后,这不是我想要的行为。我尝试使用JavaScript手动完成并以此代码结束:

//init an array with values from 0 to 360 for degrees 
var degrees = [];
for(var i = 0; i <= 360; i++) {
    degress.push(i);
}
// function to rotate it, after it's fetched from the DOM
var rotate = function() {
    var deg = degrees.shift();
    element.style.msTransform = "rotate(" + deg + "deg)";
    degrees.push(deg);         
}
setInterval(rotate, 7);

虽然它正在运行,但我担心是否会出现任何性能损失。如果有更好的解决方案。欢迎任何建议。

javascript animation svg
2个回答
1
投票

创建者功能和有组织的对象将是一个良好的开端。请记住,如果可以避免,则不应污染全局命名空间。

同时取消反弹请求和动画。每个7毫秒的请求是在60fps屏幕上每帧两个请求(最常见),并且不需要计算和丢弃用户从未看到的帧。

在我的例子中,我使用requestAnimationFrame因为它将与屏幕刷新同步。在每个请求我检查手柄是否已经绘制一个框架,如果不是我安排框架绘图。

请注意,您仍然可以每7毫秒设置一次JavaScript变量。只是DOM的速度变慢了。

编辑1 - 在IE9中没有requestAnimationFrame

我对requestAnimationFrame的错误,但是反弹仍然是一个好主意。通过去抖动,有几个因素可以请求更改,它仍然只会在相关时呈现。

我已经用requestAnimationFrame取代了setTimeout(.... 1000/60)接近60 fps的动画。

function createRotator(element) {
  var rotator;
  rotator = {
    degrees: 0,
    element: element,
    eventHandle: false,
    rotate: function rotate() {
      rotator.degrees = (rotator.degrees + 1) % 360;
      if (rotator.eventHandle === false)
        rotator.eventHandle = setTimeout(function() {
          rotator.element.style.transform = "rotate(" + rotator.degrees + "deg)";
          rotator.element.style.msTransform = "rotate(" + rotator.degrees + "deg)";
          rotator.eventHandle = false;
        }, 1000 / 60);
    }
  };
  return rotator;
}
//TEST
var nodes = 0;
var handle;
handle = setInterval(function() {
  nodes++;
  if (nodes > 10) {
    clearInterval(handle);
  }
  var testNode = document.body.appendChild(document.createElement("p"));
  testNode.innerHTML = "Hello dear World!";
  testNode.style.width = "115px";
  testNode.style.cssFloat = "left";
  testNode.style.marginTop = "100px";
  var rotator = createRotator(testNode);
  setInterval(rotator.rotate, 3);
}, 1000 / 4);

0
投票

是的,使用IE9,你在CSS动画上运气不佳。我唯一的建议是内存优化

//init a variable to store the current angle
let angle = 0;

// function to rotate it
function rotate() {
    angle = (++angle)%360;
    element.style.msTransform = "rotate(" + angle+ "deg)";      
}
setInterval(rotate, 7);

此设计更改还允许您在不改变间隔长度的情况下即时更改旋转速度。所有你要改变的是++angleangle + w,其中w是角速度。

同样不幸的是,你不能使用requestAnimationFrame而不是间隔。那好吧。这不是世界末日。

编辑:我觉得这个功能在很大程度上依赖于全局变量。所以,这是一个稍微“更好”但更重的方式。

/** Takes in an element, an angular velocity, and an interval, and makes the element spin in IE9
PARAMS:
    element  : Element - The element we are spinning
    da       : Number  - The angular velocity in degrees per interval
    interval : Number  - The number of milliseconds per interval
RETURNS:
    Number - The ID of the interval that is created
**/
function makeRotate(element, da, interval){
    // Variable to store angle
    let a = 0;

    // If da isn't provided, make it 1
    da = da || 1;

    // If interval isn't provided, make it 7
    interval = interval || 7;

    // Get the ID and make the interval
    let id = window.setInterval(() => {

        // Increment the angle by the angular velocity, but wrap around 360
        a = (a + da)%360;

        // Apply the transform to the element
        element.style.msTransform = "rotate(" + a + "deg)";      
    }, interval);

    // Return the ID of the interval
    return id;
}
const intervalId = makeRotate(element, 1, 7);

此外,我确保返回间隔ID,因为能够取消那些吸盘总是很方便! window.clearInterval(intervalId);

© www.soinside.com 2019 - 2024. All rights reserved.