Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

161
Vistas
Large delay between Canvas `pointerdown` and `pointermove` events with stylus

I'm trying to create a very basic sketch pad using an HTML Canvas and pointer events. I've implemented a very basic codepen that demonstrates the issue at hand. The key functionality draws a red dot upon pointerdown events and a blue dot on pointermove events:

c.addEventListener('pointerdown', event => {
  event.preventDefault();
  updatePosition(event);
  ctx.fillStyle = 'red';
  ctx.fillRect(position.x - 2, position.y - 2, 4, 4);
  drawing = true;
});

c.addEventListener('pointermove', event => {
  if (!drawing) return;
  event.preventDefault();
  updatePosition(event);
  ctx.fillStyle = 'blue';
  ctx.fillRect(position.x - 2, position.y - 2, 4, 4);
});

Both when using a stylus (a Surface Pen) or just touch, I observe a large gap between the initial pointerdown event and the eventual (good) "stream" of pointermove events, as demonstrated here:

enter image description here

I've observed to varying degrees with multiple input methods on different hardware. Is there a way I can eliminate or mitigate this?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Using the fillRect() method isn't the best choice for 'live' interactive drawing. The reason is, that the pointermove event or any event for that matter has finite precision. That is, if you move your mouse fast enough it won't recognize all positions the pointer might have hit during the movement - it might just be the start and end position.

The usual approach for such a scenario is using the lineTo() method instead as it draws a line from the previous to the current position obtained by e.g. a pointermove event. The thickness of such a line can be controlled using the lineWidth property.

Here's your modified example:

const c = document.getElementById('board');

const compStyle = window.getComputedStyle(c);
const width = parseInt(compStyle.getPropertyValue('width').replace('px', ''));
const height = parseInt(compStyle.getPropertyValue('height').replace('px', ''));

c.width = width;
c.height = height;
const ctx = c.getContext('2d');
ctx.lineWidth = 4;
ctx.lineCap = 'round';

const position = {
  x: 0,
  y: 0
};
const updatePosition = (event) => {
  let rect = event.target.getBoundingClientRect();
  position.x = (event.clientX - rect.left) * (width / rect.width);
  position.y = (event.clientY - rect.top) * (height / rect.height);
}

let drawing = false;

c.addEventListener('pointerdown', event => {
  event.preventDefault();

  updatePosition(event);
  ctx.beginPath();
  ctx.strokeStyle = 'red';
  ctx.moveTo(position.x, position.y)
  ctx.arc(position.x, position.y, ctx.lineWidth / 4, 0, 2 * Math.PI);
  ctx.stroke();
  ctx.strokeStyle = 'blue';
  drawing = true;
});

c.addEventListener('pointermove', event => {
  if (!drawing) return;
  event.preventDefault();
  updatePosition(event);
  ctx.lineTo(position.x, position.y);
  ctx.stroke();
});

c.addEventListener('pointerup', event => {
  ctx.closePath();
  drawing = false;
});
#board {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  touch-action: none;
}
<canvas id="board"></canvas>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda