[英]Zoom In Canvas And Then Zooming Out in a different mouse position Breaks Background Display
我正在尝试在我的 canvas 上实现缩放 function,使鼠标 position 相对于之前的位置保持不变。
这个function差不多就完成了。 这是一个完整的例子: https://codepen.io/PJEstrada006/pen/dyRxVXE?editors=0011
public zoom_wheel_canvas_translate(event): void { // this is the illusionary point on UI that we wish to stay locked on let point = this.mouse_position; const wheel = event.deltaY < 0? 1: -1; // Compute zoom factor. let zoomIntensity = 0.2; let zoom = Math.exp(wheel * zoomIntensity); this.scale = this.scale * zoom; if (this.scale <= 1) { this.canvas_ctx.setTransform(1, 0, 0, 1, 0, 0); this.scale = 1; return } if (this.scale >= 30) { this.scale = 30 } this.canvas_ctx.clearRect( 0, 0, this.canvas_elm.width, this.canvas_elm.height ); let transform = this.canvas_ctx.getTransform(); this.canvas_ctx.resetTransform(); this.canvas_ctx.translate(point.x, point.y); this.canvas_ctx.scale(zoom, zoom); this.canvas_ctx.translate(-point.x, -point.y); this.canvas_ctx.transform(transform.a, transform.b, transform.c, transform.d, transform.e, transform.f) let transform_new = this.canvas_ctx.getTransform(); console.log('a', transform.a, 'd', transform.d) console.log('e', transform.e, 'f', transform.f) }
我有一个图像设置为 canvas 的背景,它是这样绘制的:
ctx.drawImage(
this.image,
0,
0
)
问题是,如果我执行以下操作:
缩小最终以错误的方式结束了 canvas 的翻译,而我的 canvas 图像由于不正确的翻译或比例而出现“切片”或不完整。 这发生在比例变为 1 之前,然后它会自行修复,因为当比例 = 1 时我有一个 resetTransform() 调用。
我期望无论我如何移动鼠标,我最终都会缩小并最终得到原始变换矩阵(单位矩阵)。
任何人都可以帮助我发现我在转换方面做错了什么。 我不太明白为什么如果我不移动鼠标它就可以完美运行,但如果我将鼠标移动到放大 state 然后缩小,它就会停止工作。
您正在寻找“了解为什么此鼠标移开算法不起作用”,我不会说它不起作用,因为没有错误,我在您的代码笔上测试了缩放,我感觉很好...
您的缩放是相对于鼠标的 position 而言的,与之交互感觉直观流畅。
我对您的代码做了一些清理:
https://codepen.io/heldersepu/pen/LYjYEyL?editors=0010
我看到的唯一问题是在不考虑图像可能超出范围的情况下进行翻译,
看到这段代码:
context.translate(x, y);
context.scale(zoom, zoom);
context.translate(-x, -y);
该代码在 map 图像非常大且环绕的世界中会很好,我相信谷歌地图使用类似的逻辑,这是一个完美的用例,但你没有考虑图像的限制。
放大你的图像我们不会看到问题,因为图像总是被填充,但是如果我们在边缘,你可能会移出图像的边界。
这是一个例子:
结果 canvas 看起来像这样:
这种情况怎么办?
当我们缩小时,一个选项可能是不翻译:
if (wheel > 0) context.translate(x, y);
context.scale(zoom, zoom);
if (wheel > 0) context.translate(-x, -y);
或者您可以根据鼠标有条件地在一个轴上而不是另一个轴上平移 position,但正确的解决方案由您决定,您必须测试并查看您喜欢的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.