Additief Animatie met de Web-Animaties API

0
51

Deze functies zijn niet geland in een stabiele browsers op het moment van schrijven. Echter, alles wat besproken wordt is al in Firefox Nightly standaard en belangrijke onderdelen zijn in Chrome Canary (met de Experimentele Web-Platform Functies vlag ingeschakeld), dus ik raden u aan een van die browsers (bij het lezen van dit artikel) om te zien als veel van de functies in actie mogelijk.

Ongeacht de methode van uw voorkeur van animatie op het web, er zullen tijden zijn dat je wilt laten bewegen hetzelfde pand in afzonderlijke animaties. Misschien heeft u een hover effect dat schaalt een afbeelding en klik op de gebeurtenis die de aanleiding is tot een vertaal — zowel invloed op de transformatie. Standaard is deze animaties niet weet niets over de andere, en alleen een visueel worden toegepast (omdat ze van invloed zijn op de dezelfde CSS-eigenschap en de andere waarden worden overschreven).

element.animatie({
transformeren: [‘translateY(0)’, ‘translateY(10px)’]
}, 1000);

/* Dit wordt volledig vervangen de vorige animatie */
element.animatie({
transformeren: [‘schaal(1)’, ‘schaal(1.15)’]
}, 1500);

De tweede animatie in deze Web-Animaties API voorbeeld is de enige die zou worden visueel weergegeven in dit voorbeeld als zowel de animaties spelen op hetzelfde moment en dat was het laatste gedefinieerd.

Soms hebben we zelfs grootsere ideeën waar we willen een fundamentele animatie en vervolgens gebaseerd op een interactie van de gebruiker te wijzigen in staat soepel wijzigen van de animatie een beetje halverwege zonder dat de bestaande duur, keyframes, of versoepeling. CSS-Animaties en de huidige Web-Animaties API in stabiele browsers vandaag de dag kan dit niet uit de doos.

Een Nieuwe Optie

De Web-Animaties specificatie introduceert de samengestelde goederen (en de daarmee samenhangende iterationComposite). De standaard composiet is ‘vervangen’ en het gedrag dat we al jaren waar een actief animeren van onroerend goed gewoon vervangt alle eerder ingestelde waarde — hetzij van een regel of een andere animatie.

De ‘toevoegen’ – waarde is waar de dingen wijzigen van de vorige normen.

element.animatie({
transformeren: [‘schaal(1)’, ‘schaal(1.5)’]
}, {
duur: 1000,
vullen: ‘beide’
});
element.animatie({
transformeren: [‘draaien(0deg)’, ‘draaien(180deg)’]
}, {
duur: 1500,
vullen: ‘beide’,
composiet: ‘toevoegen’
});

Nu zowel de animaties worden gezien als de browser op de te vliegen figuren uit de juiste transformatie op een bepaald punt in het element tijdlijn van de boekhouding voor zowel transformaties. In onze voorbeelden, de versoepeling is ‘lineaire’ standaard en de animaties op de zelfde tijd beginnen, dus we breken wat de effectieve transformatie is op een bepaald punt. Zoals:

  • 0ms: schaal(1) te draaien(0deg)
  • 500ms: schaal(1.25) draaien(60deg) (halverwege de eerste animatie, 1/3 door de tweede)
  • 1000ms: schaal(1.5) draaien(120deg) (einde van de eerste, 2/3 door seconde)
  • 1500ms: schaal(1.5) draaien(180deg) (einde van de tweede)

Zie de Pen Animatie Composiet van Dan Wilson (@danwilson) op CodePen.

Dus Laten we Creatief

Een individuele animatie bestaat niet alleen uit een begin-toestand en het einde staat — hij kan zijn eigen versoepeling, iteratieteller, duur, en meer keyframes in het midden. Terwijl een element is medio animatie kunt u het gooien van een extra transformatie op met zijn eigen timing opties.

Zie de Pen door het Toevoegen van meer transformeren animaties van Dan Wilson (@danwilson) op CodePen.

Dit voorbeeld kunt u meerdere animaties op hetzelfde element, alle invloed van het transform-eigenschap. Om te houden van het gaan in dit voorbeeld beperken we ons elke animatie een enkele transformatie van de functie (zoals alleen een schaal), te beginnen bij een standaard waarde (zoals schaal(1) of translateX(0)), en eindigde op een redelijk willekeurige waarde op dezelfde transformatie van de functie, eindeloos herhaald. De volgende animatie zal invloed hebben op een andere interne functie met eigen gerandomiseerde duur en versoepeling.

element.animatie(getTransform(), //bijv. { transform: [‘draaien(0deg), ‘roteren(45deg)’] }
{
duur: getDuration(), //tussen de 1000 en 6000ms
iteraties: de Oneindigheid,
composiet: ‘toevoegen’,
versoepeling: getEasing() //een van de twee opties
});

