Tipps und Tricks für AngularJS, Teil 4: Animationen in AngularJS 1.4

Know-how  –  1 Kommentare

Animationen geben Webangeboten einen dynamischen Anstrich. Um ihre Beliebtheit wissen auch die AngularJS-Autoren, weshalb in Version 1.4 einige neue Features zur Integration bewegter Elemente und deren Steuerung zu finden sind.

Mit heutigen Endgeräten und modernen Browsern ist es möglich, teils erstaunliche Animationen und Effekte darzustellen. Noch vor nicht allzu langer Zeit wäre das nur mit Plug-ins wie Flash möglich gewesen. Die rasante Entwicklung von CSS3-Transitionen und -Animationen hat jedoch dazu geführt, dass sie heute in breiter Verwendung sind. AngularJS trägt dem Trend mit dem optionalen Modul ngAnimate Rechnung, das mit der Veröffentlichung der aktuellen Version 1.4 eine Rundumerneuerung erfahren hat.

Die Programmierschnittstelle ngAnimate bietet die Möglichkeit, mit CSS3 reine CSS-Animationen und -Transitionen zu definieren, die ausgeführt werden, wenn das zu animierende Element die entsprechenden CSS-Klassen erhält. Ergänzend lassen sich CSS3-Animationen auch um Keyframes erweitern, die die Feinabstimmung des Animationsverlaufs ermöglichen.

Freunden programmierter Animationen bietet ngAnimate jedoch auch die Möglichkeit, Bewegungsabläufe und Ähnliches mit JavaScript zu definieren. Hierbei ist zu beachten, dass derartig erstellte Animationen grundsätzlich nicht durch Hardware beschleunigt und dementsprechend langsamer als ihre CSS3-Pendants sind.

Für die aktuelle Version 1.4 haben die Entwickler die zugrundeliegende Implementierung mit Blick auf Angular 2 neu geschrieben. Dadurch ergeben sich unter anderem bessere Performance und neue Features.

Das AngularJS-Animations-1x1

Zur Erinnerung an die Handhabung der Methoden zeigt das folgende Beispiel, wie Entwickler einfache div-Elemente mit den unterschiedlichen Methoden animieren können. Ein Klick auf die Schaltfläche bewirkt, dass die roten Kästen ein- beziehungsweise ausklappen. Der dazugehörende Code und eine Live-Demo finden sich auf plunkr.

ngAnimate-Animationsvarianten

Das verwendete HTML-Markup definiert drei div-Elemente, die zur Unterscheidung mit einer eigenen CSS-Klasse versehen sind. Die Schaltfläche führt nach dem Klick die Funktion toggleAnimation des Controllers MainCtrl aus. Zusätzlich kommt die Direktive ng-if zum Einsatz, die abhängig von der Eigenschaft isActive die Elemente zum DOM-Baum hinzufügt oder entfernt.

<div ng-controller="MainCtrl">
<button ng-click="toggleAnimation()">Animation umschalten</button>
<div>
<div class="cube-css-transition"
ng-if="isActive">CSS-Transition</div>
<div class="cube-keyframe-animation"
ng-if="isActive">CSS-KeyFrame-Animation</div>
<div class="cube-javascript-animation"
ng-if="isActive">JavaScript-Animation</div>
</div>
</div>

Innerhalb der Datei app.js ist ein neues AngularJS-Modul namens AngularAnimateVariants definiert, das wiederum ngAnimate benötigt. Danach registriert die Datei den MainCtrl mit einer Eigenschaft isActive, die angibt, ob die Kästen eingeklappt sind, und der erwähnten Methode toggleAnimation. Letztere dient lediglich dazu, den Wert von isActive zu tauschen.

'use strict';

var app = angular.module('AngularAnimateVariants', ['ngAnimate']);

app.controller('MainCtrl', function($scope) {
$scope.isActive = true;
$scope.toggleAnimation = function() {
$scope.isActive = !$scope.isActive;
};
});

Animationen mit JavaScript

