Afspeelbediening voor webanimaties in Chrome 39

Eerder dit jaar introduceerde Chrome 36 de element.animate-methode als onderdeel van de bredere Web Animations-specificatie . Dit maakt efficiënte, native animaties mogelijk die dwingend zijn geschreven, waardoor ontwikkelaars de keuze hebben om hun animaties en overgangen te bouwen met de meest geschikte aanpak voor hen.

Om het even op te frissen, ziet u hier hoe u een wolk over het scherm kunt animeren, met een terugbelactie als u klaar bent:

var player = cloud.animate([
    {transform: 'translateX(' + start + 'px)'},
    {transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
    console.info('Cloud moved across the screen!');
    startRaining(cloud);
};

Dit alleen al is ongelooflijk eenvoudig en het is zeker de moeite waard om te overwegen als onderdeel van uw gereedschapskist wanneer u absoluut animaties of overgangen maakt. In Chrome 39 zijn er echter afspeelbesturingsfuncties toegevoegd aan het AnimationPlayer object dat wordt geretourneerd door element.animate . Voorheen kon je, zodra een animatie was gemaakt, alleen cancel() aanroepen of naar de finish-gebeurtenis luisteren.

Deze afspeeltoevoegingen openen de mogelijkheden van wat webanimaties kunnen doen: animaties omzetten in een hulpmiddel voor algemene doeleinden, in plaats van prescriptief te zijn over overgangen, dat wil zeggen 'vaste' of vooraf gedefinieerde animaties.

Pauzeren, terugspoelen of de afspeelsnelheid wijzigen

Laten we beginnen met het bijwerken van het bovenstaande voorbeeld om de animatie te pauzeren als er op de wolk wordt geklikt:

cloud.addEventListener('mousedown', function() {
    player.pause();
});

U kunt ook de eigenschap playbackRate wijzigen:

function changeWindSpeed() {
    player.playbackRate *= (Math.random() * 2.0);
}

U kunt ook de methode reverse() aanroepen, wat normaal gesproken gelijk staat aan het omkeren van de huidige playbackRate (vermenigvuldigen met -1). Er zijn echter een paar speciale gevallen:

  • Als de verandering veroorzaakt door de reverse() methode ertoe zou leiden dat de lopende animatie effectief eindigt, wordt de currentTime ook omgekeerd. Als bijvoorbeeld een geheel nieuwe animatie wordt omgekeerd, wordt de hele animatie achterstevoren afgespeeld.

  • Als de speler is gepauzeerd, begint de animatie te spelen.

De speler schrobben

Een AnimationPlayer maakt het nu mogelijk dat de currentTime wordt gewijzigd terwijl een animatie wordt uitgevoerd. Normaal gesproken zal deze waarde in de loop van de tijd toenemen (of afnemen als de playbackRate negatief is). Hierdoor kan de positie van een animatie extern worden bestuurd, bijvoorbeeld door gebruikersinteractie. Dit wordt gewoonlijk scrubben genoemd.

Als uw HTML-pagina bijvoorbeeld de lucht vertegenwoordigt en u een sleepbeweging wilt gebruiken om de positie van een momenteel afgespeelde wolk te wijzigen, kunt u enkele handlers aan het document toevoegen:

var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
    startEvent = event;
    startEventTime = players.currentTime;
    player.pause();
});
document.addEventListener('touchmove', function(event) {
    if (!startEvent) return;
    var delta = startEvent.touches[0].screenX -
        event.changedTouches[0].screenX;
    player.currentTime = startEventTime + delta;
});

Terwijl u over het document sleept, wordt de currentTime gewijzigd om de afstand tot uw oorspronkelijke gebeurtenis weer te geven. Mogelijk wilt u het afspelen van de animatie ook hervatten wanneer het gebaar eindigt:

document.addEventListener('touchend', function(event) {
    startEvent = null;
    player.play();
});

Dit zou zelfs gecombineerd kunnen worden met omkeergedrag, afhankelijk van waar de muis van de pagina werd gehaald ( gecombineerde demo ).

In plaats van een AnimationPlayer te scrubben als reactie op een gebruikersinteractie, kan currentTime ervan ook worden gebruikt om de voortgang of status weer te geven: om bijvoorbeeld de status van een download te tonen.

Het nut hier is dat een AnimationPlayer het mogelijk maakt een waarde in te stellen en dat de onderliggende native implementatie voor de voortgangsvisualisatie zorgt. In het geval van downloaden kan de duur van een animatie worden ingesteld op de totale downloadgrootte, en de currentTime op de momenteel gedownloade grootte ( demo ).

UI-overgangen en gebaren

Mobiele platforms zijn lange tijd het domein geweest van gewone gebaren: slepen, glijden, slingeren en dergelijke. Deze gebaren hebben meestal een gemeenschappelijk thema: een versleepbare UI-component, zoals het "trekken om te vernieuwen" van een lijstweergave of een zijbalk die vanaf de linkerkant van het scherm wordt gemaakt.

Met webanimaties is een soortgelijk effect heel eenvoudig hier op internet te repliceren - op desktop of mobiel. Wanneer bijvoorbeeld een gebaar dat currentTime bestuurt, wordt voltooid:

var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);

var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
    var srcTime = player.currentTime;
    var dstTime = findNearest(setpoints, srcTime);
    var driftDuration = dstTime - srcTime;

    if (!driftDuration) {
    runCallback(dstTime);
    return;
    }

    var driftPlayer = target.animate(steps, {
    duration: duration,
    iterationStart: Math.min(srcTime, dstTime) / duration,
    iterations: Math.abs(driftDuration) / duration,
    playbackRate: Math.sign(driftDuration)
    });
    driftPlayer.onfinish = function() { runCallback(dstTime); };
    player.currentTime = dstTime;
});

Hierdoor ontstaat er een extra animatie die een 'drift' uitvoert. Dit speelt zich af tussen waar het gebaar werd voltooid, tot en met ons bekende goede doelwit.

Dit werkt omdat animaties een prioriteit hebben op basis van hun creatievolgorde: in dit geval heeft driftPlayer voorrang op de speler. Wanneer driftPlayer voltooid is, zullen het programma en de effecten ervan verdwijnen. De uiteindelijke tijd komt echter overeen met de currentTime van de onderliggende speler, zodat uw gebruikersinterface consistent blijft.

Ten slotte, als je van kittens houdt, is er een demo-webapplicatie die deze gebaren laat zien. Het is mobielvriendelijk en gebruikt de polyfill voor achterwaartse compatibiliteit, dus probeer het op uw mobiele apparaat te laden!

Ga heen en element.animeer

De element.animate -methode is op dit moment helemaal geweldig - of je hem nu voor eenvoudige animaties gebruikt of de geretourneerde AnimationPlayer op andere manieren gebruikt.

Deze twee functies worden ook volledig ondersteund in andere moderne browsers via een lichtgewicht polyfill . Deze polyfill voert ook functiedetectie uit, dus naarmate browserleveranciers de specificatie implementeren, zal deze functie in de loop van de tijd alleen maar sneller en beter worden.

De specificaties voor webanimaties zullen ook blijven evolueren. Als je geïnteresseerd bent om met aankomende functies te spelen, zijn ze nu ook beschikbaar in een meer gedetailleerde polyfill: web-animations-next .