1. ホーム
  2. javascript

[解決済み] 点の拡大表示(拡大縮小、平行移動の使用)

2022-04-22 08:31:30

質問

HTML 5のキャンバスで、マウスの下にある点をズームできるようにしたい。 グーグルマップ . どうすれば実現できるのでしょうか?

どのように解決するのですか?

ようやく解決しました。

const zoomIntensity = 0.2;

const canvas = document.getElementById("canvas");
let context = canvas.getContext("2d");
const width = 600;
const height = 200;

let scale = 1;
let originx = 0;
let originy = 0;
let visibleWidth = width;
let visibleHeight = height;


function draw(){
    // Clear screen to white.
    context.fillStyle = "white";
    context.fillRect(originx, originy, width/scale, height/scale);
    // Draw the black square.
    context.fillStyle = "black";
    context.fillRect(50, 50, 100, 100);

    // Schedule the redraw for the next display refresh.
    window.requestAnimationFrame(draw);
}
// Begin the animation loop.
draw();

canvas.onwheel = function (event){
    event.preventDefault();
    // Get mouse offset.
    const mousex = event.clientX - canvas.offsetLeft;
    const mousey = event.clientY - canvas.offsetTop;
    // Normalize mouse wheel movement to +1 or -1 to avoid unusual jumps.
    const wheel = event.deltaY < 0 ? 1 : -1;

    // Compute zoom factor.
    const zoom = Math.exp(wheel * zoomIntensity);
    
    // Translate so the visible origin is at the context's origin.
    context.translate(originx, originy);
  
    // Compute the new visible origin. Originally the mouse is at a
    // distance mouse/scale from the corner, we want the point under
    // the mouse to remain in the same place after the zoom, but this
    // is at mouse/new_scale away from the corner. Therefore we need to
    // shift the origin (coordinates of the corner) to account for this.
    originx -= mousex/(scale*zoom) - mousex/scale;
    originy -= mousey/(scale*zoom) - mousey/scale;
    
    // Scale it (centered around the origin due to the trasnslate above).
    context.scale(zoom, zoom);
    // Offset the visible origin to it's proper position.
    context.translate(-originx, -originy);

    // Update scale and others.
    scale *= zoom;
    visibleWidth = width / scale;
    visibleHeight = height / scale;
}
<canvas id="canvas" width="600" height="200"></canvas>

として、キーは タタライズさんご指摘の ズーム後にズームポイント(マウスポインタ)が同じ場所に残るような軸位置を計算することです。

本来、マウスは距離 mouse/scale にあるため、ズーム後もマウスの下の点が同じ場所にあるようにしたいのですが、この場合、コーナーから mouse/new_scale コーナーから離れる。したがって origin (コーナーの座標)を考慮する必要があります。

originx -= mousex/(scale*zoom) - mousex/scale;
originy -= mousey/(scale*zoom) - mousey/scale;
scale *= zoom

残りのコードでは、描画コンテキストにスケーリングとトランスレートを適用して、その原点がキャンバスの角と一致するようにする必要があります。