Gostaria de compartilhar com vocês o efeito da imagem abaixo que implementei recentemente.
Se quisermos desenhar a animação da curva abaixo
Se você desenhar uma linha curta para conectar a cada vez, a imagem abaixo será dividida em cinco segmentos.
Leia mais dez parágrafos
Se o número de segmentos divididos for suficiente, desenhar um segmento de cada vez parecerá uma trajetória curva.
curva bézier quadrática/** * Animação da curva quadrática de Bézier* @param {Array<número>} iniciar coordenadas do ponto inicial* @param {Array<número>} coordenadas do ponto de curvatura (ou seja, o ponto de viragem, não coordenadas exatas, apenas direção aproximada) * @param {Array<número>} coordenadas do ponto final * @param {número} porcentagem de porcentagem de desenho (0-100) */ function drawCurvePath(início, ponto, fim, porcentagem){ ctx.beginPath(); //Começa a desenhar linhas ctx.moveTo(start[0], start[1]); //Move a caneta para o ponto inicial for (var t = 0; t <= percent / 100; t += 0,005) { //Obter as coordenadas de cada ponto no tempo var x = quadraticBezier(start[0], point[0], end[0], t); quadraticBezier(start[1], point[1], end[1], t); ctx.lineTo(x, y); //Desenha uma linha reta do ponto no tempo anterior até o ponto no tempo atual} ctx.stroke( ); //Stroke} /** * Equação da curva quadrática de Bézier* @param {Array<número>} ponto inicial* @param {Array<número>} ponto de curvatura* @param {Array<número>} ponto final * @param {número} progresso do desenho (0-1) */ function quadraticBezier(p0, p1, p2, t) { var k = 1 - t retorno k * k * p0 + 2 * (1 - t) * t *; p1 + t * t * p2 }
Para conteúdo mais detalhado da curva de Bézier, consulte este blog
em código completo
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, escala inicial=1.0> <meta http-equiv=X-UA -Conteúdo compatível=ie=edge> <title>Animação da curva quadrática de Bézier</title> <style> body { background: #0f1632 } #canvas { border: 1px solid #ccc; } #img { display: none <!--Basta ocultar a imagem diretamente, ela será citada diretamente mais 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'); 300, 100], fim: [100, 400], departamento: 'dados 1', valor: 4321 } função init(){ percent = 0; //Reinicia o processo a cada vez draw(); } function draw(){ ctx.clearRect(0, 0, 1500, 750); # ffffff'; //Definir o estilo da linha drawCurvePath(data.start, data.point, data.end, percent); //À medida que o processo aumenta, isso controla a velocidade da animação if (percent <= 100) { //Continue chamando se o desenho não for concluído Se o desenho for concluído, o progresso será redefinido requestAnimationFrame(draw); }else{ init() } } function drawCurvePath(start, point, end, percent) / /... } function quadraticBezier( p0, p1, p2, t) { //... } </script></body></html>
A animação sai
Como mencionado anteriormente, o parâmetro point
na função drawCurvePath(start, point, end, percent)
não é um ponto específico de curvatura, mas uma direção geral.
Vamos dar uma olhada na situação quando point
é alterado para [200,200]
Se você deseja obter o efeito de queda, você precisa adicionar um efeito gradiente à linha de cima para baixo, de longe para perto.
/** * Cria um gradiente linear* @param {Array<número>} ponto inicial* @param {Array<número>} ponto de curvatura* @param {Array<número>} ponto final* @param {número} desenho progresso ( 0-1) */function createLinearGradient(start,end,startColor,endColor){ var lineGradient = ctx.createLinearGradient(...start, ...end); lineGradient.addColorStop(0, startColor); // lineGradient.addColorStop(0.3, '#fff'); lineGradient.addColorStop(1, endColor}//A função draw precisa de alguns ajustes function draw(){ // ctx.strokeStyle = '#ffffff'; ctx.strokeStyle = createLinearGradient(data.start, data.end, 'rgba(255,255,255,.2)', '#fff' );
Para obter detalhes sobre gradiente de tela, consulte MDN
Auréola de cabeça Para adicionar um halo na cabeça, você precisa desenhar um círculo e definir um gradiente radial. Use a função drawCurvePath
para obter x, y e redefinir a posição do círculo.
function createHeadLight(x,y){ ctx.beginPath(); //Criar gradiente radial var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, 20); )); radialGradient.addColorStop(.2, rgba(255,255,255,.8)); radialGradient.addColorStop(1, transparente); Matemática .PI, falso); ctx.fill();}//A função drawCurvePath precisa de alguns ajustes function drawCurvePath(start, point, end, percent){ //... ctx.stroke() // Stroke createHeadLight(x,y) // Desenha um círculo como desenhar uma frequência de linha}
Para obter detalhes arc
para desenhar círculos, consulte MDN
Adicionar texto é muito semelhante a adicionar um halo de cabeça. Ambos usam a função drawCurvePath
para obter x, y e redefinir a posição do bloco de texto.
/** * Criar texto* @param {String} dados do departamento* @param {Número} dados* @param {Número} coordenada do eixo x* @param {Número} coordenada do eixo y*/função drawText(departamento, valor, x, y) { ctx.fillStyle = '#fff' ctx.font = 22px Microsoft Yahei; y + 20); //Para fazer o texto no canto inferior direito do halo x, o eixo y precisa ser deslocado em alguma distância var width = ctx.measureText(value).width; do texto ctx.fillStyle = createLinearGradient([x + 30, 0], //O intervalo de renderização do eixo x do gradiente de texto é [x+30,x+30+largura do texto], [x + 30 + largura, 0], //Aqui y é definido como 0 porque não há API para obter a altura do texto. Escrever 0 também é aceitável '#fffd00', '#ff6d00' ); 50 ); } //A função drawCurvePath precisa de alguns ajustes function drawCurvePath(start, point, end, percent, Department, value) { //... createHeadLight(x,y) drawText(departamento, valor, x, y) }Adicione texto e imagens na posição final após a conclusão da animação
Observe que ao adicionar texto e imagens após a conclusão da animação, você precisa limpar a tela imediatamente após a conclusão da animação da curva e, em seguida, adicionar texto e imagens.
/** * Criar imagem* @param {Número} coordenada do eixo x* @param {Número} coordenada do eixo y*/function drawImg(x, y) { ctx.drawImage(img, x - img.width / 2, y - img.height); }//A função draw precisa de alguns ajustes draw(){ //... if (percent <= 100) { requestAnimationFrame(draw); }else{ ctx.clearRect(0, 0, 1500, 750); //Limpa a tela imediatamente após a conclusão da animação da curva drawText(data.department, //Renderizar texto data.value, data.end[0], data .end[1 ]) drawImg(data.end[0], data.end[1]) //Renderizar a imagem setTimeout(function(){ //Redesenhar init() após 2.000 ms },2000) } }Terminar
O código completo deste exemplo
O código completo do exemplo na primeira foto do artigo
Artigo de referência: Use a tela para desenhar uma animação de curva – compreensão aprofundada das curvas de Bézier
O texto acima é todo o conteúdo deste artigo. Espero que seja útil para o estudo de todos. Também espero que todos apoiem a Rede VeVb Wulin.