5

ゆっくり描きたかったポイントがたくさんあります。setTimeOutとこのチュートリアルの効果を試してみます。しかし、それほど成功することはありません。

関数は次のようになります

働き:

var myFunction = function(ctx, grid, points) {
                ctx.beginPath();
                ctx.moveTo(points[0].x, points[0].y);
                ctx.lineWidth = 2;
                ctx.strokeStyle = '#2068A8';
                ctx.fillStyle = '#2068A8';
                var count = 1;
                for (count = 1; count < points.length; count++) {
                    ctx.lineTo(points[count].x , points[count].y);
                }
                ctx.stroke();
            }

この関数の周りには他にも多くの描画関数がありますが、アニメーション化するのは1つだけです。

キャンバスで関数をゆっくり描画するにはどうすればよいですか?

4

2 に答える 2

10

これを行うには、頭のてっぺんから考えることができる2つの方法があります。1つは基本的にポイントを描画し、もう1つのポイントを描画する前に一定時間一時停止します。これが私が提供した最初の例です.2番目の方法では、現在のターゲットに部分的な線を描画します。これにより、描画の外観がはるかに滑らかになります。補足として、requestAnimationFrame両方の例で使用しているのは、あらゆるタイプのキャンバスアニメーションを実行するための推奨される方法です。

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = 400;
canvas.height = 200;

var points = [],
    currentPoint = 1,
    nextTime = new Date().getTime()+500,
    pace = 200;

// make some points
for (var i = 0; i < 50; i++) {
    points.push({
        x: i * (canvas.width/50),
        y: 100+Math.sin(i) * 10
    });
}

function draw() {

    if(new Date().getTime() > nextTime){
        nextTime = new Date().getTime() + pace;

        currentPoint++;
        if(currentPoint > points.length){
            currentPoint = 0;
        }
    }
    ctx.clearRect(0,0,canvas.width, canvas.height);
    ctx.beginPath();
    ctx.moveTo(points[0].x, points[0].y);
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#2068A8';
    ctx.fillStyle = '#2068A8';
    for (var p = 1, plen = currentPoint; p < plen; p++) {
        ctx.lineTo(points[p].x, points[p].y);
    }
    ctx.stroke();

    requestAnimFrame(draw);
}

draw();

ライブデモ

少し途切れがちな場合は、次の手順を実行して、より滑らかな線を描画できます。

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = 400;
canvas.height = 200;

var points = [],
    currentPoint = 1,
    speed = 2,
    targetX = 0,
    targetY = 0,
    x = 0,
    y = 0;

// make some points
for (var i = 0; i < 50; i++) {
    points.push({
        x: i * (canvas.width/50),
        y: 100+Math.sin(i) * 10
    });
}

// set the initial target and starting point
targetX = points[1].x;
targetY = points[1].y;
x = points[0].x;
y = points[0].y;

function draw() {
    var tx = targetX - x,
        ty = targetY - y,
        dist = Math.sqrt(tx*tx+ty*ty),
        velX = (tx/dist)*speed,
        velY = (ty/dist)*speed;

        x += velX
        y += velY;

    if(dist < 1){
        currentPoint++;

        if(currentPoint >= points.length){
            currentPoint = 1;
            x = points[0].x;
            y = points[0].y;
        }

        targetX = points[currentPoint].x;
        targetY = points[currentPoint].y;
    }

    ctx.clearRect(0,0,canvas.width, canvas.height);
    ctx.beginPath();
    ctx.moveTo(points[0].x, points[0].y);
    ctx.lineWidth = 2;
    ctx.strokeStyle = '#2068A8';
    ctx.fillStyle = '#2068A8';

    for (var p = 0, plen = currentPoint-1; p < plen; p++) {
        ctx.lineTo(points[p].x, points[p].y);
    }
    ctx.lineTo(x, y);    
    ctx.stroke();

    requestAnimFrame(draw);
}

draw();

ライブデモ

于 2013-01-23T18:41:04.093 に答える
0

これらの例をありがとう、Loktar!これは、Loktarが投稿した回答の上記の2番目の例に対するコメントであるはずですが、サインアップしたばかりで「評判」が十分でないため、コメントできません。

上記の2番目のデモを試しましたが、速度を遅くすると、新しい線分が、開始するはずのポイントの前のポイントから成長し始めることがわかります。これは私がそれを機能させるためにそれを微調整した方法です:

次の行を変更しました。

ctx.lineTo(points[p].x, points[p].y); 
// => 
ctx.lineTo(points[p+1].x, points[p+1].y);

これで、結果は非常にスムーズに見えます。Loktarの投稿はほぼ完璧だったので、コメントしています。微調整が必​​要な細部が1つだけあるという理由だけで、人々が彼の投稿を見逃さないように願っています。もう一度ありがとう、Loktar!

于 2020-12-11T07:38:00.230 に答える