2014-09-24 3 views
1

Мне нужно отслеживать положение мыши относительно элемента <canvas> в моем приложении. В настоящее время у меня есть прослушиватель событий mousemove, прикрепленный к <canvas>, который обновляет положение мыши всякий раз, когда он срабатывает, используя offsetX/offsetY, если доступно, или layerX/layerY, когда offsetX/Y недоступен. Использование offsetX/Y или layerX/Y дает мне координаты мыши относительно моего <canvas>, что я и хочу. Поскольку мое приложение работает над своей магией, различные 3D-преобразования 3D применяются к <canvas>, и даже когда <canvas> очень сильно преобразуется, offsetX/Y по-прежнему дает мне точные координаты в локальном преобразованном координатном пространстве <canvas>.Отслеживание относительной позиции мыши без события mousemove

Это путаница, поэтому я попытаюсь указать пример. Если мой <canvas> имеет ширину и высоту 100px и расположен в (0,0) по отношению к окну просмотра обозревателя, и я нажимаю на (50,50) (в видовых окнах), что соответствует (50,50) в my <canvas>, а 50 - это значение, которое (правильно) возвращается через offsetX и offsetY. Если я затем применим transform: translate3d(20px,20px,0px) к моему <canvas> и щелкните по (50,50) (в окнах просмотра), так как мой холст сдвинут на 20 пикселей вниз и 20 пикселей справа, что фактически соответствует (30,30) относительно <canvas>, и 30 - это значение, которое (правильно) возвращается через offsetX и offsetY.

Проблема, с которой я столкнулся, заключается в том, что делать, когда пользователь физически не перемещает мышь, но преобразовывается <canvas>. Я только обновляю положение мыши на событиях mousemove, поэтому что делать, если нет mousemove?

Например. Моя мышь расположена на (50,50), и никакие преобразования не применяются к <canvas>. Мои this.mouseX и this.mouseY равны 50; они были сохранены в финальном событии mousemove, когда я переместил мышь (50, 50). Не перемещая мышь вообще, я применяю вышеуказанное преобразование (transform: translate3d(20px,20px,0px)) к моему <canvas>. Теперь мне нужно, чтобы this.mouseX и this.mouseY были равны 30, так как это новое положение моей мыши относительно текущего преобразования <canvas>. Но this.mouseX и this.mouseY по-прежнему равны 50. Поскольку я никогда не двигал мышью, не было никакого события mousemove, и эти сохраненные координаты никогда не обновлялись.

Как я могу справиться с этим? Я думал о создании нового события jQuery, вручную присваивая некоторые свойства (pageX и pageY?) На основе моей старой/предыдущей позиции мыши, а затем запуская это событие, но я не думаю, что это заставит браузер пересчитать offsetX и offsetY. Я также думал о том, чтобы взять известную старую/предыдущую позицию мыши и умножить ее на мою матрицу преобразования, но это будет очень сложно, так как мои координаты мыши находятся в 2d-пространстве, но преобразования, которые я применяю к <canvas>, являются все трехмерные преобразования.

Я думаю, действительно, что я хочу сделать, это взять мою известную позицию 2d-страницы и раскинуть ее в 3D-пространстве и выяснить, где я нахожусь в преобразованном <canvas>, все в javascript (доступно jQuery).

Возможно ли это? Это даже имеет смысл?

+0

Если вы хотите получить «новые» координаты мыши без перемещения мыши - тогда я думаю, вам придется взять ваши «старые» координаты (из последнего события mousemove) и «применить» преобразование к этим значениям самостоятельно вычислить, какими должны быть правильные «новые» координаты. – CBroe

+0

@ CBroe Я действительно надеялся избежать этого, но, возможно, вы правы ... –

ответ

0

Похоже, вы хотите обновить свои значения указателя мыши, даже если вы не перемещаете мышь.Вы должны попробовать что-то вроде этого:

var event = ''; 
var counter = 1; 

$(function(e){ 
    event = e; 
    window.setInterval(refresh, 10); 
}); 

$(document).mousemove(function(e){ 
    event = e; 
    refresh; 
}); 

function refresh(){ 
    counter++; 
    $('#mousepos').val("event.pageX: " + event.pageX + ", event.pageY: " + event.pageY + ", counter: " + counter) 
} 

Счетчик предназначен для визуализации обновления. Вы можете установить интервал на все, что вы хотите (10 = 10 мс = 0,01 с). Просто переместите все из вашего .mousemove() в эту функцию refresh() и вызовите его правильно, и ваша позиция мыши должна обновиться, даже если вы не двигаетесь вашей мыши.

Посмотрите на эту скрипку на примере жизни: http://jsfiddle.net/82cmxw8L/1

EDIT:

Потому что моя скрипка не работал на спрашивающего, я обновил его: http://jsfiddle.net/82cmxw8L/8/

Новое в том, что теперь позиция мыши устанавливается каждые 0,1 секунды, независимо от того, что, а не обновляется только при перемещении мыши.

+0

Спасибо за предложение, но, к сожалению, похоже, что это не будет работать для моих целей. Я немного изменил ваш jsfiddle, чтобы проверить его. Я добавил поле, которое скользит вправо, когда вы наводите на него курсор, и прикрепляло событие к этому окну вместо документа, а когда вы наводите курсор на поле и его слайды, вы можете видеть, что значения offsetX и offsetY (позиция мыши относительно div, а не страницы) НЕ обновляются, пока вы на самом деле не переместите мышь. –

+0

Я обновил свой ответ. Теперь он должен работать так, как вы ожидали. – WcPc

1

Работает во всех браузерах

var mouseX=0; 
var mouseY=0; 
var canvas = document.querySelector('#canvas'); 
var rect = canvas.getBoundingClientRect(); 
document.onmousemove = function(e) { 
     mouseX=e.clientX-rect.left; 
     mouseY=e.clientY-rect.top; 
}; 
function updateCoords() { 
     mouseX=e.clientX-mouseX; 
     mouseY=e.clientY-mouseY; 
     setTimeout(updatecoords,10); 
} 

Теперь мы можем вызвать функцию updateCoords() один раз, чтобы повторно проверить новую позицию.

updateCoords(); 

Вы можете добавить свой код в функции updateCoords() и он будет выполняться каждые 10 миллисекунд

Концепция: mouseX и mouseY переменные обновляются на mousemove события, а также обновляется, когда есть какие-либо изменения в положение холста.

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