javascript - 相对于鼠标坐标缩放画布
问题描述
我有一个非常简单的应用程序,我在画布上完美地绘制了图像。我正在通过 image.width/2、image.height/2 翻译上下文,并将目标点设置为 -image.width/2、-image.height/2。
function draw() {
window.canvas = document.getElementById('canvas');
window.ctx = canvas.getContext('2d');
window.image = document.createElement("img");
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(image.width/2,image.height/2);
ctx.drawImage(image,-image.width/2,-image.height/2);
};
image.src = 'rec.JPG';
}
这是按应有的方式显示图像。所以考虑到这个概念,如果我想在画布中心制作图像的中心点,我应该像上面那样做。现在,我希望用户单击画布,我正在获取鼠标坐标。然后我想缩放这个图像并重新绘制画布,这样用户就会在中心看到图像的那部分(缩放版本)。代码如下:
function zoom(evt) {
var x = getMousePos(canvas, evt).x;
var y = getMousePos(canvas, evt).y;
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(x,y);
ctx.scale(1.5, 1.5);
ctx.drawImage(image,-x,-y);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
但不知何故,我没有得到正确的结果。我想查看用户单击的区域,然后再次单击以缩小,仅此而已。我可以轻松完成后面的部分,但在缩放完美区域时遇到问题。我在 stackoverflow 上看到了类似的问题,但它们不符合我的要求。这是我的 html 和 css:
<style>
.container {
height: 500px;
}
.container .image-container {
height: 500px;
width: 50%;
overflow: auto;
position: absolute;
border: 1px solid;
}
img {
display: none;
}
canvas {
width: 100%;
}
</style>
<body onload="draw()">
<div class="container">
<div class="image-container">
<canvas
id="canvas"
onclick="zoom(event)"
>
</canvas>
</div>
</div>
</body>
PS:我不想平移。只需点击放大和缩小。你可以玩这个片段。
function draw() {
window.canvas = document.getElementById('canvas');
window.ctx = canvas.getContext('2d');
window.image = document.createElement("img");
window.isZoom = false;
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(image.width/2,image.height/2);
ctx.drawImage(image,-image.width/2,-image.height/2);
};
image.src = 'https://d85ecz8votkqa.cloudfront.net/support/help_center/Print_Payment_Receipt.JPG';
}
function zoom(evt) {
if(!isZoom) {
var x = getMousePos(canvas, evt).x;
var y = getMousePos(canvas, evt).y;
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(x,y);
ctx.scale(2, 2);
ctx.drawImage(image,-x,-y);
canvas.style.cursor = 'zoom-out';
isZoom = true;
} else {
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.translate(image.width/2,image.height/2);
ctx.drawImage(image,-image.width/2,-image.height/2);
isZoom=false;
canvas.style.cursor = 'zoom-in';
}
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
<style>
.container {
height: 500px;
}
.container .image-container {
height: 500px;
width: 50%;
overflow: auto;
position: absolute;
border: 1px solid;
}
img {
display: none;
}
canvas {
width: 100%;
cursor: zoom-in;
}
</style>
<body onload="draw()">
<div class="container">
<div class="image-container">
<canvas
id="canvas"
onclick="zoom(event)"
>
</canvas>
</div>
</div>
</body>
解决方案
你真的很近,只需将比例混合到你的图像中
function draw() {
window.canvas = document.getElementById('canvas');
window.ctx = canvas.getContext('2d');
window.image = document.createElement("img");
window.isZoom = false;
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0,0);
};
image.src = 'https://d85ecz8votkqa.cloudfront.net/support/help_center/Print_Payment_Receipt.JPG';
}
function zoom(evt) {
canvas.width = image.width;
canvas.height = image.height;
ctx.clearRect(0, 0, canvas.width, canvas.height);
var scale = 2
if (!isZoom) {
var pos = getMousePos(canvas, evt);
ctx.scale(scale, scale);
ctx.drawImage(image, -pos.x*scale*scale, -pos.y*scale*scale);
canvas.style.cursor = 'zoom-out';
} else {
ctx.drawImage(image, 0, 0);
canvas.style.cursor = 'zoom-in';
}
isZoom = !isZoom
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
.container {
height: 500px;
}
.container .image-container {
height: 500px;
width: 50%;
overflow: auto;
position: absolute;
border: 1px solid;
}
img {
display: none;
}
canvas {
width: 100%;
cursor: zoom-in;
}
<body onload="draw()">
<div class="container">
<div class="image-container">
<canvas id="canvas" onclick="zoom(event)">
</canvas>
</div>
</div>
</body>
除了添加var scale
我对您的代码进行了一些清理之外:
var x = getMousePos(canvas, evt).x;
var y = getMousePos(canvas, evt).y;
对 getMousePos 的双重调用有点浪费
推荐阅读
- mysql - 如何在 MySql 中使用条件更新同一行?
- python - 如何将字符串从python中的字典转换为变量名
- c# - D3DImage 在 WPF 应用程序上丢失设备
- elasticsearch - 如何在同一可视化中容纳每分钟和每小时的数据?
- sql - 内连接与 order by 和 where 类
- node.js - 如何在 Google App Engine 上运行迁移
- javascript - css动画需要居中,不干扰首页布局
- django - 如何在 django 视图中使用类型转换和计算进行求和查询?
- mysql - 使用 WITH 子句乘以列
- java - 在设置回收器项目单击侦听器时获取空指针异常