Javascript 不使用ctx.scale将画布缩放到鼠标光标

Javascript 不使用ctx.scale将画布缩放到鼠标光标,javascript,html,canvas,zooming,Javascript,Html,Canvas,Zooming,我正在尝试将缩放原点更改为鼠标光标,而不是默认的左上角,并且我无法使用ctx.translate和ctx.scale,因为网格缓冲区需要重新绘制并且无法缩放(一行必须始终为1px宽)。网格可以缩放和移动,只是原点不正确 我不知道缩放后如何计算网格的新x和新y坐标 重要的代码片段和我已经尝试过的内容在Camera类中进行了注释 const canvas=document.getElementById(“canvas”); const ctx=canvas.getContext(“2d”); //

我正在尝试将缩放原点更改为鼠标光标,而不是默认的左上角,并且我无法使用ctx.translate和ctx.scale,因为网格缓冲区需要重新绘制并且无法缩放(一行必须始终为1px宽)。网格可以缩放和移动,只是原点不正确

我不知道缩放后如何计算网格的新x和新y坐标

重要的代码片段和我已经尝试过的内容在Camera类中进行了注释

const canvas=document.getElementById(“canvas”);
const ctx=canvas.getContext(“2d”);
//乌提尔斯//
函数getCursorPos(evt){
const rect=canvas.getBoundingClientRect();
返回{
x:Math.floor(((evt.clientX-rect.left)/(rect.right-rect.left))*canvas.offsetWidth),
y:Math.floor(((evt.clientY-rect.top)/(rect.bottom-rect.top))*canvas.offsetHeight),
};
}
//////////
常量场景={
渲染器:画布,
背景:ctx,
宽度:1200,
身高:1000,
手机号码:30,
渲染:函数(缓冲区,x,y){
this.context.clearRect(0,0,this.renderer.width,this.renderer.height);
this.context.drawImage(缓冲区,x,y);
},
};
类网格{
构造函数(){
this.width=scene.width;
this.height=scene.height;
this.cellSize=scene.cellSize;
this.color=“black”;
this.buffer=document.createElement(“画布”);
this.buffer.width=this.width;
this.buffer.height=this.height;
}
构建(){
//我们不直接在主画布(scene.renderer)上进行绘制调用,
//相反,我们创建一个缓冲区(在本例中是画布元素),
//调用scene.render()时,将在主画布上绘制为图像;
const ctx=this.buffer.getContext(“2d”);
clearRect(0,0,this.buffer.width,this.buffer.height);
ctx.setLineDash([2,5]);
for(设u=0,len=this.height;u0?-this.zoomInc:this.zoomInc;
这个.zoom+=步长;
//这个.x和这个.y是网格在画布上渲染的位置;
//首先我想这样做:
//this.x=-this.toScreen(this.toWorld(x)-x);
//this.y=-this.toScreen(this.toWorld(y)-y);
//但它只有在网格位于x:0y:0时才起作用;
//经过一些研究后,我尝试将x和y相对于光标在网格中的世界位置移动;
//const-worldPos={x:this.toWorld(x)-this.x,y:this.toWorld(y)-this.y};
//this.x=-(this.x-worldPos.x*步);
//this.y=-(this.y-worldPos.y*步);
//如果x和y未更改,缩放原点默认为相机的当前原点;
}
getZoom(){
返回这个.zoom;
}
}
函数init(){
//初始设置//
常量网格=新网格();
常量摄影机=新摄影机();
grid.build();
const gridBuffer=grid.getBuffer();
scene.context.drawImage(gridBuffer,0,0);
scene.renderer.addEventListener(“mousemove”(evt)=>{
if(camera.isStartedDrag()){
camera.drag(getCursorPos(evt));
渲染(gridBuffer,-camera.x,-camera.y);
}
});
scene.renderer.addEventListener(“鼠标向下”(mousedown),(evt)=>{
摄像头.setStartDrag(getCursorPos(evt));
});
scene.renderer.addEventListener(“mouseup”,()=>{
camera.stopDrag();
});
scene.renderer.addEventListener(“轮子”,“evt)=>{
evt.preventDefault();
摄像机设置刻度(evt);
const zoom=camera.getZoom();
grid.setCellSize(scene.cellSize*缩放);
grid.setDimensions(scene.width*缩放,scene.height*缩放);
//我们根据新的缩放级别重建更小或更大的网格;
grid.build();
const gridBuffer=grid.getBuffer();
渲染(gridBuffer,-camera.x,-camera.y);
});
}
init()

我最近写了一个简单的工具来显示意大利的新冠病毒-19数据图表,它正好解决了您的问题,我可以说有很多方面需要注意。我的图表和您正在寻找的图表之间的唯一区别似乎是,在我的图表中,水平缩放和垂直缩放是独立的

这是最新版本,因此您可以检查它是否满足您的需要

<