CSS, HTML und Javascript mit {stil}

Javascript für CSS-Animationen

JS element width height

CSS Keyframes Animationen bringen HTML-Elementen viele Kunststücke bei – aber erst Javascript fügt komplexe Animationen zusammen.

CSS selber bietet kaum auslösende Events und kann eine Animation nur begrenzt neu starten.

Ohne besonderes auslösendes Event (z.B. hover oder focus) starten CSS Keyframes-Animationen automatisch, wenn das Dokument im Browserfenster geladen wird.

CSS-Animation mit Javascript starten

Die einfachste Technik zum erneuten Start einer CSS Keyframes-Animation ist wohl das Löschen und erneute Einfügen der animierten Elemente. Javascript cloneNode kopiert ein Element mit allen Child Nodes:

CSS bewegt
CSS rotiert
CSS blendet ein
CSS blendet aus
restart

Eine ganz einfache CSS-Animation:

HTML Markup der Animation
<div class="textani">
   <div class="ani t0">CSS bewegt</div>
   <div class="ani t1">CSS rotiert</div>
   <div class="ani t2">CSS blendet ein</div>
   <div class="ani t3">CSS blendet aus</div>
   <div id="trestart">restart</div>
</div>
Das CSS der Keyframes-Animation:
.textani { 
   width: 300px; height: 200px; 
   overflow: hidden; position: relative; 
}

.ani { position: absolute; }
	
.t0 { top: 30px; animation: tmovedown 2s }
.t1 { top: 60px; animation: tmoveup 2s }
.t2 { top: 90px; animation: tmoveleft 2s }
.t3 { top: 120px; animation: tmoveright 2s }

@keyframes tmovedown {
	from { transform: translateY(-200px)}
	to { transform: translateY(0px)}
}
	
#trestart { 
   position: absolute; 
   bottom:0; right: 0; 
}
Javascript: CSS Keyframes-Animation restart
<script>
document.getElementById('trestart').onclick = function () {
   var clone = document.querySelector('.textani').cloneNode();
   var ani = document.querySelectorAll('.ani');
   var len = ani.length;
   for (var i=0; i<len; i++) {
      var clone = ani[i].cloneNode(true);
      ani[i].parentNode.replaceChild(clone, ani[i]);
   }
}
</script>

Javascript startet die komplette Animation bei einem Click auf den Button durch Klonen aller Elemente der Animation und Ersetzen des Originals durch den Klone – also Löschen und Clone einsetzen.

Das wars im einfachsten Fall.

CSS Animation mit animation-play-state starten und stoppen

animation-play-state: paused versetzt eine Animation in eine Wartezustand, bis ein Event mit animation-play-state: running die Sequenz der Keyframes auslöst.

Eine Animation mit animation-play-state: paused wird zwar schon beim Laden der Seite gestartet, sie pausiert aber sofort.

Wird die Animation durch :hover gestartet, läuft sie solange die Maus über dem Element hovert. Sobald die Maus das animerte Element verlässt, springt das Element ruckzuck abrupt zurück auf seine Position vor der Animation.

In vielen Situationen wirkt es natürlicher, wenn die Animation an der Stelle stehenbleibt, an der die Maus das Element verlässt.

var banner = document.querySelector('#banner');
var first = true; 
banner.onmouseover = 
banner.ontouchstart = function (evt) {
    evt.preventDefault();
    this.children[0].style.animationPlayState = 'running';
}
banner.onmouseout = 
banner.ontouchend = function (evt) {
    this.children[0].style.animationPlayState = 'paused';
}

Das spielt die Animation ab, solange die Maus über dem Banner hovert. Verlässt sie das Banner, pausiert die Animation und wird beim nächsten Hovern an dieser Stelle wieder aufgenommen.

Starten mit mouseover und touch

Der CSS-Pseudo-Selektor :hover löst eine CSS-transition oder Keyframe-Animation aus. Auf Touch-Screens gibt es kein zuverlässiges hover. Das touch-Event gibt es wiederum nicht für's CSS.

Das lösen ein paar Zeilen Javascript:

var box = document.querySelectorAll('.box');
for (var i=0; i<box.length; i++) {
	box[i].onmouseover = 
	box[i].ontouch = function () {
		this.classList.add('toggle');
		this.firstElementChild.setAttribute('style','opacity:1');
	}
	box[i].onmouseout = 
	box[i].ontouchend = function () {
		this.classList.remove('toggle');
		this.firstElementChild.setAttribute('style','opacity:0.3');
	}
}

Javascript classList schaltet eine Klasse hinzu oder entfernt sie. classList wird allerdings erst ab IE 10 unterstützt. Wenn IE 9 noch mitgezogen werden muss, gibt es ein classList-Polyfil auf Github.

CSS Animation im Viewport?

Eine Animation starten, wenn sie in den Viewport kommt:

Restart

Drei Elemente werden animiert: Korpus, Head und die Strahlen des Roboters sind CSS Keyframes-Animationen und bestehen jeweils aus einer Gruppe von Elementen.

Position des Elements im Dokument finden
function findPos (obj) {
   var curleft = curtop = 0;
   if (obj.offsetParent) {
      do {
         curleft += obj.offsetLeft;
         curtop += obj.offsetTop;
      } while ( obj = obj.offsetParent);
      return [curleft,curtop];
   }
}

Gefunden bei quirksmode

Bis wohin scrollen?
var topPos = findPos (robox)[1] - robox.offsetHeight - window.innerHeight;

offsetHeight und innerHeight

elem.offsetHeight ist die Höhe eines Elements mitsamt padding, aber ohne margin.

window.innerHeight ist die verfügbare Höhe des Browserfensters in px.

Weit genug gescrollt? Animation starten
window.onscroll = function () {
   if (window.pageYOffset  > topPos ) {
       var clone = robox.cloneNode(true);
       robox.parentNode.replaceChild (clone,robox);
       window.onscroll = null;
       document.querySelector('#newRobot').onclick = function () {
         document.querySelector('.robox').parentNode.replaceChild(document.querySelector('.robox').cloneNode(true),document.querySelector('.robox'))
      }
   }
}

pageYOffset

window.pageYOffset ist die Zahl der Pixel, um die das aktuelle Dokument von der oberen linken Ecke des Browserfensters vertical gescrollt wurde.

IE / Edge: SVG-Animation mit CSS Keyframes

Animationen von SVG-Element mit CSS Keyframes (und Transitions ebenso) funktionieren in IE nur bei CSS-Eigenschaften wie opacity und fill, nicht aber mit transform und rotate.

Dieser Einschränkung unterliegen auch SVG-Animationen mit jQuery, besser mit velocity.js.