Me gustaría compartir con ustedes el efecto de la imagen a continuación que implementé recientemente.
Si queremos dibujar la animación de la curva de abajo
Si dibujas una línea corta para conectar cada vez, la siguiente imagen se divide en cinco segmentos.
Leer diez párrafos más
Si el número de segmentos divididos es suficiente, dibujar un segmento a la vez parecerá una trayectoria curva.
curva de Bézier cuadrática/** * Animación de curva Bézier cuadrática* @param {Array<número>} coordenadas del punto de inicio* @param {Array<número>} coordenadas del punto de curvatura (es decir, el punto de inflexión, no coordenadas exactas, solo dirección aproximada) * @param {Array<número>} coordenadas del punto final * @param {número} porcentaje de dibujo porcentual (0-100) */ function drawCurvePath(inicio, punto, final, porcentaje){ ctx.beginPath(); //Comienza a dibujar líneas ctx.moveTo(start[0], start[1]); //Mueve el lápiz al punto inicial para (var t = 0; t <= percent / 100; t += 0.005 ) { //Obtener las coordenadas de cada punto de tiempo var x = quadraticBezier(start[0], point[0], end[0], var y =); quadraticBezier(start[1], point[1], end[1], t); ctx.lineTo(x, y); //Dibuja una línea recta desde el punto de tiempo anterior hasta el punto de tiempo actual} ctx.stroke( ); //Trazo} /** * Ecuación de curva de Bézier cuadrática* @param {Array<número>} punto inicial* @param {Array<número>} punto de curvatura* @param {Array<número>} punto final * @param {número} progreso del dibujo (0-1) */ function quadraticBezier(p0, p1, p2, t) { var k = 1 - t; return k * k * p0 + 2 * (1 - t) * t * p1 +t*t*p2;
Para obtener contenido más detallado de la curva de Bézier, consulte este blog.
en código completo
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta nombre=viewport content=ancho=ancho-dispositivo, escala-inicial=1.0> <meta http-equiv=X-UA -Contenido compatible = es decir = borde> <título>Animación de curva Bézier cuadrática</título> <estilo> cuerpo {fondo: #0f1632} #canvas {borde: 1px solid #ccc; } #img { display: none; <!--Simplemente oculta la imagen directamente, se citará directamente más tarde--> } </style></head><body> <canvas id=canvas width =1500 altura =750></canvas> <img id=img src=https://s3.imgsha.com/2019/04/22/light.png> <script> var ctx = document.getElementById('canvas').getContext('2d'); var img = document.getElementById('img'); var porcentaje = 0; var datos = { inicio: [400, 200], punto: [ 300, 100], fin: [100, 400], departamento: 'datos 1', valor: 4321 } función init(){ percent = 0; //Restablece el proceso cada vez draw(); } function draw(){ ctx.clearRect(0, 0, 1500, 750); //Borra el lienzo cada vez ctx.strokeStyle = ' # ffffff'; //Establece el estilo de línea drawCurvePath(data.start, data.point, data.end, percent += 0.8); //A medida que aumenta el proceso, esto controla la velocidad de la animación if (percent <=). 100) { //Continuar llamando si el dibujo no se completa. Si el dibujo se completa, el progreso se restablecerá requestAnimationFrame(draw); }else{ init() } } function drawCurvePath(start, point, end, percent) / /... } function quadraticBezier( p0, p1, p2, t) { //... } </script></body></html>
sale la animacion
Como se mencionó anteriormente, el parámetro point
en drawCurvePath(start, point, end, percent)
no es un punto de curvatura específico, sino una dirección general.
Echemos un vistazo a la situación cuando point
se cambia a [200,200]
Si desea lograr el efecto de caída, debe agregar un efecto de degradado a la línea de mayor a menor, de lejos a cerca.
/** * Crear un degradado lineal* @param {Array<número>} punto inicial* @param {Array<número>} punto de curvatura* @param {Array<número>} punto final* @param {número} dibujo progreso (0-1) */función createLinearGradient(inicio,fin,startColor,endColor){ var lineGradient = ctx.createLinearGradient(...inicio, ...fin); lineGradient.addColorStop(0, startColor); // lineGradient.addColorStop(0.3, '#fff'); lineGradient.addColorStop(1, endColor); return lineGradient}//La función de dibujo necesita algunos ajustes function draw(){ // ctx.strokeStyle = '#ffffff'; ctx.strokeStyle = createLinearGradient(datos.inicio, datos.fin, 'rgba(255,255,255,.2)', '#fff' ); //...}
Para obtener detalles sobre el degradado del lienzo, consulte MDN
halo de cabeza Para agregar un halo de cabeza, debe dibujar un círculo y establecer un degradado radial. Utilice la función drawCurvePath
para obtener x, y y restablecer la posición del círculo.
function createHeadLight(x,y){ ctx.beginPath(); //Crear gradiente radial var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, 20); radialGradient.addColorStop(0, rgba(255,255,255, 1); )); radialGradient.addColorStop(.2, rgba(255,255,255,.8)); radialGradient.addColorStop(1, transparente); ctx.fillStyle = radialGradient; //Dibujar un círculo ctx.arc(x, y, 20, 0, 2 * Matemáticas .PI, falso); ctx.fill();}//La función drawCurvePath necesita algunos ajustes function drawCurvePath(start, point, end, percent){ //... ctx.stroke() // Trazo createHeadLight(x,y) // Dibujar un círculo como dibujar una línea de frecuencia}
Para obtener detalles arc
para dibujar círculos, consulte MDN
Agregar texto es muy similar a agregar un halo de cabeza. Ambos usan la función drawCurvePath
para obtener x, y y restablecer la posición del bloque de texto.
/** * Crear texto* @param {Cadena} datos de departamento* @param {Número} datos* @param {Número} coordenada del eje x* @param {Número} coordenada del eje y*/función drawText(departamento, valor, x, y) { ctx.fillStyle = '#fff' ctx.font = 22px Microsoft Yahei; y + 20); // Para hacer que el texto en la esquina inferior derecha del halo sea x, el eje y debe estar desplazado una cierta distancia var width = ctx.measureText(value).width //Obtener el ancho; del texto ctx.fillStyle = createLinearGradient([x + 30, 0], //El rango de representación del eje x del gradiente de texto es [x+30,x+30+text width], [x + 30 + width, 0], // Aquí y se establece en 0 porque no existe una API para obtener la altura del texto. También es aceptable escribir 0 '#fffd00', '#ff6d00' ); 50 ); } //La función drawCurvePath necesita algunos ajustes function drawCurvePath(inicio, punto, fin, porcentaje, departamento, valor) { //... createHeadLight(x,y) drawText(departamento, valor, x, y) }Agregue texto e imágenes en la posición final una vez completada la animación.
Tenga en cuenta que al agregar texto e imágenes después de completar la animación, debe limpiar el lienzo inmediatamente después de completar la animación de la curva y luego agregar texto e imágenes.
/** * Crear imagen* @param {Número} coordenada del eje x* @param {Número} coordenada del eje y*/function drawImg(x, y) { ctx.drawImage(img, x - img.width / 2, y - img.height); }//La función de dibujo necesita algunos ajustes draw(){ //... if (percent <= 100) { requestAnimationFrame(draw); }else{ ctx.clearRect(0, 0, 1500, 750); //Borrar el lienzo inmediatamente después de que se complete la animación de la curva drawText(data.department, //Renderizar texto data.value, data.end[0], data .end[1]) drawImg(data.end[0], data.end[1]) //Renderiza la imagen setTimeout(function(){ //Redibujar init() después de 2000ms },2000) } }Finalizar
El código completo de este ejemplo.
El código completo del ejemplo en la primera imagen del artículo.
Artículo de referencia: Utilice el lienzo para dibujar una animación de curva: comprensión profunda de las curvas de Bézier
Lo anterior es el contenido completo de este artículo. Espero que sea útil para el estudio de todos. También espero que todos apoyen VeVb Wulin Network.