2014-02-12 2 views
7

enter image description hereenter image description hereHTML5 캔버스 줌 후 좌표를 얻을

배경을 번역 : 내가 HTML5 캔버스를 가지고 내가에 그려진 이미지를 가지고있다. 이제 이미지가 처음로드되면 100 % 스케일로로드됩니다. 이미지는 5000 x 5000입니다. 그리고 캔버스 크기는 600 x 600입니다. 따라서 onload는 처음 600 x 픽셀과 600 y 픽셀 만 볼 수 있습니다. 캔버스에서 이미지를 확대 및 축소하는 옵션이 있습니다.

문제 : 스케일링 및 변환을 고려하면서 캔버스가 아닌 이미지를 기준으로 마우스 클릭의 픽셀 좌표를 반환하는 알고리즘을 찾으려고합니다. 이미 많은 주제가 있음을 알고 있지만, 내가 본 것은 아무것도 없습니다. 제 문제는 번역과 스케일링이 여러 개인 경우입니다. 한 번 확대하여 올바른 좌표를 얻을 수 있으며, 다시 오른쪽 좌표를 크기를 조정하고 다시 가져올 수 있지만 한 번 이상 확대 또는 축소하면 좌표가 꺼집니다.

여기까지 제가 지금까지 있습니다.

//get pixel coordinates from canvas mousePos.x, mousePos.y 
(mousePos.x - x_translation)/scale //same for mousePos.y 

annotationCanvas.addEventListener('mouseup',function(evt){ 
        dragStart = null; 
        if (!dragged) { 
         var mousePos = getMousePos(canvas, evt); 
         var message1 = " mouse x: " + (mousePos.x) + ' ' + "mouse y: " + (mousePos.y); 
         var message = " x: " + ((mousePos.x + accX)/currentZoom*currentZoom) + ' ' + "y: " + ((mousePos.y + accY)/currentZoom); 
         console.log(message); 
         console.log(message1); 
         console.log("zoomAcc = " + zoomAcc); 
         console.log("currentZoom = " + currentZoom); 
         ctx.fillStyle="#FF0000"; 
         ctx.fillRect((mousePos.x + accX)/currentZoom, (mousePos.y + accY)/currentZoom, -5, -5); 

        } 
      },true); 
//accX and accY are the cumulative shift for x and y respectively, and xShift and xShift yShift are the incremental shifts of x and y respectively 

여기서 현재 확대/축소는 누적 확대/축소입니다. zoomAcc는 그 시점에서 줌의 단일 반복입니다. 따라서이 경우, 확대 할 때 zoomAcc는 항상 1.1이고 currentZoom = currentZoom * zoomAcc입니다.

왜 잘못 되었나요? 누군가가 이러한 변환을 추적하는 방법을 보여 주시고 mousePos.x 및 mousePos.y에 적용 해 주시면 감사하겠습니다.

감사

UPDATE : 이미지에서

가, 녹색 점은 내가 클릭 한 위치, 빨간 점은 그 시점의 내 계산이 마르크의 방법을 사용하여 계산되는 경우입니다. m 값은 markE 메소드의 행렬 값입니다.

+0

: 당신은 브라우저의 창을 변환 할 수 있습니다

가 변형이 같은 좌표로 좌표? 그래서 당신은 마지막으로 당신의 문제를 해결 않았다 어떻게 ... 내가 같은 문제 :( – AkshayJ

답변

9

번역 및 축척 할 컨텍스트를 지정하면이를 캔버스 변환이라고합니다. 동시에 행렬을 업데이트 또한 context.translate 또는 context.scale 및 않으면

// an array representing the canvas affine transformation matrix 
var matrix=[1,0,0,1,0,0]; 

는 다음 행렬을 사용할 수

캔버스 변환 6 개 배열 요소로 표현 될 수있는 매트릭스에 기초 변환되지 않은 X/Y 좌표 (마우스 이벤트와 같은)를 변형 된 이미지 좌표로 변환합니다.

context.translate :

동시에 context.translate (X, Y)를 수행하고 이런 행렬이 역 추적 할 수

// do the translate 
// but also save the translate in the matrix 
function translate(x,y){ 
    matrix[4] += matrix[0] * x + matrix[2] * y; 
    matrix[5] += matrix[1] * x + matrix[3] * y; 
    ctx.translate(x,y); 
} 

context.scale :

동시에 컨텍스트를 수행 할 수 있습니다.규모 (X, Y)와 같은 매트릭스 스케일링 것을 추적 :

// do the scale 
// but also save the scale in the matrix 
function scale(x,y){ 
    matrix[0] *= x; 
    matrix[1] *= x; 
    matrix[2] *= y; 
    matrix[3] *= y;  
    ctx.scale(x,y); 
} 

전환 마우스를 변환 이미지 좌표하는

문제를 좌표는 브라우저가 당신이 당신의 캔버스 좌표 시스템을 변화 한 것을 인식하지 못하는 것입니다 브라우저는 변형 된 캔버스를 기준으로하지 않고 브라우저 윈도우를 기준으로 마우스 좌표를 반환합니다.

다행히도 변환 행렬은 축적 된 모든 번역 및 비율을 추적 해 왔습니다.

// convert mouseX/mouseY coordinates 
// into transformed coordinates 

function getXY(mouseX,mouseY){ 
    newX = mouseX * matrix[0] + mouseY * matrix[2] + matrix[4]; 
    newY = mouseX * matrix[1] + mouseY * matrix[3] + matrix[5]; 
    return({x:newX,y:newY}); 
} 
+0

마르크에 붙어 있어요, 감사합니다 자세한 설명을 제공합니다. 지시 사항을 따랐으며, 처음으로 줌을 처음 할 때 올바른 좌표를 얻습니다.하지만 줌 후에 이동하면 꺼집니다. 내 질문에 그림을 추가했습니다. – flash

+0

누락되었습니다. canvas의 'width'와'height' 속성으로 인한 자동 크기 조절입니다. 너비와 높이의 실제 너비와 높이의 비율을 캔버스 너비와 높이에 더하면 고정되어야합니다. – Domi

+0

또한, 어떤 것들은 캔버스의 내부 변환 행렬을 재설정 할 것입니다. 예 : 'canvas.width' 또는'height'를 설정할 때. 나중에 매트릭스를 재설정하십시오. – Domi