我在JSFiddle中制作了一个快速简单的解决方案,以便更好更快地解释:
var Canvas = document.getElementById("canvas");
var ctx = Canvas.getContext("2d");
var startAngle = (2*Math.PI);
var endAngle = (Math.PI*1.5);
var currentAngle = 0;
var raf = window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame;
function Update(){
//Clears
ctx.clearRect(0,0,Canvas.width,Canvas.height);
//Drawing
ctx.beginPath();
ctx.arc(40, 40, 30, startAngle + currentAngle, endAngle + currentAngle, false);
ctx.strokeStyle = "orange";
ctx.lineWidth = 11.0;
ctx.stroke();
currentAngle += 0.02;
document.getElementById("angle").innerHTML=currentAngle;
raf(Update);
}
raf(Update);
http://jsfiddle.net/YoungDeveloper/YVEhE/3/
当浏览器选择fps时,如何独立于帧速旋转环。因为目前,如果速度为30fps,它的旋转速度会较慢,但如果速度为60fps,因为每次调用都会增加旋转量。
正如我从几个线程中了解到的,这与getTime有关,我真的试过了,但没能完成,我需要在10秒内旋转一次。
另一件事是,角度会越来越大,长时间后它会崩溃,因为会超过可变的最大值,那么我该如何制作无缝旋转帽呢?
感谢您的阅读!
只需使用时间差异方法即可将步骤锁定到新旧时间之间的差异:
演示
从获取当前时间开始:
var oldTime = getTime();
/// for convenience later
function getTime() {
return (new Date()).getTime();
}
然后在你的循环中:
function Update(){
var newTime = getTime(), /// get new time
diff = newTime - oldTime; /// calc diff between old and new time
oldTime = newTime; /// update old time
...
currentAngle += diff * 0.001; /// use diff to calc angle step
/// reset angle
currentAngle %= 2 * Math.PI;
raf(Update);
}
使用此方法将动画绑定到时间而不是FPS。
更新有一分钟我以为用浮动来调整角度不起作用,但你可以(必须仔细检查),所以代码更新了。
一些数学方法可以让你在动画循环中以指定的速度绘制形状
演示:http://jsfiddle.net/m1erickson/9Z8pG/
声明一个startTime。
var startTime=Date.now();
声明360度旋转(10秒==10000ms)的时间长度
var cycleTime=1000*10; // 1000ms X 10 seconds
在每个动画帧内
使用模数数学将当前时间划分为10000ms周期。
var elapsed=Date.now()-startTime;
var elapsedCycle=elapsed%cycleTime;
在每个动画帧中,计算当前时间经过当前周期的百分比。
var elapsedCyclePercent=elapsedCycle/cycleTime;
当前旋转角度是一个完整的圆(数学PI*2)X百分比。
var radianRotation=Math.PI*2 * elapsedCyclePercent;
以帧的当前旋转角度重新绘制对象:
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.beginPath();
ctx.arc(40, 40, 30, -Math.PI/2, -Math.PI/2+radianRotation, false);
ctx.strokeStyle = "orange";
ctx.lineWidth = 11.0;
ctx.stroke();
要在设备之间保持一致的行为,您需要自己处理时间,并更新位置/旋转/。。。基于古老的好公式:位置=速度*时间
这样做的第二个好处是,在帧下降的情况下,移动仍将保持相同的速度,因此不会那么明显。
小提琴在这里:http://jsfiddle.net/gamealchemist/YVEhE/6/
在Javascript中,时间通常以毫秒为单位,因此速度将以弧度/毫秒为单位
这个公式可能会让事情变得更容易:
var turnsPerSecond = 3;
var speed = turnsPerSecond * 2 * Math.PI / 1000; // in radian per millisecond
然后要更新你的旋转,只需计算自更新功能开始时的最后一帧(dt)以来经过的时间,并执行:
currentAngle += speed * dt ;
而不是添加一个常数。
为了避免角度溢出或精度损失(这将在相当长的一段时间后发生…),请使用%运算符:
currentAngle = currentAngle % ( 2 * Math.PI) ;
function Update() {
var callTime = perfNow();
var dt = callTime - lastUpdateTime;
lastUpdateTime = callTime;
raf(Update);
//Clears
ctx.clearRect(0, 0, Canvas.width, Canvas.height);
//Drawing
ctx.beginPath();
ctx.arc(40, 40, 30, startAngle + currentAngle, endAngle + currentAngle, false);
ctx.strokeStyle = "orange";
ctx.lineWidth = 11.0;
ctx.stroke();
currentAngle += (speed * dt);
currentAngle = currentAngle % (2 * Math.PI);
angleDisplay.innerHTML = currentAngle;
}