在调查了所有可能创建轻量级和灵活的旋转器的方法后,我最终使用了非常出色的
因为CSS3
requestAnimationFrame
。它基本上与CSS3 animation
做的是一样的事情:执行计算并将结果交给浏览器,以便在屏幕重绘时(通常为60fps)同步重绘。虽然CSS3 transition
和 animation
适用于非常基本的用法,因为只有一个transitionend
事件,可能不会在某些情况下触发,但requestAnimationFrame
提供了完全控制,您可以完美地同步执行多个复杂的计算和屏幕重绘。
在HTML5 worker中执行此代码是否有意义?
CSS
i.spinner {position:relative;display:inline-block;margin:20px}
i.bar {display:block;position:absolute;top:0;left:50%;height:inherit}
i.bar i {display:block;width:100%;height:29%;background:#000}
i.bar:nth-child(2) {transform:rotate(45deg);-webkit-Transform:rotate(45deg);-moz-Transform:rotate(45deg);-ms-Transform:rotate(45deg)}
i.bar:nth-child(3) {transform:rotate(90deg);-webkit-Transform:rotate(90deg);-moz-Transform:rotate(90deg);-ms-Transform:rotate(90deg)}
i.bar:nth-child(4) {transform:rotate(135deg);-webkit-Transform:rotate(135deg);-moz-Transform:rotate(135deg);-ms-Transform:rotate(135deg)}
i.bar:nth-child(5) {transform:rotate(180deg);-webkit-Transform:rotate(180deg);-moz-Transform:rotate(180deg);-ms-Transform:rotate(180deg)}
i.bar:nth-child(6) {transform:rotate(225deg);-webkit-Transform:rotate(225deg);-moz-Transform:rotate(225deg);-ms-Transform:rotate(225deg)}
i.bar:nth-child(7) {transform:rotate(270deg);-webkit-Transform:rotate(270deg);-moz-Transform:rotate(270deg);-ms-Transform:rotate(270deg)}
i.bar:nth-child(8) {transform:rotate(315deg);-webkit-Transform:rotate(315deg);-moz-Transform:rotate(315deg);-ms-Transform:rotate(315deg)}
JS
function buildspinner(size, invert) {
var color = '#000',
spinner = document.createElement('i'),
bar = document.createElement('i'),
hand = document.createElement('i'),
opacitymap = [0.8, 0.2, 0.2, 0.2, 0.2, 0.5, 0.6, 0.7],
nodemap = [];
if (invert) {color = '#fff'};
spinner.className = 'spinner';
spinner.style.cssText = 'width:' + size + 'px;height:' + size + 'px';
bar.className = 'bar';
bar.style.cssText = 'width:' + (size / 9) + 'px;height:' + size + 'px;margin-left:' + (-size / 18) + 'px';
hand.style.cssText = 'border-radius:' + size + 'px;background:' + color;
bar.appendChild(hand);
for (var j = 0; j < 8; j++) {
var clone = bar.cloneNode(true);
clone.style.opacity = opacitymap[j];
spinner.appendChild(clone);
nodemap.push(clone)
}
document.body.appendChild(spinner);
requestAnimationFrame(function(timestamp) {animatespinner(timestamp, timestamp, 125, opacitymap, nodemap, 0)})
}
function animatespinner(starttime, timestamp, duration, opacitymap, nodemap, counter) {
var progress = (timestamp - starttime) / duration;
counter++;
if (counter % 3 == 0) {
for (var j = 0; j < 8; j++) {
var next = j - 1;
if (next < 0) {
next = 7
};
nodemap[j].style.opacity = (opacitymap[j] + (opacitymap[next] - opacitymap[j]) * progress)
}
}
if (progress < 1) {
requestAnimationFrame(function(timestamp) {animatespinner(starttime, timestamp, 125, opacitymap, nodemap, counter)})
} else {
var rotatearray = opacitymap.pop();
opacitymap.unshift(rotatearray);
requestAnimationFrame(function(timestamp) {animatespinner(timestamp, timestamp, 125, opacitymap, nodemap, 0)})
}
}
counter
变量用于节流。您希望动画平滑进行,但是要保持CPU使用率低。在这个例子中,我们每3帧更改一次不透明度,大大减少CPU开销,而不会对平滑度产生明显影响(在Quadcore 3GHz处理器上将CPU使用率从12%降至5%)。因为CSS3
animation
依赖于keyframes
,您必须为每个旋转手创建单独的关键帧,这会导致太多的计算。相同的Spinner使用CSS3 animation构建,结果CPU使用率达到30%。
演示