Additiv-Animasjon med Web-Animasjoner API

0
16

Disse funksjonene har ikke landet på noen stabil nettlesere på tidspunktet for skriving. Men, alt er diskutert allerede i Firefox Nattlig standard og sentrale deler er i Chrome Canary (med den Eksperimentelle Web-Plattformen Har flagget er aktivert), så jeg anbefaler at du bruker en av disse nettleserne (når du leser denne artikkelen) å se så mange av funksjonene i aksjon som mulig.

Uansett din foretrukne metoden for animasjon på nettet, vil det være ganger du trenger for å animere den samme egenskapen i egne animasjoner. Kanskje du har en hover effekt som skalerer et bilde og klikk på en hendelse som utløser en oversett — både som påvirker transform. Som standard, de animasjoner ikke vet noe om den andre, og bare én vil visuelt benyttes (siden de er som påvirker den samme CSS eiendom og andre verdier vil overstyres).

elementet.animere({
forvandle: [‘translateY(0)’, ‘translateY(10px)’]
}, 1000);

/* Dette vil helt overstyre den forrige animasjon */
elementet.animere({
forvandle: [‘skala(1)’, ‘skala(1.15)’]
}, 1500);

Den andre animasjon i denne Web-Animasjoner API-et eksempel er den eneste som ville være visuelt gjengitt i dette eksemplet som både animasjoner spille på samme tid, og det var den siste definert.

Noen ganger har vi til og med har bedre ideer hvor vi ønsker en grunnleggende animasjon og da basert på noen brukermedvirkning endring i tilstand vi jevnt endre animasjonen litt midtveis uten at det påvirker eksisterende varighet, keyframes, eller lettelser. CSS-Animasjoner og gjeldende Web-Animasjoner API i stabil nettlesere i dag ikke kan gjøre dette ut av boksen.

Et Nytt Alternativ

Web-Animasjoner spesifikasjon introduserer kompositt eiendom (og relaterte iterationComposite). Standard kompositt er ‘erstatt’, og har det problemet vi har hatt i mange år nå, hvor en aktivt blir eiendommens verdi bare erstatter alle tidligere angitte verdi — enten fra et regelsett eller annen animasjon.

‘Legg til’ – verdien er der ting endringen fra forrige normer.

elementet.animere({
forvandle: [‘skala(1)’, ‘skala(1.5)’]
}, {
varighet: 1000,
fyll: ‘begge’
});
elementet.animere({
forvandle: [‘roter(0deg)’, ‘roter(180deg)’]
}, {
varighet: 1500,
fyll: ‘begge’,
kompositt: ‘legg til’
});

Nå er både animasjoner vil bli sett på som nettleseren på fly tall ut riktig transformasjon på et gitt tidspunkt i elementet er tidslinjen regnskap for både transformasjoner. I våre eksempler, lettelser er “lineær” standard og animasjoner starter på samme tid, slik at vi kan bryte ut hva den effektive forvandle er på et gitt tidspunkt. For eksempel:

  • 0ms: skala(1) roter(0deg)
  • 500ms: skala(1.25) roter(60deg) (halvveis gjennom første animasjon, 1/3 gjennom andre)
  • 1000ms: skala(1.5) roter(120deg) (slutten av første, 2/3 gjennom andre)
  • 1500ms: skala(1.5) roter(180deg) (slutten av andre)

Se Pen Animasjon Sammensatt av Dan Wilson (@danwilson) på CodePen.

Så La oss Få Kreative

En individuell animasjon ikke bare bestå av en start-tilstand og end state — det kan ha sin egen lettelser, iterasjon telle, varighet, og mer keyframes i midten. Mens et element er midten av animasjonen du kan kaste en ekstra transformasjon på det med sin egen timing valg.

Se Penn Legge til flere forvandle animasjoner av Dan Wilson (@danwilson) på CodePen.

Dette eksemplet kan du bruke flere animasjoner på samme element, som alle påvirker forvandle eiendommen. For å holde fra å gå ut i dette eksemplet, vi begrense hver animasjon til en enkel transformasjon av funksjon på en tid (for eksempel bare en skala), og starter med en standardverdi (for eksempel skala(1) eller translateX(0)), og avslutningen på en rimelig tilfeldig verdi på den samme transformasjonen funksjon, gjentatt uendelig. Neste animasjon vil påvirke en annen enkel funksjon med sin egen randomisert varighet og lettelser.

