Je voudrais partager avec vous l'effet de l'image ci-dessous que j'ai récemment mis en œuvre.
Si on veut dessiner l'animation de la courbe ci-dessous
Si vous tracez une courte ligne pour vous connecter à chaque fois, l'image ci-dessous est divisée en cinq segments.
Lire dix autres paragraphes
Si le nombre de segments divisés est suffisant, dessiner un segment à la fois ressemblera à une trajectoire courbe.
courbe de Bézier quadratique/** * Animation de la courbe de Bézier quadratique* @param {Array<number>} coordonnées du point de départ* @param {Array<number>} coordonnées du point de courbure (c'est-à-dire le point d'inflexion, pas les coordonnées exactes, juste la direction approximative) * @param {Array<number>} coordonnées du point final * @param {number} pourcentage de dessin en pourcentage (0-100) */ function drawCurvePath(start, point, end, percent){ ctx.beginPath(); //Commencer à tracer des lignes ctx.moveTo(start[0], start[1]); //Déplacez le stylo jusqu'au point de départ pour (var t = 0; t <= percent / 100; t += 0,005 ) { //Obtenir les coordonnées de chaque point temporel var x = quadraticBezier(start[0], point[0], end[0], t); quadraticBezier(start[1], point[1], end[1], t); ctx.lineTo(x, y); //Trace une ligne droite du point temporel précédent au point temporel actuel} ctx.stroke( ); //Course} /** * Équation quadratique de la courbe de Bézier* @param {Array<number>} point de départ* @param {Array<number>} point de courbure* @param {Array<number>} point final * @param {numéro} progression du dessin (0-1) */ function quadraticBezier(p0, p1, p2, t) { var k = 1 - t; return k * k * p0 + 2 * (1 - t) * t * p1 + t * t * p2 ;
Pour un contenu plus détaillé de la courbe de Bézier, veuillez vous référer à ce blog
en code complet
<!DOCTYPE html><html lang=en><head> <meta charset=UTF-8> <meta name=viewport content=width=device-width, initial-scale=1.0> <meta http-equiv=X-UA -Compatible content=ie=edge> <title>Animation de courbe de Bézier quadratique</title> <style> body { background : #0f1632 } #canvas { border : 1px solid #ccc; } #img { display: none; <!--Cachez simplement l'img directement, elle sera citée directement plus tard--> } </style></head><body> <canvas id=canvas width =1500 hauteur =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 percent = 0; var data = { start: [400, 200], point: [ 300, 100], fin : [100, 400], département : 'données 1', valeur : 4321 } fonction init(){ percent = 0; //Réinitialise le processus à chaque fois draw(); } function draw(){ ctx.clearRect(0, 0, 1500, 750); //Efface le canevas à chaque fois ctx.strokeStyle = ' # ffffff'; //Définit le style de ligne drawCurvePath(data.start, data.point, data.end, percent); //À mesure que le processus augmente, cela contrôle la vitesse d'animation if (percent <= 100) { //Continuez à appeler si le dessin n'est pas terminé. Si le dessin est terminé, la progression sera réinitialisée requestAnimationFrame(draw); }else{ init() } } function drawCurvePath(start, point, end, percent) / /... } fonction quadraticBezier( p0, p1, p2, t) { //... } </script></body></html>
L'animation sort
Comme mentionné précédemment, le paramètre point
dans drawCurvePath(start, point, end, percent)
n'est pas un point de courbure spécifique, mais une direction générale.
Jetons un coup d'œil à la situation lorsque point
est changé en [200,200]
Si vous souhaitez obtenir l'effet de chute, vous devez ajouter un effet de dégradé à la ligne de haut en bas, de loin vers près.
/** * Créer un dégradé linéaire* @param {Array<number>} start point de départ* @param {Array<number>} point de courbure* @param {Array<number>} end end point* @param {number} dessin progrès ( 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);//La fonction draw nécessite quelques ajustements function draw(){ // ctx.StrokeStyle = '#ffffff'; ctx.StrokeStyle = createLinearGradient(data.start, data.end, 'rgba(255,255,255,.2)', '#fff' ); //...}
Pour plus de détails sur le dégradé de toile, veuillez vous référer à MDN
Auréole de tête Pour ajouter un halo de tête, vous devez dessiner un cercle et définir un dégradé radial. Utilisez la fonction drawCurvePath
pour obtenir x, y et réinitialiser la position du cercle.
function createHeadLight(x,y){ ctx.beginPath(); //Créer un dégradé radial var radialGradient = ctx.createRadialGradient(x, y, 0, x, y, 20); )); radialGradient.addColorStop(.2, rgba(255,255,255,.8)); radialGradient.addColorStop(1, transparent); ctx.fillStyle = radialGradient; //Dessine un cercle ctx.arc(x, y, 20, 0, 2 * Math .PI, faux); ctx.fill();}//La fonction drawCurvePath nécessite quelques ajustements function drawCurvePath(start, point, end, percent){ //... ctx.stroke(); // Stroke createHeadLight(x,y) // Draw un cercle, c'est comme dessiner une fréquence linéaire}
Pour plus de détails arc
pour dessiner des cercles, veuillez vous référer à MDN
L'ajout de texte est très similaire à l'ajout d'un halo de tête. Les deux utilisent la fonction drawCurvePath
pour obtenir x, y et réinitialiser la position du bloc de texte.
/** * Créer du texte* @param {String} données du département* @param {Number} data* @param {Number} coordonnée de l'axe x* @param {Number} coordonnée de l'axe y*/function drawText(department, value, x, y) { ctx.fillStyle = '#fff' ctx.font = 22px Microsoft Yahei; ctx.fillText(département, x + 30, y + 20); //Afin de placer le texte dans le coin inférieur droit du halo x, l'axe y doit être décalé d'une certaine distance var width = ctx.measureText(value).width; du texte ctx.fillStyle = createLinearGradient([x + 30, 0], //La plage de rendu de l'axe x du dégradé de texte est [x+30,x+30+text width], [x + 30 + width, 0], //Ici, y est défini sur 0 car il n'y a pas d'API pour obtenir la hauteur du texte. L'écriture de 0 est également acceptable '#fffd00', '#ff6d00' ); 50 ); } //La fonction drawCurvePath nécessite quelques ajustements function drawCurvePath(start, point, end, percent, Department, value) { //... createHeadLight(x,y) drawText(département, valeur, x, y) }Ajoutez du texte et des images à la position finale une fois l'animation terminée
Veuillez noter que lors de l'ajout de texte et d'images une fois l'animation terminée, vous devez nettoyer le canevas immédiatement après la fin de l'animation de la courbe, puis ajouter du texte et des images.
/** * Créer une image* @param {Numéro} Coordonnée sur l'axe x* @param {Numéro} Coordonnée sur l'axe y*/function drawImg(x, y) { ctx.drawImage(img, x - img.width / 2, y - img.height); }//La fonction de dessin nécessite quelques ajustements draw(){ //... if (percent <= 100) { requestAnimationFrame(draw); }else{ ctx.clearRect(0, 0, 1500, 750); //Effacer le canevas immédiatement après la fin de l'animation de la courbe drawText(data.department, //Render le texte data.value, data.end[0], data .end[1 ]) drawImg(data.end[0], data.end[1]) //Rend l'image setTimeout(function(){ //Redessine init() après 2000 ms },2000) } }Finition
Le code complet de cet exemple
Le code complet de l'exemple dans la première image de l'article
Article de référence : Utiliser Canvas pour dessiner une animation de courbe - compréhension approfondie des courbes de Bézier
Ce qui précède représente l’intégralité du contenu de cet article. J’espère qu’il sera utile à l’étude de chacun. J’espère également que tout le monde soutiendra le réseau VeVb Wulin.