Есть ли способ ускорить событие mousemove?

Я написал небольшой сценарий рисования (холст) для этого веб-сайта: http://scri.ch/

Когда вы нажимаете на документ, каждое mousemove событие в основном выполняет следующее:
- Получить координаты.
- context.lineTo() между этой точкой и предыдущей
- context.stroke() линия

Как видите, если вы перемещаете курсор очень быстро, событие запускается недостаточно (в зависимости от вашего процессора / браузера и т. Д.), И отображается прямая линия.

В псевдокоде:

window.addEventListener('mousemove', function(e){
  myContext.lineTo(e.pageX, e.pageY);
  myContext.stroke();
}, false);

Это известная проблема, и решение хорошее, но я хотел бы ее оптимизировать.

Поэтому вместо stroke() каждый раз, когда запускается событие mousemove, я помещаю новые координаты в очередь массива и регулярно рисую / очищаю ее с помощью таймера.

В псевдокоде:

var coordsQueue = [];

window.addEventListener('mousemove', function(e){
  coordsQueue.push([e.pageX, e.pageY]);
}, false);

function drawLoop(){
  window.setTimeout(function(){
    var coords;
    while (coords = coordsQueue.shift()) {
      myContext.lineTo(coords[0], coords[1]);
    }
    myContext.stroke();
    drawLoop();
  }, 1000); // For testing purposes
}

Но это не улучшило линию. Поэтому я попытался нарисовать точку только на mousemove. Тот же результат: слишком много места между точками.

Это заставило меня понять, что первый блок кода достаточно эффективен, просто событие mousemove запускается слишком медленно.

Итак, после того, как я потратил некоторое время на реализацию бесполезной оптимизации, настала ваша очередь: есть ли способ оптимизировать скорость запуска mousemove в сценариях DOM?

Можно ли в любой момент «запросить» позицию мыши?

Спасибо за советы!


person bpierre    schedule 16.03.2011    source источник
comment
Дубликат: stackoverflow.com/questions/5258424 /   -  person river    schedule 16.03.2011


Ответы (2)


Если вы хотите увеличить частоту отчетов, боюсь, вам не повезло. Мыши сообщают свою позицию операционной системе только n раз в секунду, и я думаю, что n обычно меньше 100. (Если кто-то может подтвердить это фактическими характеристиками, не стесняйтесь. добавить их!)

Итак, чтобы получить плавную линию, вам нужно придумать какую-то схему интерполяции. По этой теме существует множество литературы; Я рекомендую монотонную кубическую интерполяцию, потому что она локальная, простая в реализации и очень стабильная (без перерегулирования).

Затем, когда вы вычислили сплайн, вы можете аппроксимировать его с помощью отрезков, достаточно коротких, чтобы он выглядел гладко, или вы можете сделать все возможное и написать свой собственный Алгоритм Брезенхема для его рисования.

Если все это того стоит для простого приложения для рисования ... это, конечно, вам решать.

person Thomas    schedule 16.03.2011
comment
Спасибо за ссылки, но да, это было бы немного излишним для этого приложения. Я думаю, что проблема исходит не от ОС (Photoshop намного быстрее), а от браузеров, которые добровольно ограничивают запуск события mousemove, конечно, потому что многие скрипты напрямую полагаются на него для выполнения интенсивных задач. Но почему бы не разрешить авторам запрашивать позицию мыши? Что-то вроде window.getMousePosition()? - person bpierre; 16.03.2011
comment
Редактирование SVG (code.google.com/p/svg-edit) открыто source и явно выполняет некоторые вычисления сглаживания, поэтому вам, вероятно, не нужно воссоздавать колесо. - person jbrookover; 03.04.2011
comment
Нормальные мыши отправляют около 100-150 обновлений в секунду. Мой Logitech G3 отправляет 500 сообщений. Игровые мыши могут отправлять еще больше. - person Paul Groke; 06.04.2011

Классный сайт, к сожалению, нет возможности запросить текущее положение мыши с помощью JavaScript, единственные хуки, которые у вас есть, - это события, которые вы уже используете. Если вам нужно больше контроля, я бы посмотрел на использование вспышки, где вы можете изменить частоту кадров и запросить положение мыши.

trace("Mouse X: " + _xmouse);
trace("Mouse Y: " + _ymouse);
person SavoryBytes    schedule 02.04.2011
comment
Спасибо, но я не буду использовать Flash, я евангелист открытых стандартов! ;-) - person bpierre; 02.04.2011
comment
тогда вы во власти этих стандартов :-) - person SavoryBytes; 02.04.2011
comment
Намного лучше, чем быть во власти Флэша. - person Lightness Races in Orbit; 06.04.2011