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

177
Vistas
¿Cómo dibujar una fracción de una curva bezier con lienzo?

Digamos que tengo una curva bezier producida a partir del siguiente código:

 const ctx = document.querySelector('canvas').getContext('2d'); ctx.beginPath(); ctx.moveTo(50, 20); ctx.quadraticCurveTo(230, 30, 50, 100); ctx.stroke();
 <canvas></canvas>

¿Hay alguna manera de dibujar solo, digamos, el último 90%?

Para mi aplicación, quiero "consumir" la curva y crear una animación en la que un círculo se mueva a lo largo de la ruta de la línea, comiendo la curva en el camino.

Lo único que se me ocurrió fue, en lugar de dibujar la curva con la función quadraticCurveTo , calcular una enorme lista de puntos manualmente a través de la siguiente función:

 t = 0.5; // given example value x = (1 - t) * (1 - t) * p[0].x + 2 * (1 - t) * t * p[1].x + t * t * p[2].x; y = (1 - t) * (1 - t) * p[0].y + 2 * (1 - t) * t * p[1].y + t * t * p[2].y;

Y luego solo haz moveTo y lineTo para cada uno de los 300 o más puntos.

Pero eso tiene tres problemas:

  1. Es computacionalmente costoso
  2. ¿Cómo determinas cuántos puntos calcular?
  3. ¿No seguirá siendo irregular a menos que calcule miles de puntos?

¿Hay una mejor manera?

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

0

Puede usar ctx.setLineDash([]) con ctx.lineDashOffset , esa es la forma común de simular el dibujo parcial de rutas.

 const ctx = document.querySelector('canvas').getContext('2d'); animate(); function animate(){ let i = 0; drawCurve(i); function drawCurve(start){ ctx.clearRect(0,0,300,150); // initial width and height of canvas const line_len = 204; // to let the last part of curve stay ctx.setLineDash([1000]); // bigger than curve length ctx.lineDashOffset = -start; // changing parameter ctx.beginPath(); ctx.moveTo(50, 20); ctx.quadraticCurveTo(230, 30, 50, 100); ctx.stroke(); const anim_id = requestAnimationFrame(() => drawCurve(++start)); if(start > line_len) cancelAnimationFrame(anim_id); } }
 <canvas></canvas>

Puede ser complicado obtener la longitud del camino en el lienzo. Así que prefiero calcularlo usando SVG oculto. La <path> tiene el atributo d vacío. Entonces puedo asignarle nuestra cadena de ruta y getTotalLength() de ella. Ahora tenemos la longitud de su ruta y podemos usar esos datos para definir la matriz setLineDash correctamente, por lo que path_len (dónde detenerse).

También podemos obtener la posición actual del inicio de la ruta utilizando el método path.getPointAtLength().

 animate(); function animate(){ const path = document.querySelector('svg > path'); const path_string = 'M 50 20 Q 230 30 50 100'; path.setAttribute('d', path_string); const path_len = path.getTotalLength(); const ctx = document.querySelector('canvas').getContext('2d'); drawCurve(0); function drawCurve(start){ ctx.clearRect(0,0,300,150); // initial width and height of canvas ctx.save(); ctx.setLineDash([path_len + 1]); // bigger than curve length ctx.lineDashOffset = -start; // changing parameter ctx.stroke(new Path2D(path_string)); ctx.restore(); const cur_pos = path.getPointAtLength(start - 7); // current position - (radius + 2) ctx.beginPath(); ctx.arc(cur_pos.x, cur_pos.y, 5, 0, 2*Math.PI, false); // radius = 5 (should be a constant) ctx.fill(); const anim_id = requestAnimationFrame(() => drawCurve(++start)); if(start > path_len) cancelAnimationFrame(anim_id); } }
 <svg style="display:none"> <path d=""></path> </svg> <canvas></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