Javascript光标缩放
是否有一种方法可以使用此代码缩放光标点?我不能动脑去做这件事。画布将缩放,但它仅从左上角放大和缩小Javascript光标缩放,javascript,html,canvas,zooming,panning,Javascript,Html,Canvas,Zooming,Panning,是否有一种方法可以使用此代码缩放光标点?我不能动脑去做这件事。画布将缩放,但它仅从左上角放大和缩小 var previousMousePosition = new Vector(0, 0); function OnMouseWheel (event) { var delta = event.wheelDelta ? event.wheelDelta/40 : event.detail ? -event.detail : 0; var mousePosition = new Vec
var previousMousePosition = new Vector(0, 0);
function OnMouseWheel (event) {
var delta = event.wheelDelta ? event.wheelDelta/40 : event.detail ? -event.detail : 0;
var mousePosition = new Vector(event.clientX, event.clientY);
var scaleFactor = 1.1;
if (delta) {
var factor = Math.pow(scaleFactor,delta);
context.scale(factor,factor);
}
}
画布始终从当前原点开始缩放。默认原点为[0,0] 如果要从另一个点进行缩放,可以首先执行
context.translate(desiredX,desiredY)代码>。这会将画布的原点重置为[desiredX,desiredY]
这样,您的context.scale
将从指定的原点开始缩放
由于所有上下文转换对每个后续图形都有效,因此在使用当前图形后,通常需要反转转换(=对下一个可能/可能不使用当前转换的图形进行“重置”)。要取消转换,只需使用负参数调用转换:例如context.scale(-factor,-factor)
。转换应该按照与原始转换相反的顺序进行
因此,重构代码可以是:
// set the origin to mouse x,y
context.translate(mousePosition.x,mousePosition.y);
// scale the canvas at x,y
context.scale(factor,factor);
// ...draw stuff
// reverse the previous scale
context.scale(-factor,-factor);
// reverse the previous translate
context.translate(-mousePosition.x,-mousePosition.y);
首先,我想指出,从您的代码来看,您似乎正在侦听画布上的“鼠标滚轮”事件。如前所述,“鼠标滚轮”活动是非标准的,不可能成为标准。因此,当你听它的时候,你得到的结果充其量是好坏参半的。几乎每个平台都可以使用“滚动”事件,这可能是捕获用户输入的更好途径
就你的问题而言,你在寻找行为的正确轨道上,但你错过了一步
在画布上下文对象上调用scale
时,行为非常简单。从左上角(0,0)开始,该方法根据提供的因子缩放画布的点。假设你有一块10x10的画布,在1,1处有一个黑点。如果画布在两个轴上按2的因子缩放,则0,0点将保持在同一位置,但点1,1将位于缩放前点2,2的位置
为了实现您正在寻找的“缩放”行为,必须在缩放后对上下文进行转换,以便参考点占据与缩放前相同的物理位置。在本例中,参考点是执行缩放操作时用户光标所在的点
幸运的是,canvas上下文对象提供了一个translate(x,y)
方法,该方法相对于画布的0,0点移动上下文的原点。要将其转换为正确的数量,您必须:
缩放前计算鼠标光标与画布原点的距离
将该距离除以比例因子
按该值转换原点
由于您的代码没有指明HTML的结构,下面我用一些注释和伪代码对其进行了标记,以展示如何实现此算法:
//You'll need to get a reference to your canvas in order to calculate the relative position of
//the cursor to its top-left corner, and save it to a variable that is in scope inside of your
//event handler function
var canvas = document.getElementById('id_of_your_canvas');
//We're also going to set up a little helper function for returning an object indicating
//the position of the top left corner of your canvas element (or any other element)
function getElementOrigin(el){
var boundingBox = el.getBoundingClientRect();
return { x: boundingBox.left, y: boundingbox.top};
}
function OnMouseWheel (event) {
//you probably want to prevent scrolling from happening or from bubbling so:
event.preventDefault();
event.stopPropagation();
var delta = event.wheelDelta ? event.wheelDelta/40 : event.detail ? -event.detail : 0;
var canvasCorner = getElementOrigin(canvas)
//JavaScript doesn't offer a 'vector' or 'point' class natively but we don't need them
var mousePosition = {x: event.clientX, y: event.clientY};
var diff = {x: mousePostion.x - canvasCorner.x, y: mousePosition.y - canvasCorner.y};
var scaleFactor = 1.1;
if (delta) {
var factor = Math.pow(scaleFactor,delta);
var transX = (-1/factor) * diff.x;
var transY = (-1/factor) * diff.y;
context.scale(factor,factor);
context.translate(transX, transY);
}
}
0,0可能是左上角?-那是我的猜测