2014-11-14 4 views
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); 
    } 
} 
+0

0,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); 
0

첫째, 난 당신이 캔버스에 '마우스 휠'이벤트를 수신하는 것처럼 사용자 코드에서 보이는 것을 지적하고 싶습니다. here에서 언급했듯이 'mousewheel'이벤트는 표준이 아니며 표준이되기까지 궤도에 오르지 않습니다. 결과적으로 청취시 최상의 결과를 얻을 수 있습니다. '스크롤'이벤트는 거의 모든 플랫폼에서 사용할 수 있으며 사용자 입력을 캡처하는 좋은 방법 일 수 있습니다.

질문과 관련하여 찾고있는 행동에 대해 올바른 방향으로 가고 있지만 한 걸음도 빠져 있습니다.

캔버스 컨텍스트 개체에서 scale을 호출하면 동작이 매우 간단합니다. 왼쪽 위 모서리 (0,0)부터 시작하여 메서드는 제공된 요소별로 캔버스의 점을 조절합니다. 당신은 10x10 화포가 있고, 1,1에 검은 점이 있다고 해봅시다. 캔버스가 두 축 모두에서 2의 배율로 배율 조정되면 0,0 점은 같은 위치에 있지만 1,1 점은 점 조정 전에 점 2,2가됩니다.

찾고있는 '확대/축소'동작을 달성하려면 참조 점이 크기 조정 전에 수행 한 동일한 물리적 위치를 차지하도록 크기 조정 후 컨텍스트가 으로 변환되어야합니다 (). 귀하의 경우, 참조 점은 줌 동작이 수행 될 때 사용자의 커서가 위치하는 지점입니다.

운좋게도 캔버스 컨텍스트 개체는 translate(x,y) 메서드를 제공하여 캔버스의 0,0 점을 기준으로 컨텍스트의 원점을 이동합니다.

  1. 그 값
  2. 에 의해 원점을 번역 배율
  3. 에 의해
  4. 나누기 그 거리를 확대하기 전에 캔버스 원점에서 마우스 커서의 거리를 계산한다 : 그것을 정확한 액수를 번역하려면 다음을 수행해야

    : 나는 약간의 의견과 의사에 그것을 표시 한 아래의 코드는이 알고리즘을 구현하는 방법을 보여주기 위해, 당신의 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); 
    } 
}