Bij elke animatie begint, zal de browser effectief vinden waar het is op de eerder toegepast animaties en start een nieuwe rotatie animatie met de opgegeven timing opties. Zelfs als er al een rotatie in de tegenovergestelde richting gaat, doet de browser de wiskunde om erachter te komen hoeveel een rotatie moet gebeuren.
Omdat iedere animatie heeft zijn eigen timing opties, bent u waarschijnlijk om de exacte dezelfde beweging te herhalen in dit voorbeeld als u eenmaal een paar. Dit geeft de animatie een fris gevoel als je het te bekijken.

Aangezien elke animatie in ons voorbeeld wordt de standaardwaarde (0 voor vertalingen en 1 voor schalen) krijgen we een soepele start. Als we in plaats daarvan had keyframes, zoals { transform: [‘schaal(.5)’, ‘schaal(.8)’] } we een sprong omdat het niet op deze schaal voor en alle van een plotselinge start de animatie op halve schaal.

Hoe worden de waarden opgeteld?

Transformatie van waarden volgt u de syntaxis van de in de spec, en als u het toevoegen van een transformatie die u toevoegt aan een lijst.

Voor het transformeren van animaties A, B, en C de daaruit berekende transformeren waarde [huidige waarde] [waarde in B] [huidige waarde in C]. Bijvoorbeeld, stel dat de volgende drie:

element.animatie({
transformeren: [‘translateX(0)’, ‘translateX(10px)’]
}, 1000);

element.animatie({
transformeren: [‘translateY(0)’, ‘translateY(-20px)’]
}, {
duur:1000,
composiet: ‘toevoegen’
});

element.animatie({
transformeren: [‘translateX(0)’, ‘translateX(300px)’]
}, {
duur:1000,
composiet: ‘toevoegen’
});

Elke animatie voor 1 seconde met een lineaire verlichten, zodat halverwege de animaties van de resulterende transformatie zou de waarde translateX(5px) translateY(-10px) translateX(150px). Easings, de tijdsduur, de vertragingen, en meer zal hebben allemaal invloed op de waarde als je verder gaat.

Transformaties zijn niet het enige wat we kunnen animeren, echter. Filters (hue-rotate(), blur(), etc) heeft een vergelijkbaar patroon waarin de items worden toegevoegd aan een lijst filter.

Sommige eigenschappen van een getal als waarde, zoals de dekking. Hier zullen de nummers toe te voegen tot één bedrag.

element.animatie({
dekking: [0, .1]
}, 1000);

element.animatie({
dekking: [0, .2]
}, {
duur:1000,
composiet: ‘toevoegen’
});

element.animatie({
dekking: [0, .4]
}, {
duur:1000,
composiet: ‘toevoegen’
});

Omdat iedere animatie weer 1s in duur met een lineaire versoepeling, kunnen we berekenen de waarde op elk punt in de animatie.

  • 0ms: laagdekking: 0 (0 + 0 + 0)
  • 500ms: laagdekking: .35 (.05 + .1 + .2)
  • 1000ms: laagdekking: .7 (.1 + .2 + .4)

Als zodanig, kunt u het niet zien van zoveel als u verschillende animaties die de waarde 1 als een keyframe. Dat is een max waarde voor de visuele staat, zodat het toevoegen van een up-to-waarden buiten dat zal er hetzelfde uitzien alsof het gewoon een 1.

Zie de Pen door het Toevoegen van meer dekking animaties van Dan Wilson (@danwilson) op CodePen.

Vergelijkbaar met de dekking en andere eigenschappen die aanvaarden aantal waarden, eigenschappen die accepteren lengtes, percentages, of de kleuren ook som tot een enkel resultaat waarde. Met kleuren, je moet niet vergeten dat ze ook een max waarde (of een maximum van 255 in rgb() of 100% voor verzadiging/helderheid in de hsl – ()), dus je kan het maximale uit een witte. Met lengtes kan je schakelen tussen de eenheden (zoals de px te vmin) alsof het in een calc().

Voor meer details, de specificatie beschrijft de verschillende soorten animatie en hoe het resultaat wordt berekend.

Werken met Vullen Modi

Wanneer u niet doen van een oneindige animatie (of u gebruik maakt van een composiet of niet) standaard zal de animatie niet te houden zijn eind staat als de animatie eindigt. De vulling eigenschap maakt het mogelijk voor ons om dit gedrag te veranderen. Als u wilt om een soepele overgang bij het toevoegen van een eindige animatie, zal je waarschijnlijk willen een fill-mode van de naar voren of beide om te zorgen dat de eind-toestand blijft.

