簡體   English   中英

Canvas使用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方法將步驟鎖定為新舊時間之間的差異:

DEMO

從獲取當前時間開始:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM