0

有没有办法使用此代码放大光标点?我无法动脑筋去做这件事。画布缩放,但它只从左上角放大和缩小。

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);
    }
}
4

2 回答 2

1

画布始终从其当前原点缩放。默认原点是 [0,0]。

如果你想从另一个点缩放,你可以先做context.translate(desiredX,desiredY);. 这会将画布的原点重置为 [desiredX,desiredY]。

这样,您context.scale将从指定的原点扩展。

由于所有上下文转换对于每个后续绘图都保持有效,因此您通常希望在完成当前绘图后反转转换(=='resetting' 用于可能/可能不使用当前转换的下一个绘图)。要取消转换,只需使用否定参数调用转换:例如。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);
于 2014-11-14T20:30:56.733 回答
0

首先,我想指出,从您的代码看来,您正在监听画布上的“鼠标滚轮”事件。如此处所述,“鼠标滚轮”事件是非标准的,并且不会成为标准。因此,在聆听时,您会得到充其量是混合的结果。“滚动”事件几乎在每个平台上都可用,并且可能是捕获用户输入的更好途径。

至于你的问题,你正在寻找你正在寻找的行为的正确轨道,但你错过了一步。

当您调用scale画布上下文对象时,行为非常简单。从左上角 (0,0) 开始,该方法通过提供的因子缩放画布的点。假设您有一个 10x10 的画布,在 1,1 处有一个黑点。如果画布在两个轴上都按 2 倍缩放,则 0,0 点将保持在同一位置,但点 1,1 将是缩放前点 2,2 所在的位置。

为了实现您正在寻找的“缩放”行为,必须在缩放之后翻译上下文,以便参考点占据与缩放之前相同的物理位置。在您的情况下,参考点是执行缩放操作时用户光标所在的点。

幸运的是,画布上下文对象提供了一种translate(x,y)方法,可以相对于画布的 0,0 点移动上下文的原点。要将其翻译为正确的数量,您必须:

  1. 缩放前计算鼠标光标到画布原点的距离
  2. 将该距离除以比例因子
  3. 按该值翻译原点

由于您的代码并未指明 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);
    }
}
于 2014-11-14T20:43:40.067 回答