JavaScript-gebaseerde animaties met Anime.js, deel 4 callbacks, easings en SVG

Na het voltooien van de eerste drie handleidingen van de serie, zou je nu heel comfortabel moeten zijn met veel Anime.js-functies. De eerste tutorial liet je zien hoe je doelelementen selecteert. In de tweede zelfstudie leer je over verschillende soorten parameters die kunnen worden gebruikt om fijne controle te hebben over de vertraging en duur van animaties van verschillende elementen. De derde zelfstudie was gericht op het leren hoe je meer controle kunt krijgen over de waarden van één enkele eigenschap in de loop van de animatie.

In deze zelfstudie leert u over verschillende callbacks die kunnen worden gebruikt om een ​​functie uit te voeren op basis van de voortgang van de animatie. Bijna elk voorbeeld in de vorige tutorials gebruikte CSS-eigenschappen om aan te tonen hoe verschillende methoden en parameters werken. Dit kan u het idee hebben gegeven dat de bibliotheek meer geschikt is voor het animeren van CSS-eigenschappen. Deze keer hebben we een sectie gewijd aan het maken van interessante SVG-gerelateerde animaties in Anime.js.

callbacks

Zoals ik al zei in de inleiding, kunt u callbacks gebruiken om functies uit te voeren op basis van de voortgang van de animatie. Er zijn vier verschillende callbacks: beginnen, rennen, bijwerken, en compleet. Elke callback-functie wordt op een specifiek tijdstip afgevuurd en iedereen accepteert een animatie-object als argument. 

De beginnen() functie wordt aangeroepen wanneer de animatie daadwerkelijk begint. Dit betekent dat als een animatie een vertraging van 800 ms heeft, beginnen() wordt pas gebeld nadat die vertraging voorbij is. U kunt controleren of een animatie is begonnen met spelen of niet animationName.begin, die zal terugkeren waar of vals respectievelijk.

De rennen callback kan worden gebruikt om een ​​functie in elk frame uit te voeren nadat een animatie daadwerkelijk begint te spelen. Als u vanaf elk begin van de animatie een functie in elk frame wilt uitvoeren, ongeacht de animatie vertraging, je zou de bijwerken callback in plaats daarvan.

De compleet terugbellen lijkt op beginnen behalve dat het wordt genoemd als de animatie is afgelopen. Net als beginnen, je kunt gebruiken animationName.complete om te controleren of een animatie al dan niet is afgespeeld.

U hebt in de eerste zelfstudie al gezien hoe u de bijwerken terugbellen tijdens het animeren van numerieke waarden van een JavaScript-object. In deze zelfstudie zullen we dat voorbeeld aanpassen en zien hoe we al deze callbacks samen kunnen gebruiken om meer informatie aan de gebruiker te geven.

var filesScanned = count: 0, infected: 0; var scanCount = document.querySelector (". scan-count"); var besmet = document.querySelector (". besmet-count"); var scanning = anime (targets: filesScanned, autoplay: false, count: 100, infected: 8, delay: 1000, duration: 2000, easing: "linear", round: 1, update: function (anim) if (anim .huidige tijd < 1000)  document.querySelector(".update-cb").innerHTML = "Creating an Index… ";  , begin: function()  document.querySelector(".begin-cb").innerHTML = "Starting the Scan… "; , run: function()  scanCount.innerHTML = filesScanned.count; infected.innerHTML = filesScanned.infected; , complete: function()  document.querySelector(".complete-cb").innerHTML = "Scan Complete… ";  );

Ik heb opzettelijk enige vertraging in deze animatie toegevoegd, zodat we het verschil in de timing van de uitvoering van verschillende callbacks kunnen opmerken. De bijwerken callback begint zijn functie uit te voeren zodra de animatie-instance begint. 

De daadwerkelijke animatie begint na 1000 ms te spelen en dat is wanneer de beginnen functie toont het bericht "Bezig met starten van de scan ..." voor de gebruiker. De rennen De functie begint ook tegelijkertijd te werken en werkt de numerieke waarden van het object na elk frame bij. Zodra de animatie is voltooid, is de compleet callback toont een "Scan Complete ..." -bericht voor de gebruiker.

Functies versmallen