elementet.animere(getTransform (), //, f.eks. { forvandle: [‘roter(0deg),” roter(45deg)’] }
{
varighet: getDuration(), //mellom 1000 og 6000ms
iterations: Infinity,
kompositt: ‘legg til’,
lettelser: getEasing() //en av to alternativer
});

Når hver enkelt animasjon starter, vil nettleseren effektivt finne ut hvor den er i sin tidligere brukt animasjoner og starte en ny rotasjon animasjon med det angitte tidspunktet valg. Selv om det er allerede en rotasjon går i motsatt retning, vil nettleseren gjøre regnestykket for å finne ut hvor mye en rotasjon må skje.
Siden hver enkelt animasjon har sin egen timing valg, du er usannsynlig å se den nøyaktige samme bevegelse gjentas i dette eksemplet når du har lagt til et par. Dette gir animasjon en frisk følelse som du ser det.

Siden hver enkelt animasjon i vårt eksempel starter med standard verdi (0 for oversettelser og 1 for skalering) vi få en myk start. Hvis vi i stedet hadde keyframes, for eksempel { forvandle: [‘skala(.5)’, ‘skala(.8)’] } vi ville få en hoppe fordi de ikke har denne skalaen før og begynner plutselig animasjon på halv skala.

Hvordan er verdier som er lagt til?

Transformasjon verdiene følger syntaksen i spec, og hvis du legger til en transformasjon du legge til en liste.

For transformere animasjoner A, B, og C som følge beregnet forvandle verdien vil være [nåværende verdi i Et] [nåværende verdi i B] [nåværende verdi i C]. For eksempel, anta følgende tre animasjoner:

elementet.animere({
forvandle: [‘translateX(0)’, ‘translateX(10px)’]
}, 1000);

elementet.animere({
forvandle: [‘translateY(0)’, ‘translateY(-20 piksler)’]
}, {
varighet:1000,
kompositt: ‘legg til’
});

elementet.animere({
forvandle: [‘translateX(0)’, ‘translateX(300px)’]
}, {
varighet:1000,
kompositt: ‘legg til’
});

Hver kjører animasjonen i 1 sekund med en lineær lettelser, så halvveis gjennom animasjoner den resulterende forvandle ville ha verdien translateX(5px) translateY(-10px) translateX(150px). Easings, varighet, forsinkelser, og mer vil alle påvirke verdien som du går sammen.

Forvandler er ikke det eneste vi kan animere, imidlertid. Filtre (hue-rotate(), blur(), osv) følger et lignende mønster hvor elementer er lagt til et filter listen.

Noen egenskaper bruke et nummer som en verdi, for eksempel dekkevne. Her vil tallene legge opp til en enkelt sum.

elementet.animere({
dekkevne: [0, .1]
}, 1000);

elementet.animere({
dekkevne: [0, .2]
}, {
varighet:1000,
kompositt: ‘legg til’
});

elementet.animere({
dekkevne: [0, .4]
}, {
varighet:1000,
kompositt: ‘legg til’
});

Siden hver enkelt animasjon igjen er 1s varighet med en lineær lettelser, kan vi beregne den resulterende verdien på et punkt i denne animasjonen.

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

Som sådan, du vil ikke bli å se mye hvis du har flere animasjoner som inkluderer verdien 1 som en keyframe. Det er en maks verdi for sin visuelle tilstand, så det å legge opp til verdier utover det vil se det samme som om det var bare en 1.

Se Penn Legge til mer dekkevne animasjoner av Dan Wilson (@danwilson) på CodePen.

Lik tetthet og andre egenskaper som godtar antall verdier, egenskaper som godtar lengder, prosenter, eller farger vil også summen til en enkelt resultat verdi. Med farger, må du huske at de også har en maks verdi, også (om maks 255 i rgb() eller 100% metning/letthet i hsl()), slik at resultatet kan maks ut til en hvit. Med lengder, kan du bytte mellom enheter (for eksempel px å vmin) som om det er inne i en calc().

For mer informasjon, spesifikasjonen beskriver de ulike typer av animasjon og hvordan resultatet er beregnet.

Arbeide med Fyll Moduser

Når du ikke gjør en uendelig animasjon (om du bruker en kompositt-eller ikke) som standard animasjonen vil ikke holde seg slutten stat som animasjon ender. Fyll hotellet tillater oss å endre atferd. Hvis du vil ha en myk overgang når du legger til et endelig animasjon, du sannsynligvis vil ha en fylle-modus av enten forover eller begge, for å sørge for at sluttresultatet gjenstår.

