我有一个任务是在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);
虽然它正在运行,但我担心是否会出现任何性能损失。如果有更好的解决方案。欢迎任何建议。
答案 0 :(得分: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);
答案 1 :(得分: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);
此设计更改还允许您在不改变间隔长度的情况下即时更改旋转速度。您要更改的是++angle
到angle + w
,其中w
是角速度。
不幸的是,您不能使用requestAnimationFrame
而不是间隔。那好吧。它不是世界末日。
编辑: 令我烦恼的是,该功能在很大程度上依赖于全局变量。所以,这是一个稍微好一点的#34;虽然更重,但这样做的方式。
/** 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);