Verlichtingsfuncties kunnen worden gebruikt om te bepalen hoe de waarde van een eigenschap overgaat van de beginwaarde naar de uiteindelijke waarde. Deze easing-functies kunnen worden opgegeven met de easing-parameter, die zowel strings als aangepaste Bézier-curvecoördinaten (in de vorm van een array) kan accepteren. 

Er zijn 31 verschillende ingebouwde easing-functies. Een van hen is lineair, en de andere 30 bestaan ​​uit tien verschillende variaties van easeIn, easeOut, en easeInOut. Er worden drie elastische versnellingsvergelijkingen aangeroepen easeInElasticeaseOutElastic, en easeInOutElastic. U kunt hun elasticiteit regelen met behulp van de elasticiteit parameter. De waarde van elasticiteit kan ergens tussen 0 en 1000 zijn.

easeIn vergelijkingen versnellen de waardeverandering van de eigenschap vanaf nul. Dit betekent dat de verandering in waarde in het begin langzaam zou zijn en zeer snel aan het einde. De snelheid van verandering is nul in het begin en maximum aan het einde. easeOut vergelijkingen vertragen de waardeverandering van de eigenschap vanaf de maximale snelheidswijziging. 

Dit betekent dat de waardewijziging in het begin erg snel zal zijn en aan het eind erg traag. easeInOut vergelijkingen versnellen de snelheidsverandering in het begin en vertragen deze aan het einde. Dit betekent dat de snelheid van verandering zowel in het begin als het einde traag is, en het zal het snelst zijn in het midden van de animatie. De volgende demo toont het verschil in de snelheid van verandering voor elk van deze versnellingsfuncties.

U kunt ook uw eigen aangepaste easing-functies toevoegen aan de ingebouwde lijst met behulp van anime.easings. Hier is een voorbeeld van het maken van aangepaste easing-functies.

anime.easings ['tanCube'] = functie (t) return Math.pow (Math.tan (t * Math.PI / 4), 3);  anime.easings ['tanSqr'] = functie (t) return Math.pow (Math.tan (t * Math.PI / 4), 2);  var tanCubeSequence = anime (targets: '.tan-cube', translateX: '75vw', duur: 2000, easing: 'tanCube', autoplay: false); var tanSqrSequence = anime (targets: '.tan-sqr', translateX: '75vw', duur: 2000, easing: 'tanSqr', autoplay: false);

SVG-gebaseerde animaties

Alle bewegingsgerelateerde animaties die we tot nu toe hebben gemaakt, hebben de doelelementen in rechte lijnen verplaatst. Het is ook mogelijk in Anime.js om een ​​element langs een complex SVG-pad te verplaatsen met veel rondingen. U kunt zowel de positie als de hoek van de bewegende elementen op het pad bepalen. Om een ​​element naar de x-coördinaat van het pad te verplaatsen, kunt u gebruiken path (x). Evenzo kan een element worden verplaatst volgens de y-coördinaat van het pad met path (y)

