简体   繁体   English

从第二个 canvas 绘图时居中并放大一点

[英]Center and zoom in on a point when drawing from a second canvas

Update: I found a solution to my own question.更新:我找到了解决我自己问题的方法。 See answer below.请参阅下面的答案。

I'm working on a center-and-zoom feature for my canvas.我正在为我的 canvas 开发中心和缩放功能。 When the user clicks on the screen, the clicked point should be moved to the center and zoomed in.当用户点击屏幕时,点击的点应该移动到中心并放大。

I have two canvases.我有两张画布。 The first canvas is rendered on screen and shows a portion of the second canvas.第一个 canvas 在屏幕上呈现并显示第二个 canvas 的一部分。 The second canvas is not a true "OffscreenCanvas" but is stored in memory only.第二个 canvas 不是真正的“OffscreenCanvas”,而是仅存储在 memory 中。

The panning and zooming is done in increments using requestAnimationFrame.使用 requestAnimationFrame 以增量方式进行平移和缩放。

Since it's probably a good idea to let the "offscreen canvas" remain unaltered, I'm attempting to apply all of the changes to the onscreen canvas.由于让“屏幕外画布”保持不变可能是个好主意,因此我尝试将所有更改应用于屏幕 canvas。 Panning is simple enough, but how to combine panning and zooming?平移很简单,但是如何将平移和缩放结合起来呢?

In the current code, zooming is achieved by shrinking the size of the viewport (viewportWidth or Height -= viewportWidth or Height * 0.01).在当前代码中,缩放是通过缩小视口的大小来实现的(viewportWidth or Height -= viewportWidth or Height * 0.01)。 I then compensate for the smaller viewport by panning a bit further than I would have otherwise (+ viewportWidth or Height * 0.01 * 0.5).然后,我通过平移比其他方式(+ viewportWidth 或 Height * 0.01 * 0.5)更远的位置来补偿较小的视口。

[![image explaining my problem with panning and zooming][1]][1] [![解释我的平移和缩放问题的图像][1]][1]

However, with this solution, the screen centers on a point to the left of where the user clicked.但是,使用此解决方案时,屏幕将位于用户单击位置左侧的某个点上。 Can you tell me what I'm doing wrong?你能告诉我我做错了什么吗?

Alternatively, if there is a better way to go about this, I would be very happy to hear about it.或者,如果有更好的方法 go 关于这个,我会很高兴听到它。

This is what I've come up with so far:到目前为止,这是我想出的:

// Global variables:
onscreenCanvas
offscreenCanvas
viewportPositionX
viewportPositionY
viewportWidth
viewportHeight

document.addEventListener('click', (event) => {

let counter = 0

// Distance from clicked point to center of screen:
let panX = -(window.innerWidth/2 - event.pageX)
let panY = -(window.innerHeight/2 - event.pageY)

function panAndZoom() {
// Pan one percent of the distance:
viewportPositionX += panX * 0.01
viewportPositionY += panY * 0.01

let ctx = onscreenCanvas.getContext('2d')

ctx.drawImage(
offscreenCanvas,
viewportPositionX + viewportWidth * 0.01 * 0.5,
viewportPositionY + viewportHeight * 0.01 * 0.5,
viewportWidth - viewportWidth * 0.01,
viewportHeight - viewportHeight * 0.01,
0,
0,
window.innerWidth,
window.innerHeight)

// Shrink viewport by one percent:
viewportWidth -= viewportWidth * 0.01
viewportHeight -= viewportHeight * 0.01

counter++

if (counter <= 100) {
window.requestAnimationFrame(panAndZoom)
}

}

panAndZoom()

})


  [1]: https://i.stack.imgur.com/b9DR7.png

Okay, so I found a solution.好的,所以我找到了解决方案。 Instead of decreasing the size of the viewport for each redraw, I should have increased the size of the scaling.我应该增加缩放的大小,而不是减少每次重绘的视口大小。

let scaleX = viewportWidth * 0.005
let scaleY = viewportHeight * 0.005

[...]

ctx.drawImage(
offscreenCanvas,
viewportPositionX + scaleX * 0.5,
viewportPositionY + scaleY * 0.5,
viewportWidth - scaleX,
viewportHeight - scaleY,
0,
0,
window.innerWidth,
window.innerHeight)

scaleX += viewportWidth * 0.005
scaleY += viewportHeight * 0.005

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM