web-dev-qa-db-ja.com

キャンバス:座標を変更せずに描画をキャンバスサイズに合わせる

キャンバスにフラクタルを動的に描画しているとしましょう。フラクタルがどのくらいの大きさになるかわからないので、ある時点で、そこにフラクタルが収まるようにキャンバスをスケーリング(ズームアウト)する必要があります。

どうすればよいですか?スケーリング方法:

  1. 適切に、それが私たちが持っている図面に完全に合うように、そして
  2. 座標が同じままで、フラクタル計算でスケール値を使用する必要がないようにします(つまり、可能であればreturn xではなくreturn x * scaleを使用します)。
  3. フラクタルがすべての方向に成長し、負の値がある場合はどうなりますか?

以下の小さな例をご覧ください。

var $canvas = document.querySelector('canvas'),
    ctx     = $canvas.getContext('2d'),
    lastX   = 0,
    lastY   = 0;

    drawLoop();


function drawLoop() {
    var newX = lastX + 30,
        newY = lastY + 30;

    ctx.beginPath();
    ctx.moveTo(lastX, lastY);
    ctx.lineTo(newX, newY);
    ctx.stroke();

    lastX = newX;
    lastY = newY;

    setTimeout(drawLoop, 1000);
}
<canvas width="100" height="100" style="border: 1px solid #ccc;"></canvas>
2
Daniel J F

Canvas変換を使用して、描画座標をスケーリング、変換、回転できます。

描画の最小座標と最大座標がある場合

例:

const min = {x: 100, y: 200};
const max = {x: 10009, y: 10000}; 

次のようにキャンバスに合わせることができます

const width = canvas.width;
const height = canvas.height;

// get a scale to best fit the canvas
const scale = Math.min(width / (max.x - min.x), height / (max.y - min.y));

// get a Origin so that the drawing is centered on the canvas
const top = (height - (max.y - min.y)) / 2;
const left = (width - (max.x - min.x)) / 2;

// set the transform so that you can draw to the canvas
ctx.setTransform(scale, 0, 0, scale, left, top);

// draw something
ctx.strokeRect(min.x, min.y, max.x - min.x, max.y - min.y);

最初に描画領域のサイズがわからない場合は、描画座標を保存する必要があります。最小値と最大値が変更されたら、変換を再計算し、キャンバスをクリアして再描画します。最初のサイズがわからなければ他に方法はありません。

4
Blindman67