Abschließend findet sich in app.js noch die Definition der mit JavaScript erstellten Animation. Hierzu können Entwickler die Methode animate verwenden, die das oder die zu animierenden Objekte in Form eines CSS-Selektoren als ersten Parameter erwartet. Der zweite Parameter ist die Animationsimplementierung. Per Konvention rechnet AngularJS mit einem Objekt als Rückgabewert, das die jeweilige Animationsmethode implementiert. Im Falle des gezeigten Beispiels sind das die Methoden enter und leave, die mit jQuery die Anfangsposition der Animation setzen und im Anschluss via animate eine einfache Animation der Elementhöhe vornehmen. Da ngAnimate alle Funktionen asynchron ausführt, ist es notwendig, nach erfolgter Animation die Funktion done auszusetzen. Abschließend senden die Funktionen einen Callback zurück, den die Anwendung im Falle des vorzeitigen Beendens durch den Benutzer ausführt und die Animation mit der Funktion stop anhält.

app.animation('.cube-javascript-animation', function() {
return {
enter : function(element, done) {
jQuery(element).css({
height:'0px'
});
jQuery(element).animate({
height: '200px'
}, 500, done);

return function(cancelled) {
if(cancelled) {
jQuery(element).stop();
}
}
},
leave : function(element, done) {
jQuery(element).css({
height:'200px'
});
jQuery(element).animate({
height: '0px'
}, 500, done);

return function(cancelled) {
if(cancelled) {
jQuery(element).stop();
}
}
},
...
};
});

Die vollständige Liste und Beschreibung aller Animationsmethoden ist in der AngularJS-Dokumentation zu finden.

Animationen mit CSS

Eine alternative Variante der CSS3-Animationen lässt sich durch die Definition entsprechender CSS-Klassen umsetzen. Dazu erhalten zunächst sämtliche Kästen eine einheitliche Formatierung.

.cube-css-transition,
.cube-keyframe-animation,
.cube-javascript-animation
{
width: 200px;
height: 200px;
background-color: darkred;
border: 1px solid;
margin: 5px;
float:left;
text-align: center;
line-height: 200px;
color: white;
font-size: 15px;
}

Zum Erstellen von CSS3-Animationen ist es notwendig, der zu animierenden Klasse die Erweiterungsklassen ng-enter für das Hinzufügen und ng-leave für das Entfernen des Elements zu liefern. Bei CSS3-Transitionen führen sie in beiden Fällen über eine halbe Sekunde hinweg einen gleichmäßige Animation aus. Mit den Erweiterungsmethoden ist zudem der Startwert der zu animierenden CSS-Eigenschaften anzugeben. Die ergänzenden Klassen, die mit dem Zusatz -active versehen sind, starten letztlich den Animationsvorgang und geben zugleich den Endwert der CSS-Eigenschaft an. Sind sie definiert, kümmert sich ngAnimate selbstständig darum, sie rechtzeitig zum Element hinzuzufügen beziehungsweise sie zu entfernen.

.cube-css-transition.ng-enter,
.cube-css-transition.ng-leave {
-webkit-transition:0.5s linear all;
transition:0.5s linear all;
}

.cube-css-transition.ng-enter {
height:0px;
}
.cube-css-transition.ng-enter.ng-enter-active {
height: 200px;
}

.cube-css-transition.ng-leave {
height:200px;
}
.cube-css-transition.ng-leave.ng-leave-active {
height: 0px;
}

Abschließend sei noch die Vorgehensweise mit CSS3-Animationen demonstriert. Hierbei können Entwickler ähnlich wie bei Transitionen vorgehen und ebenfalls ng-enter, ng-leave und die entsprechenden -active-Erweiterungen verwenden. Neu ist jedoch, dass die CSS-Eigenschaft animation Verwendung findet, die über die Dauer einer halben Sekunde eine definierte Animation increase-size und decrease-size aufruft. Zusätzlich können Entwickler mit keyframes auch in den Animationsverlauf eingreifen. So lässt sich bestimmen, wie die Höhe des Elements zu einem in Prozent angegebenen Animationsfortschritt aussehen soll.

.cube-keyframe-animation.ng-enter {
-webkit-animation:0.5s increase-size;
animation:0.5s increase-size;
}
.cube-keyframe-animation.ng-leave {
-webkit-animation:0.5s decrease-size;
animation:0.5s decrease-size;
}

@keyframes increase-size {
from { height: 0px; }
to { height: 200px; }
}
@-webkit-keyframes increase-size{
from { height: 0px; }
to { height: 200px; }
}

@keyframes decrease-size {
0% { height: 200px; }
40% { height: 140px; }
60% { height: 170px; }
100% { height: 0px; }
}
@-webkit-keyframes decrease-size{
0% { height: 200px; }
40% { height: 140px; }
60% { height: 170px; }
100% { height: 0px; }
}