有没有办法使用此代码缩放光标点?我无法理解这一点。画布放大但只从左上角放大和缩小。
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 :(得分:1)
画布总是从它的当前原点缩放。默认原点为[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);
答案 1 :(得分:0)
首先,我想指出,从您的代码中看起来您正在监听画布上的'mousewheel'事件。如上所述here,“鼠标滚轮”事件是非标准的,无法成为标准。因此,在收听时,您最多会得到混合的结果。 “滚动”事件几乎在每个平台上都可用,并且可能是捕获用户输入的更好途径。
就你的问题而言,你正在寻找你正在寻找的行为,但你错过了一步。
当您在画布上下文对象上调用scale
时,行为非常简单。从左上角(0,0)开始,该方法根据提供的因子缩放画布的点。假设您有一个10x10的画布,以及一个1,1点的黑点。如果画布在两个轴上按比例缩放2,则0,0点将保持在同一位置,但点1,1将是缩放前点2,2的位置。
为了实现您正在寻找的“缩放”行为,缩放后的上下文必须已翻译,以便参考点占用与缩放前相同的物理位置。在您的情况下,参考点是执行缩放操作时用户光标所在的点。
幸运的是,canvas上下文对象提供了一个translate(x,y)
方法,可以相对于画布的0,0点移动上下文的原点。要将其翻译为正确的ammount,您必须:
由于您的代码未指明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);
}
}