2015-02-20 13 views
6

Przeszukałem inne pytania, ale żadna z nich nie pasowała do mojej sprawy.Pozycja myszy w kanale reagującym na HTML 5

Mam elementu canvas:

<canvas id="linear-synoptic-map" width="1053px" height="1000px" ng-click="linearSynopticCtrl.canvasClicked($event)" ng-mousemove="linearSynopticCtrl.mouseMovedOverCanvas($event)"> 
</canvas> 

A ja dostaję pozycję z tej funkcji:

linearSynopticCtrl.getPositionFromEvent = function (event) { 
    var rect = linearSynopticCtrl.canvas.getBoundingClientRect(); 
    var x = event.x - rect.left; 
    var y = event.y - rect.top; 
    return new Point(x,y); 
}; 

Problemem jest to, że płótno musi reagować tak Dodałem następująca reguła css:

canvas#linear-synoptic-map { 
    width: 100%; 
} 

Kiedy następuje zmiana rozmiaru (gdy wymiar płótna zostanie skurczony o Definicja wer. lub powiększona w stosunku do definicji: 1053x1000) pomiędzy funkcjami poprawna pozycja myszy i pozycja zwrócona rozpoczyna się przerwa.

Próbowałem również uzyskanie pozycji z tego podejścia:

linearSynopticCtrl.getPositionFromEvent = function (event) { 
    var x = event.x - linearSynopticCtrl.canvas.offsetLeft; 
    var y = event.y - linearSynopticCtrl.canvas.offsetTop; 
    return new Point(x,y); 
}; 

Ale mam dużo gorsze wyniki.

Czy ktoś wie, jak rozwiązać ten problem?

+3

Spróbuj rozmiaru rzeczywista szerokość i wysokość płótna do wymiarów ekranu na okna zmiany rozmiaru zamiast css skalowanie, a następnie użyj drawImage, aby rozciągnąć obraz do rozmiaru. Będziesz oczywiście musiał śledzić ręczne skalowanie i odpowiednio dostosować pozycję myszy. – Frank

Odpowiedz

5

Współrzędne myszy nigdy nie są skalowane.

Dlatego należy przeskalować współrzędne myszy, aby odzwierciedlić skalowane płótno.

Oto jeden ze sposobów, aby Twoje płótno czuły i uzyskać skalowane myszy współrzędne:

// handle responsively resizing the canvas 
 
var scale=1.00; 
 
var originalWindowWidth=window.innerWidth; 
 
var originalCanvasWidth=document.getElementById('canvas').width; 
 
function debounce(func, wait, immediate) { 
 
    var timeout; 
 
    return function() { 
 
    var context = this, args = arguments; 
 
    var later = function() { 
 
     timeout = null; 
 
     if (!immediate) func.apply(context, args); 
 
    }; 
 
    var callNow = immediate && !timeout; 
 
    clearTimeout(timeout); 
 
    timeout = setTimeout(later, wait); 
 
    if (callNow) func.apply(context, args); 
 
    }; 
 
}; 
 
var resizeCanvas = debounce(function() { 
 
    scale=window.innerWidth/originalWindowWidth; 
 
    $('#canvas').css('width',originalCanvasWidth*scale); 
 
}, 250); 
 
window.addEventListener('resize', resizeCanvas); 
 

 
// now, do normal app stuff 
 

 
var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 

 
$("#canvas").mousemove(function(e){handleMouseMove(e);}); 
 

 
ctx.fillRect(50,50,100,100); 
 
ctx.fillText('Rect drawn at [50,50]',50,35); 
 

 
function handleMouseMove(e){ 
 

 
    var rect = canvas.getBoundingClientRect(); 
 
    var x = parseInt((event.x - rect.left)/scale); 
 
    var y = parseInt((event.y - rect.top)/scale); 
 

 
    $('#mouse').text(x+'/'+y); 
 

 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<h4>Mouse will report rect corner at<br>[50,50] even after resizing window</h4> 
 
<h4 id=mouse>mouse</h4> 
 
<canvas id="canvas" width=300 height=300></canvas>