javascript/canvas,地图样式点缩放

javascript/canvas,地图样式点缩放,javascript,canvas,Javascript,Canvas,我有一张画布,上面有一堆东西。我有一个缩放功能,它可以放大一个zoom变量,每个坐标都乘以该变量 我希望能够指向一个坐标并向那个方向缩放,就像在线地图那样 我已经设置了代码当前状态的演示。按坐标缩放 如果给定具有缩放内容的屏幕坐标,则需要以与缩放匹配的量将原点移向或移离该点 如果放大,原点将向鼠标位置移动。然后缩小 因此,使用鼠标获得x、y位置,并根据车轮方向放大或缩小的量 // e is the mouse wheel event const x = e.offsetX; const y =

我有一张画布,上面有一堆东西。我有一个缩放功能,它可以放大一个
zoom
变量,每个坐标都乘以该变量

我希望能够指向一个坐标并向那个方向缩放,就像在线地图那样

我已经设置了代码当前状态的演示。

按坐标缩放 如果给定具有缩放内容的屏幕坐标,则需要以与缩放匹配的量将原点移向或移离该点

如果放大,原点将向鼠标位置移动。然后缩小

因此,使用鼠标获得x、y位置,并根据车轮方向放大或缩小的量

// e is the mouse wheel event
const x = e.offsetX;
const y = e.offsetY;
const amount = e.wheelDelta > 0 ?  1.1 : 1 / 1.1; 
然后将其应用于当前比例并移动原点以匹配

scale *= amount;  // the new scale
// move the origin
origin.x = x - (x - origin.x) * amount;
origin.y = y - (y - origin.y) * amount;
然后,可以使用设置二维位置和比例

ctx.setTransform(scale, 0, 0, scale, origin.x, origin.y);
例子 下面是一个简单的视图示例,它使用了小提琴中的一些代码

对象
视图
跟踪当前视图并维护可应用于画布的矩阵

const ctx=canvas.getContext(“2d”);
画布宽度=500;
高度=500;
常数randI=(min,max=min+(min=0))=>(Math.random()*(max-min)+min)|0;
常量rand=(min,max=min+(min=0))=>Math.random()*(max-min)+min;
常量对象=[];
for(设i=0;i<100;i++){
objects.push({
x:rand(画布宽度),
y:rand(画布高度),
w:兰特(40),
h:兰特(40),
col:`rgb(${randI(255)},${randI(255)},${randI(255)})`,
});
}
canvas.addEventListener(“鼠标滚轮”,onmousewheel,false);
canvas.addEventListener(“DOMMouseScroll”,onmouseheel,false);
requestAnimationFrame(drawCanvas);//这将在所有其他代码运行后调用drawcanvas
常量视图=(()=>{
常量矩阵=[1,0,0,1,0,0];//当前视图转换
var m=matrix;//清除代码的别名
变量比例=1;//当前比例
var ctx;//对2D上下文的引用
const pos={x:0,y:0};//原点的当前位置
var dirty=true;
常量API={
setContext(_ctx){ctx=_ctx;dirty=true},
应用(){
if(dirty){this.update()}
ctx.setTransform(m[0],m[1],m[2],m[3],m[4],m[5])
},
getScale(){return scale},
getPosition(){return pos},
isDirty(){return dirty},
更新(){
脏=假;
m[3]=m[0]=刻度;
m[2]=m[1]=0;
m[4]=位置x;
m[5]=位置y;
},
屏幕坐标中的刻度(at,amount){//at
if(dirty){this.update()}
比例*=金额;
x位置=x位置-(x位置-x位置)*金额;
y位置=y位置-(y位置-y位置)*金额;
肮脏=真实;
},
};
返回API;
})();
view.setContext(ctx);
函数drawCanvas(){
如果(view.isDirty()){//视图已更改,则绘制所有
setTransform(1,0,0,1,0,0);//清除的默认转换
clearRect(0,0,canvas.width,canvas.height);
view.apply();//将2D上下文转换设置为视图
对于(i=0;i0){view.scaleAt({x,y},1.1)}
else{view.scaleAt({x,y},1/1.1)}
e、 预防默认值();
}
#画布{
边框:2倍实心;
}

看起来不错!
ctx.setTransform()
ctx.scale()
不同吗?最初我有一个使用
ctx.scale()
的方法,但这似乎是一种缩放和质量降低的方法。@meganukebmp setTransform只是一种比使用缩放、旋转或平移更直接的设置当前变换的方法。另外,setTransform设置当前变换,而其他方法应用于当前变换。啊,我理解。非常感谢。