Есть ли способ ускорить событие 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?

можно ли "запросить" положение мыши в любое время?

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

2 ответов


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

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

затем, как только вы вычислите сплайн, вы можете аппроксимировать его сегментами линии достаточно короткими, чтобы он выглядел гладким, или вы можете пойти на все и написать свой собственный Bresenham алгоритм его рисования.

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


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

trace("Mouse X: " + _xmouse);
trace("Mouse Y: " + _ymouse);