放大一个点(使用缩放和平移) [英] Zoom in on a point (using scale and translate)
问题描述
我希望能够放大 HTML 5 画布中鼠标下方的点,例如放大 Google 地图.我怎样才能做到这一点?
I want to be able to zoom in on the point under the mouse in an HTML 5 canvas, like zooming on Google Maps. How can I achieve that?
推荐答案
终于解决了:
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>
关键,正如@Tatarize指出,是计算轴位置,使得缩放点(鼠标指针) 缩放后保持在同一位置.
The key, as @Tatarize pointed out, is to compute the axis position such that the zoom point (mouse pointer) remains in the same place after the zoom.
本来鼠标在距离角落mouse/scale
,我们希望鼠标下的点在缩放后保持在同一个位置,但这是在mouse/new_scale
远离角落.因此,我们需要移动 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 *= zoom
剩下的代码需要应用缩放并转换到绘制上下文,使其原点与画布角重合.
The remaining code then needs to apply the scaling and translate to the draw context so it's origin coincides with the canvas corner.
这篇关于放大一个点(使用缩放和平移)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!