Zie de Pen Spiraal: Composiet + Vullen Vooruit te zetten Dan Wilson (@danwilson) op CodePen.

Dit voorbeeld heeft een animatie met een spiraalvormig pad door het opgeven van een rotatie en een translatie. Er zijn twee knoppen toevoegen nieuwe tweede animaties met een extra kleine vertaling. Omdat ze opgeven vul in: ‘vooruit’ elke extra vertaling effectief blijft onderdeel van de transformatie lijst. De groeiende (of krimpende) spiraal past zich naadloos aan bij elke vertaling, aanpassing, want het is een additief animatie van translateX(0) een nieuw bedrag en blijft in dat nieuwe bedrag.

Het accumuleren van animaties

De nieuwe optie composite heeft een derde waarde — ‘ophopen’. Het is in principe in lijn met de ‘add’ met uitzondering van bepaalde soorten animaties zullen zich anders gedragen. Houden met onze transformeren, laten we beginnen met een nieuw voorbeeld van het gebruik van op ‘toevoegen’ en vervolgens te bespreken hoe ‘ophopen’ is anders.

element.animatie({
transformeren: [‘translateX(0)’, ‘translateX(20px)’]
}, {
duur: 1000,
composiet: ‘toevoegen’
});
element.animatie({
transformeren: [‘translateX(0)’, ‘translateX(30 met een afwijkende)’]
}, {
duur: 1000,
composiet: ‘toevoegen’
});
element.animatie({
transformeren: [‘schaal(1)’, ‘schaal(.5)’]
}, {
duur: 1000,
composiet: ‘toevoegen’
});

Op de 1 tweede teken (het einde van de animaties), de effectieve waarde:

transformeren: translateX(20px) translateX(30 met een afwijkende) schaal(.5)

Die visueel duwen van een element aan de rechterkant 50px en dan verkleinen tot de helft van de breedte en de helft van de hoogte.

Als iedere animatie was met behulp van ‘accumulate’ plaats, dan is het resultaat:

transformeren: translateX(50px) schaal(.5)

Die visueel duwen van een element aan de rechterkant 50px en dan verkleinen tot de helft van de breedte en de helft van de hoogte.

Geen noodzaak voor een dubbele nemen, de visuele resultaten zijn in feite precies hetzelfde — dus hoe is ‘verzamelen’ anders zijn?

