[英]Canvas is drawing with inconsistent speed (requestAnimationFrame)
[英]Canvas rotate circle in certain speed using RequestAnimationFrame
我在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秒內旋轉一次。
另一件事是,角度,它會越來越多,經過很長一段時間它會崩潰,因為可變的最大量將超過,所以我如何制作無縫旋轉帽?
謝謝你的閱讀!
有些數學運算可讓您在動畫循環內以指定的速度繪制形狀。
演示: 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;
當前旋轉角度是一個完整的圓圈(Math.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();
只需使用time-diff方法將步驟鎖定為新舊時間之間的差異:
從獲取當前時間開始:
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。
更新一分鍾我認為修改角度不適用於浮點數,但你可以(必須仔細檢查)所以代碼更新。
要在設備之間保持一致的行為,您需要自己處理時間,並根據良好的舊公式更新位置/旋轉/ ...:position = speed * time;
這樣做的第二個好處是,在幀丟失的情況下,移動仍將保持相同的速度,因此它將不太明顯。
小提琴在這里: 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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.