Tenzij het pad een rechte lijn is, zal het bijna altijd een hoek vormen ten opzichte van de horizontale basislijn. Als u een niet-cirkelvormig element roteert, zal het natuurlijker aanvoelen als het element de hoek van het pad volgt. U kunt dit doen door de draaien eigenschap gelijk te zijn aan path ( 'angle). Hier is de code die vier elementen met verschillende versnellingswaarden langs een SVG-pad animeert.

var path = anime.path ('path'); var easings = ['linear', 'easeInCubic', 'easeOutCubic', 'easeInOutCubic']; var motionPath = anime (targets: '.square', translateX: path ('x'), translateY: path ('y'), rotate: path ('angle'), easing: function (el, i) ga terug opheffingen [i];, duur: 10000, loop: true);

Je kunt in de volgende demo zien dat het rode vierkantje met easeInCubic versnelling is in het begin het langzaamst en het snelst aan het einde. Evenzo is het oranje vierkant met easeOutCubic is de snelste in het begin en de langzaamste aan het einde.

Je kunt ook de morphing van verschillende SVG-shapes in elkaar animeren met Anime.js. De enige voorwaarde is dat beide vormen hetzelfde aantal punten moeten hebben. Dit betekent dat je alleen driehoeken in andere driehoeken en vierhoeken naar andere vierhoeken kunt morphen. Als u probeert te morphen tussen een ongelijk aantal polygoonpunten, resulteert dit in een abrupte vormverandering. Hier is een voorbeeld van het morphen van een driehoekige vorm.

var morphing = anime (targets: 'polygon', punten: [value: '143 31 21 196 286 223', value: '243 31 21 196 286 223', value: '243 31 121 196 286 223 ', value:' 243 31 121 196 386 223 ', value:' 543 31 121 196 386 223 '], easing:' linear ', duration: 4000, richting:' alternate ', loop: true ); 

Nog een interessant effect dat u met SVG kunt maken, is lijntekening. Het enige dat u hoeft te doen is Anime.js het pad geven dat u wilt gebruiken voor lijntekening en andere parameters die de duur, vertraging of versoepeling regelen. In de volgende demo heb ik de compleet callback om de lijntekening van het Font Awesome ankerpictogram met een gele kleur te vullen.

var lineDrawing = anime (targets: 'path', strokeDashoffset: [anime.setDashoffset, 0], easing: 'easeInOutCubic', duur: 4000, voltooid: function (anim) document.querySelector ('path'). setAttribute ( "vullen", "geel"););

Door de kennis van alle concepten die u tot nu toe hebt geleerd te combineren, kunt u complexere lijntekeningen maken met veel betere controle over de manier waarop ze worden getekend. Hier is een voorbeeld waarin ik mijn eigen naam heb geschreven met behulp van SVG.

var letterTime = 2000; var lineDrawing = anime (targets: "path", strokeDashoffset: [anime.setDashoffset, 0], easing: "easeInOutCubic", duration: letterTime, delay: function (el, i) return letterTime * i;, begin: function (anim) var letters = document.querySelectorAll ("path"), i; for (i = 0; i < letters.length; ++i)  letters[i].setAttribute("stroke", "black"); letters[i].setAttribute("fill", "none");  , update: function(anim)  if (anim.currentTime >= letterTime) document.querySelector (". letter-m"). setAttribute ("fill", "# e91e63");  if (anim.currentTime> = 2 * letterTime) document.querySelector (". letter-o"). setAttribute ("fill", "# 3F51B5");  if (anim.currentTime> = 3 * letterTime) document.querySelector (". letter-n"). setAttribute ("fill", "# 8BC34A");  if (anim.currentTime> = 4 * letterTime) document.querySelector (". letter-t"). setAttribute ("fill", "# FF5722");  if (anim.currentTime> = 5 * letterTime) document.querySelector (". letter-y"). setAttribute ("fill", "# 795548"); , autoplay: false); 

Ik begin met het toewijzen van de waarde 2000 aan de variabele letterTime. Dit is de tijd die ik Anime.js wil geven, terwijl het elke letter van mijn naam tekent. De vertraging eigenschap gebruikt de functie-gebaseerde indexparameter om een ​​geschikte in te stellen vertraging waarde met behulp van de letterTime veranderlijk. 

De index van de eerste letter "M" is nul, dus Anime.js begint deze meteen te tekenen. De letter "O" heeft een vertraging van 2000ms, omdat dit de tijd is die nodig is om de letter "M" volledig te tekenen.

Binnen in de beginnen callback, ik heb de beroerte waarde van alle letters in zwart en hun vullen waarden voor geen. Op deze manier kunnen we alle kleurwaarden wissen die in de bijwerken terugbellen zodat de letters naar hun oorspronkelijke status kunnen terugkeren wanneer ze in meerdere lussen worden uitgevoerd. Klik op de Schrijf de naam knop in de volgende demo om de code in actie te zien.

Laatste gedachten

In deze zelfstudie hebt u verschillende callback-functies geleerd die kunnen worden gebruikt om taken uit te voeren zoals het bijwerken van de DOM of het wijzigen van de waarde van een attribuut op basis van de voortgang van de animatie. Je hebt ook geleerd over verschillende easing-functies en hoe je er een van je eigen kunt maken. Het laatste deel van de zelfstudie was gericht op het maken van SVG-gebaseerde animaties.

Na het voltooien van alle vier de tutorials van de serie, zou je nu genoeg kennis van Anime.js moeten hebben om een ​​aantal interessante effecten voor je volgende project te creëren. Als je nog vragen hebt over deze tutorial, laat het me dan weten in de comments.