Se Pen Spiral: Kompositt Legge til + Fyll Fremover av Dan Wilson (@danwilson) på CodePen.

Dette eksemplet har en animasjon med en spiral vei ved å angi en rotasjon og oversettelse. Det er to knapper som legg til ny ett sekund animasjoner med en ekstra liten oversettelse. Siden de angir fyll: ‘forover” for hver ny oversettelse effektivt fortsatt er en del av forvandle listen. Utvidende (eller mindre) spiral tilpasser seg jevnt med hver oversettelse justering fordi det er en additiv animasjon fra translateX(0) til et nytt beløp og forblir på det nye beløpet.

Samler animasjoner

Den nye kompositt-alternativet har en tredje verdi — ‘akkumulere’. Det er konseptuelt i tråd med ‘legg til’, bortsett fra visse typer animasjoner vil oppføre seg annerledes. Tråd med våre forvandle, la oss starte med et nytt eksempel ved hjelp av “legg til” og deretter diskutere hvordan ‘akkumulere’ er forskjellige.

elementet.animere({
forvandle: [‘translateX(0)’, ‘translateX(20 piksler)’]
}, {
varighet: 1000,
kompositt: ‘legg til’
});
elementet.animere({
forvandle: [‘translateX(0)’, ‘translateX(30px)’]
}, {
varighet: 1000,
kompositt: ‘legg til’
});
elementet.animere({
forvandle: [‘skala(1)’, ‘skala(.5)’]
}, {
varighet: 1000,
kompositt: ‘legg til’
});

På 1 sekund-merke (slutten av animasjoner), er den effektive verdien vil være:

forvandle: translateX(20 piksler) translateX(30px) skala(.5)

Som vil visuelt flytte et element til høyre 50px og deretter skalere det ned til halv bredde og halv høyde.

Hvis hver enkelt animasjon hadde vært å bruke ‘akkumulere’ i stedet, så ville resultatet bli:

forvandle: translateX(50px) skala(.5)

Som vil visuelt flytte et element til høyre 50px og deretter skalere det ned til halv bredde og halv høyde.

Ingen behov for en dobbel ta, den visuelle resultater er faktisk nøyaktig det samme — så hvordan er “samle” hvilken som helst annen?

Teknisk når du samler en forvandle animasjon vi ikke lenger er alltid legge til en liste. Hvis en transformasjon funksjonen allerede finnes (som for eksempel translateX() i vårt eksempel) vil vi ikke legge verdien når vi starter vårt andre animasjon. I stedet, de indre verdier (dvs. lengde verdier), vil bli lagt, og plassert i eksisterende funksjon.

Hvis vår visuelle resultatene er de samme, hvorfor får muligheten til å samle indre verdier eksisterer?

I tilfelle av transform, bestilling av listen over funksjoner saker. Transformasjonen translateX(20 piksler) translateX(30px) skala(.5) er annerledes enn translateX(20 piksler) skala(.5) translateX(30px) fordi hver funksjon påvirker koordinatsystemet av funksjonene som følger det. Når du gjør en skala(.5) i midten, sistnevnte funksjonene vil også skje på halv skala. Derfor med dette eksempelet er translateX(30px) vil visuelt gjengis som en 15 piksler oversettelse til høyre.

Se Penn Visuell Referanse: Forvandle Koordinatsystem av Dan Wilson (@danwilson) på CodePen.

Derfor, med opphopning vi kan ha en ordre som er annerledes enn når vi alltid legge til verdier i listen.

Opptjening for Hver Iterasjon

Jeg nevnte tidligere at det også er en ny knyttet iterationComposite eiendom. Det gir muligheten til å gjøre noen av atferd vi har allerede diskutert, bortsett fra på en enkel animasjon fra en utgave til den neste.

I motsetning til kompositt, har denne eiendommen har bare to gyldige verdier: ‘erstatt’ (standard virkemåte du allerede kjenner og elsker) og “samle’. Med “samle” verdier følger allerede diskutert akkumulering prosessen for lister (som med transform) eller legges sammen for antall basert egenskaper som tetthet.

Som utgangspunkt eksempel, det visuelle resultatet for følgende to animasjoner ville være identiske:

intervaller.animere([{
forvandle: “roter(0deg) translateX(0vmin)`,
dekkevne: 0
}, {
forvandle: “roter(50deg) translateX(2vmin)`,
dekkevne: .5
}], {
varighet: 2000,
iterations: 2,
fyll: ‘fremover’,
iterationComposite: ‘akkumulere’
});

intervals2.animere([{
forvandle: “roter(0deg) translateX(0vmin)`,
dekkevne: 0
},{
forvandle: “roter(100deg) translateX(4vmin)`,
dekkevne: 1
}], {
varighet: 4000,
iterations: 1,
fyll: ‘fremover’,
iterationComposite: ‘erstatt’ //default-verdi
});

Den første animasjonen er bare å slå opp sin tetthet av .5, roterende 50 grader, og flytte 2vmin for 2000 millisekunder. Det har vår nye iterationComposite verdi og er satt til å kjøre for 2 iterasjoner. Derfor, når animasjonen er avsluttet, vil det ha kjørt for 2 * 2000ms og nådde en tetthet av 1 (2 * .5), rotert 100 grader (2 * 50deg) og oversatt 4vmin (2 * 2vmin).

Se Pen Spiral med WAAPI iterationComposite av Dan Wilson (@danwilson) på CodePen.

Flott! Vi brukte bare en ny eiendom som støttes bare i Firefox Nattlig å gjenskape det vi allerede kan gjøre med Web-Animasjoner API (eller CSS)!
De mer interessante aspekter av iterationComposite spiller inn når du kombinerer det med andre elementer i Web-Animasjoner spec som kommer snart (og også allerede i Firefox Nattlig).

Sette Nye Virkning Valg

Web-Animasjoner API som det står i stabil nettlesere i dag er i stor grad på linje med CSS-Animasjoner med noen lagt niceties som en playbackRate muligheten og evnen til å hoppe/søke til forskjellige steder. Men, Animasjon hensikten er å få muligheten til å oppdatere effekt og timing valg på allerede kjører animasjoner.

Se Penn WAAPI iterationComposite & sammensatt av Dan Wilson (@danwilson) på CodePen.

Her har vi et element med to animasjoner som påvirker forvandle eiendommen og å stole på kompositt: ‘legg til’ — en som gjør elementet beveger seg over skjermen vannrett og en beveger seg vertikalt i en forskjøvet måte. Slutten staten er litt høyere på skjermen enn start-tilstand av denne andre animasjon, og med iterationComposite: ‘akkumulere’ det holder å komme høyere og høyere. Etter åtte iterasjoner animasjonen er ferdig og vrenger seg for en annen åtte iterasjoner tilbake ned til bunnen av skjermen der prosessen starter på nytt.

Vi kan endre hvor langt opp på skjermen animasjonen går ved å endre antall iterasjoner på fly. Disse animasjonene er å spille på ubestemt tid, men du kan endre dropdown til en annen iterasjon teller i midten av animasjon. Hvis du, for eksempel, kommer fra syv iterasjoner til ni, og du ser den sjette utgaven tiden, animasjon holder kjører som om ingenting har endret seg. Imidlertid, vil du se at i stedet for å starte en omvendt etter at neste (sjuende) iterasjon, det vil fortsette for to. Du kan også bytte i nye keyframes, og animasjonen timing vil forbli uendret.

animasjon.effekten.timing.iterasjoner = 4;
animasjon.effekten.setKeyframes([
{ forvandle: ‘skala(1)’ },
{ forvandle: ‘skala(1.2)’ }
]);

Endre animasjoner midway er kanskje ikke noe du skal bruke hver dag, men siden det er noe nytt på nettleseren nivå vi skal lære av sine muligheter som funksjonaliteten blir mer allment tilgjengelig. Endre iterasjon teller kan være nyttig for et spill når en bruker får en bonus runde, og spillingen fortsetter lenger enn opprinnelig forutsatt. Ulike keyframes kan være fornuftig når en bruker går fra noen feil tilstand til en suksess staten.

Hvor går vi herfra?

Den nye kompositt valg og evne til å endre timing valg og keyframes åpne nye dører for reaktive og koreografert animasjoner. Det er også en pågående diskusjon i CSS arbeidsgruppen om å legge til denne funksjonaliteten til å CSS, også utover rammen av animasjoner som påvirker kaskade på en ny måte. Vi har tid før noe av dette vil lande i en stabil store nettleser, men det er spennende å se nye muligheter som kommer og enda mer spennende å være i stand til å eksperimentere med dem i dag.