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

141
Vistas
Rendimiento de HTML Canvas clearRect y Redraw

Estoy creando un tablero de dibujo basado en la web. Parte de la funcionalidad de esto es dibujar formas (como líneas).

Me encuentro en la necesidad de realizar un seguimiento de todos los puntos dibujados en el lienzo en una matriz. Específicamente porque necesito despejar el tablero y volver a dibujar los puntos al dibujar líneas y otras formas para que se sienta "interactivo". Para aclarar la funcionalidad, he creado este JSFiddle https://jsfiddle.net/hwa95rcx/35/

HTML:

 <canvas id="test" width="500" height="500"> </canvas>

JavaScript:

 let lineStartX = 0; let lineStartY = 0; const drawingPoints = []; let mouseDown = false; const c = document.getElementById("test"); const ctx = c.getContext("2d"); c.onmousedown = (e) => { lineStartX = e.clientX; lineStartY = e.clientY; mouseDown = true; } c.onmousemove = (e) => { if (mouseDown) { ctx.beginPath(); ctx.clearRect(0, 0, 500, 500); redraw(); ctx.moveTo(lineStartX, lineStartY); ctx.lineTo(e.clientX, e.clientY); ctx.stroke(); } } c.onmouseup = (e) => { mouseDown = false; drawingPoints.push({ startX: lineStartX, startY: lineStartY, lineEndX: e.clientX, lineEndY: e.clientY }); } function redraw() { drawingPoints.forEach(el => { ctx.moveTo(el.startX, el.startY); ctx.lineTo(el.lineEndX, el.lineEndY); ctx.stroke() }); }

eso ejemplifica la razón por la que necesito almacenar una serie de puntos para volver a dibujar.

Me gustaría evitar hacer esto porque con grandes cantidades de datos, el dibujo se ralentiza o incluso falla porque estamos recorriendo todos los puntos para volver a dibujarlos. ¿Existe una forma más efectiva de lograr este efecto de dibujo de formas interactivas que estoy buscando?

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

0

Su función de redraw llama a stroke() para cada subsegmento, pero nunca llama a beginPath() . Esto significa que cuando tiene dos subsegmentos, el primero se pintará en su propio turno, y luego nuevamente cuando el segundo subsegmento llame a stroke() .
Puede ver esto con bastante claridad al observar sus primeros trazos y cómo su antialiasing oscurece la mayor parte de los subsegmentos que hay.
En realidad, le está pidiendo a la computadora que represente magnitudes de más elementos de los necesarios, esto es lo que hace que su aplicación sea lenta y, finalmente, se bloquee.

Por lo tanto, podría llamar a beginPath() en el bucle, pero lo mejor es eliminar completamente stroke() de allí. De esta manera, en cada cuadro solo pintas un solo camino. La GPU solo tiene que hacer una sola operación y debería estar bien para días de dibujos.

 let lineStartX = 0; let lineStartY = 0; const drawingPoints = []; let mouseDown = false; const c = document.getElementById("test"); const ctx = c.getContext("2d"); c.onmousedown = (e) => { lineStartX = e.clientX; lineStartY = e.clientY; mouseDown = true; } c.onmousemove = (e) => { if (mouseDown) { ctx.beginPath(); ctx.clearRect(0, 0, 500, 500); redraw(); ctx.moveTo(lineStartX, lineStartY); ctx.lineTo(e.clientX, e.clientY); ctx.stroke(); } } c.onmouseup = (e) => { mouseDown = false; drawingPoints.push({ startX: lineStartX, startY: lineStartY, lineEndX: e.clientX, lineEndY: e.clientY }); } function redraw() { // 'redraw' only traces the previous sub-segments drawingPoints.forEach(el => { ctx.moveTo(el.startX, el.startY); ctx.lineTo(el.lineEndX, el.lineEndY); }); }
 <canvas id="test" width="500" height="500"></canvas>

Tenga en cuenta que si mide que incluso el trazado requiere algo de tiempo de cálculo (aunque esto sería sorprendente), puede intentar almacenar la ruta secundaria en un objeto Path2D en lugar de llamar a los métodos de dibujo cada vez:

 let lineStartX = 0; let lineStartY = 0; const path = new Path2D(); let mouseDown = false; const c = document.getElementById("test"); const ctx = c.getContext("2d"); c.onmousedown = (e) => { lineStartX = e.clientX; lineStartY = e.clientY; mouseDown = true; } c.onmousemove = (e) => { if (mouseDown) { ctx.beginPath(); ctx.clearRect(0, 0, 500, 500); redraw(); ctx.moveTo(lineStartX, lineStartY); ctx.lineTo(e.clientX, e.clientY); ctx.stroke(); } } c.onmouseup = (e) => { mouseDown = false; path.moveTo(lineStartX, lineStartY); path.lineTo(e.clientX, e.clientY); } function redraw() { ctx.stroke(path); }
 <canvas id="test" width="500" height="500"></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