Technisch gezien wanneer het om een transformatie animatie hebben we niet altijd toe te voegen aan een lijst. Als een transformatie van de functie al bestaat (zoals de translateX() in ons voorbeeld zullen wij het niet toevoegen van de waarde wanneer we beginnen aan onze tweede animatie. In plaats daarvan, de innerlijke waarden (d.w.z. de lengte-waarden) worden toegevoegd en geplaatst in de bestaande functie.

Als onze visuele resultaten hetzelfde zijn, waarom is de optie om te accumuleren innerlijke waarden bestaan?

In het geval van de transformatie, de volgorde van de lijst van functies van zaken. De transformatie translateX(20px) translateX(30 met een afwijkende) schaal(.5) is anders dan translateX(20px) schaal(.5) translateX(30 met een afwijkende), omdat elke functie heeft invloed op het coördinatenstelsel van de functies die volgen. Wanneer u een schaal(.5) in het midden, de laatste functies zal ook gebeuren op de helft van de schaal. Daarom in dit voorbeeld de translateX(30 met een afwijkende) zal het visueel renderen van een 15px vertaling naar rechts.

Zie de Pen Visuele Referentie: de Transformatie van coördinaten Systemen van Dan Wilson (@danwilson) op CodePen.

Daarom, met de accumulatie we hebben een opdracht die anders is dan wanneer we zijn altijd het toevoegen van waarden aan de lijst.

Accumulerende voor Elke Iteratie

Ik heb al gezegd dat er ook een nieuwe gerelateerde iterationComposite eigendom. Het biedt de mogelijkheid om een aantal van de problemen die we reeds hebben besproken, behalve op een enkele animatie van een iteratie naar de volgende.

In tegenstelling tot composiet, deze woning heeft slechts twee mogelijke waarden: ‘vervangen’ (het standaard gedrag die je al kent) en ‘ophopen’. Met het ‘verzamelen’ van waarden volg de reeds besproken accumulatie proces voor lijsten (zoals met transform) of worden bij elkaar opgeteld voor het nummer op basis van eigenschappen, zoals dekking.

Als vertrekpunt bijvoorbeeld, het visuele resultaat voor de volgende twee animaties zou zijn identiek:

intervallen.animatie([{
transformeren: `roteren(0deg) translateX(0vmin)`,
dekking: 0
}, {
transformeren: `roteren(50deg) translateX(2vmin)`,
dekking: .5
}], {
duur: 2000,
herhalingen: 2,
vul in: ‘vooruit’,
iterationComposite: ‘ophopen’
});

intervals2.animatie([{
transformeren: `roteren(0deg) translateX(0vmin)`,
dekking: 0
},{
transformeren: `roteren(100deg) translateX(4vmin)`,
dekking: 1
}], {
duur: 4000,
herhalingen: 1,
vul in: ‘vooruit’,
iterationComposite: ‘in plaats van’ //default waarde
});

De eerste animatie is alleen het stoten van de dekking door .5, roterende 50 graden, en het verplaatsen van 2vmin voor 2000 milliseconden. Het heeft onze nieuwe iterationComposite waarde en is ingesteld om te worden uitgevoerd voor 2 iteraties. Daarom, wanneer de animatie eindigt, zal moeten uitvoeren voor 2 * 2000ms en bereikt een dekking van 1 (2 * .5), gedraaid op 100 graden (2 * 50deg) en vertaald 4vmin (2 * 2vmin).

Zie de Pen Spiraal met WAAPI iterationComposite van Dan Wilson (@danwilson) op CodePen.

Geweldig! We hebben net een nieuwe woning dat wordt alleen ondersteund in Firefox Nightly te herscheppen wat we nu al kunnen doen met de Web-Animaties API (of CSS)!
De meer interessante aspecten van iterationComposite gaan spelen als je het combineren met andere artikelen in de Web-Animaties spec die binnenkort (en ook al in Firefox Nightly).

Nieuwe Effect-Opties

De Web-Animaties API, zoals het staat in stabiele browsers vandaag de dag is grotendeels vergelijkbaar met de CSS-Animaties met een aantal extra voordelen zoals een playbackRate optie en de mogelijkheid om te springen/zoeken naar verschillende punten. Echter, de Animatie-object wint de mogelijkheid te werken is het effect en de timing van de opties op de reeds lopende animaties.

Zie de Pen WAAPI iterationComposite & composiet van Dan Wilson (@danwilson) op CodePen.

Hier hebben we een element met twee animaties invloed zijn op het transformeren van eigendom en op basis van composiet: ‘toevoegen’ — een dat maakt het element verplaatst zich over het scherm horizontaal en één te verplaatsen verticaal in een gespreide manier. Het einde staat een beetje hoger op het scherm dan de start van de toestand van deze tweede animatie, en met iterationComposite: ‘ophopen’ het wordt steeds hoger en hoger. Na acht iteraties de animatie klaar is, en keert zich nog acht herhalingen terug naar beneden naar de onderkant van het scherm waar het proces begint opnieuw.

Kunnen We veranderen en hoe ver omhoog over het scherm gaat de animatie door het veranderen van het aantal iteraties op de vlieg. Deze animaties zijn spelen voor onbepaalde tijd, maar u kunt de vervolgkeuzelijst om een andere iteratieteller in het midden van de animatie. Als u, bijvoorbeeld, gaat uit zeven iteraties negen en je ziet de zesde iteratie momenteel de animatie blijft lopen alsof er niets is veranderd. Echter, u zult zien dat in plaats van het starten van een omgekeerde na die komende (zevende) iteratie, het zal blijven voor twee. Je kan ook wisselen in het nieuwe keyframes, en de animatie timing zal ongewijzigd blijven.

animatie.- effect.timing.iteraties = 4;
animatie.- effect.setKeyframes([
{ transform: ‘schaal(1)’ },
{ transform: ‘schaal(1.2)’ }
]);

Het wijzigen van animaties midway misschien niet iets wat je elke dag gebruikt, maar omdat het iets nieuws op de browser van niveau zullen we leren van haar mogelijkheden als de functionaliteit wordt op grotere schaal beschikbaar. Het veranderen van iteratie telt kan handig zijn voor een spel als een gebruiker een bonus ronde en de gameplay blijft langer dan oorspronkelijk de bedoeling was. Verschillende keyframes kan zinvol zijn wanneer een gebruiker van een fout staat tot een succes staat.

Waar gaan we heen vanaf hier?

De nieuwe samengestelde opties en de mogelijkheid om te veranderen timing opties en keyframes nieuwe deuren te openen voor reactieve en choreografie animaties. Er is ook een voortdurende discussie in de CSS werkgroep over het toevoegen van deze functionaliteit CSS, zelfs buiten de context van animaties invloed hebben op de cascade in een nieuwe manier. We hebben tijd voor dit alles zal landen in een stabiele grote browser, maar het is spannend om te zien nieuwe opties komen en nog spannend te worden in staat om te experimenteren met hen vandaag.