1

私は、javascript と canvas を使用する比較的初心者です。私がこれまでに行ったことを説明しようと思います。外部スタイル シートがあり、canvas 要素の背景を設定しました (これは、地平線に向かって続く道路の背景画像です)。次に、この最初の関数 (drawRoad()) を作成して、道路の中央に沿って白い帯を描き、道路とともに地平線までたどり着きます。次に、この白いストリップにスペースを挿入する別の関数 (roadLines()) を作成しました。ここまでの様子に満足しています。

私が今やりたいことは、... drawRoad()、次にroadLines()、次にキャンバスをクリアし、次にdrawRoad()をもう一度実行し、次にroadLines()の位置を変更して、この関数を再度呼び出すことです. roadLines() の位置を垂直方向に下に移動して、道路を下っていくような効果が得られるようにします。(これが理にかなっているといいのですが?)これは正しい方法ですか?それとも、私が完全に見落としているより簡単な方法はありますか?

どんな提案でも大歓迎です。以下は私がこれまでに行ったことです。また、関数 animate() は一番下にありますが、drawRoad() を呼び出してから、roadLines() を呼び出すだけです。

window.requestAnimFrame = (function (callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function (callback) {
    window.setTimeout(callback, 1);
};})();

// set function that draws in the canvas
function drawRoad() {
    var myCanvas = document.getElementById("myCanvas");
    var ctx = myCanvas.getContext("2d");
    ctx.clearRect(0, 0, myCanvas.width, myCanvas.height);
    ctx.beginPath();
    ctx.moveTo(471, 199);
    ctx.lineTo(467, 600);
    ctx.lineTo(475, 600);
    ctx.closePath();
    ctx.fillStyle = "rgb(255, 255, 255)";
    ctx.fill();
    ctx.lineWidth = 1;
    ctx.strokeStyle = "rgb(255, 255, 255)";
}

//set variables and function/for loop that creates the spacing/intervals for road markings and movement
function roadLines() {
var interval = 1;
var space = 1;
var myCanvas = document.getElementById("myCanvas");
var ctx = myCanvas.getContext("2d");
for (var roadLine = 199; roadLine < 600; roadLine = roadLine + interval) {
    interval = (interval * 1.1);
    space = (space * 1.05);
    ctx.clearRect(450, roadLine, 40, space);
    }
}

function animate() {
    drawRoad();
    roadLines();
}
4

1 に答える 1

2

最初に行う必要があるのは、実際にアニメーション ループをループさせることです。現状では、2 つの関数を 1 回呼び出してから終了するだけなので、最初の調整は次のようになります。

function animate() {
    drawRoad();
    roadLines();

    requestAnimationFrame(animate); /// enable a loop
}

(ps: ポリフィルの名前を からrequestAnimFrameに変更してrequestAnimationFrameください。以下のデモ リンクを参照してください)。

もちろん、アニメーション ループも開始する必要があるため、どこかでグローバル スコープから呼び出すだけです。

animate();

次に確認する必要があるのは、アニメーションが表示されるように線が動いていることです。

画面ジオメトリにバインドされていないスケーリングがあるため、コードがそのままではすぐに機能しません。

これにより、オフセットをリセットしてループしようとすると行が「ジャンプ」するか、オフセットをリセットしないことを選択した場合、ループの実行時間が長くなるほど行のサイズが大きくなります。

そのため、線の引き方や妥協点を再考する必要があります。

妥協点として、オフセット ループをリセットする「スイート スポット」値を見つける必要があります。ラインの動きが遅いほど、小さな「ジャンプ」が目立ちます。

ただし、線を滑らかに見せるには、単純な 3D 投影 (または、既に持っているが表示にバインドされているものに似た 2.5D 疑似 3D) を実装する必要があります。

これは、オフセットを使用して線がアニメーション化されたオンライン デモです。オフセット制限のスイートスポットを見つけることができるように、下部にスライダーを追加しました。それを試して、どのように機能するかを確認してください。線の 3D プロジェクションは実装せず、既存のものを使用しましたが、投稿に基づいて、ここで基本を理解することが最初のステップになると感じています。

于 2013-10-07T19:51:40.410 に答える