2015-02-20 4 views
6

Я искал другие вопросы, но ни один из них не соответствовал моему делу.Позиция мыши в HTML 5 отзывчивом Холст

У меня есть холст элемент:

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

И я получаю позицию с помощью этой функции:

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

Проблема заключается в том, что полотно должно быть отзывчивым, поэтому я добавил следующее правило css:

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

Когда изменение размера происходит (когда размер холста сжимается o ver или увеличено по определению: 1053x1000) пробел начинает показывать между правильной позицией мыши и возвращенной позицией функцией.

Я также попытался получить позицию с таким подходом:

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

Но я получаю гораздо худшие результаты.

Кто-нибудь знает, как исправить эту проблему?

+3

Попробуйте изменить размер фактическую ширину и высоту холста до размеров экрана на окна изменения размера вместо css масштабирования, затем используйте drawImage, чтобы растянуть изображение до размера. Разумеется, вам нужно будет следить за ручным масштабированием и соответствующим образом скорректировать положение мыши. – Frank

ответ

5

Координаты мыши никогда не масштабируются.

Таким образом, вы должны масштабировать координаты мыши, чтобы они отражали масштабируемый холст.

Вот один из способов сделать ваш холст отзывчивым и получить масштабируемую мышь координаты:

// 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>

Смежные вопросы