Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

134
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!