CSS offset-path: Animation entlang eines Pfades

CSS offset-path bewegt Elemente entlang einer S-Kurve, einer Acht und schießt kleine Raketen in den Orbit. Damit wollen die Blink-Entwickler (Chrome und Opera) CSS Transition und Animationen bereichern, nachdem sie SVG SMIL-Animationen ins Abseits gesetzt haben.

offset-path

CSS kennt keine Animation entlang eines Pfades: Das gibt es erst mit offset-path (zuvor Motion Path).

Das Web Animation API (WAAPI) steht als umfassende Schnittstelle für Animationen auf der Schwelle. Den ersten Vorgeschmack liefern Chrome und Opera, die das CSS Motion Path Modul aus dem Web Animation API umgesetzt haben.

Animationen sind ein bewegtes Thema. CSS-Animationen haben im Handumdrehen Karriere gemacht, Javascript-Libraries wie VelocityJs und GreenSock treten die Nachfolge von ActionScript an.
Aber wir haben immer noch nichts, was so handlich wie einst die GIF-Animationen wäre: Alles in einer Datei.

Das hätte mit SVG und SMIL funktioniert, aber Blink (Chrome, Opera) und Microsoft haben schnell einen Riegel vorgesetzt als SVG sich endlich entfalten konnte. Funktionsweise und Syntax von SMIL liegen abseits von CSS-Animationen und der große Erfolg der CSS-Animationen rührt nicht zuletzt in ihrer konsistenten und gut verständlichen Syntax.

Offset-Path-Animationen

Die Animation von Elementen entlang eines Pfades fehlt im CSS-Animations-Angebot bislang.

Motion Path Acht für einen Flieger
Kein Support für offset-path (alte Syntax: motion-path). Versuchs mit Chrome oder Opera!

Der rote Flieger ist ein PNG-Bild, also ein HTML-Element – kein SVG. CSS offset-path animiert sowohl SVG- als auch HTML-Elemente mit der bekannten CSS-Syntax für Animationen.

aero {
 offset-path: path('m 138.6,161.9 c 5.7,5.7 -4.9,10.4 -9.5,9.4 -12.3,-2.8 -14.3,-18.7 -9.3,-28.3 9,-17.2 32.1,-19.1 47.2,-9.2 22,14.4 23.9,45.6 9.1,65.9 -19.8,27.1 -59.3,29 -84.77,9.1 C 59.27,183.7 57.37,135.8 82.38,105.2 112.6,68 169,66.1 204.8,96.2 c 42.1,35.5 44,100.4 8.8,141.3 C 172.9,285 99.64,286.5 53.57,246.2 1.203,200.4 -0.5627,118.6 44.87,67.3 95.88,9.8 186.2,8.1 242.5,58.7 305.1,115 306.8,213.9 251,275.3');
    animation: acht 10s; 
 }
 @keyframes acht {
    0% { offset-distance: 0;}
    100% { offset-distance: 100%;}
 }
offset (alte Syntax: motion)
shorthand / Kurzschrift
offset-path (alte Syntax: motion-path)
ist der Pfad, an dem das Element ausgerichtet wird. Der Pfad ist das d-Attribut eines SVG-Elements, wie er in SVG 1.1 definiert ist.
offset-distance (alte Syntax: motion-offset)
ist der Bereich des Pfades, an dem das Objekt in der Animation erscheint und wird entweder als Floating Point-Wert oder in % notiert. Mit offset-distance von 0 bis 100% läuft das Element entlang des vollständigen Pfades.
offset-rotate (alte Syntax: motion-rotation)
Ausrichtung entlang des Pfades
animation
ist die bekannte Parameter-Liste der Animation: animation-name, animation-duration, animation-delay, animation-iteration-count, und animation-timing-function (Easing).

Am Rande: Die CSS offset-path-Eigenschaften waren bereits zu einem frühen Zeitpunkt in Chrome als motion-path installiert und wurden etwas später umbenannt:

Offset Path in SVG

Zu den schönen Seiten von offset-path gehört, dass wir ein Bild (wie einst ein GIF oder ein SVG mit SMIL) in einem img-Tag animieren können, ohne CSS- oder Javascript-Dateien mit Einzelteilen zu belasten. Alles schon drin …

Test offset-path

Zur Zeit schweben die Ballons nur für Chrome und Opera, in Firefox seit Version 63 nur in about:config nach Freischalten (layout.css.motion-path.enabled) . Für den Rest – Safari, IE, Edge – gibt es im Anschluss ein Trostplaster.

c1 {
 offset-path: path( 'M 1169,756 C 2281,362 271,20 229,616 214,1080 56,1151 1169,757 z');
    offset-rotate: 0deg;   
    animation: floating 40s infinite linear;
 }
 @keyframes floating {
    0% { offset-distance: 0%;}
    100% { offset-distance: 100%;}
 }

Animation entlang eines Pfades mit SVG und SMIL

Nach der Ankündigung der Blink-Entwickler, dass SMIL nicht mehr erwünscht sei, traut sich kaum noch jemand, eine SVG SMIL-Animation ins Web zu setzen – obwohl die Ankündigung nicht umgesetzt wurde. Sehen wir uns die Animation entlang einer Acht trotzdem noch als SMIL animate Motion an – in Firefox, Safari, Opera oder Chrome:

<animateMotion 
       begin="0s" dur="8s" 
       rotate="auto"
       repeatCount="indefinite">
       <mpath xlink:href="#eight" />
 </animateMotion>

animateMotion funktioniert ebenfalls, wenn das SVG mit einem img-Tag geladen wird, kann durch Events wie onload, onclick oder ontouch gestartet werden. Als SVG sind auch die Animationen responsive.

SVG SMIL-Animationen wurden von den Blink-Entwicklern 2015 als unerwünschte und veraltete Technik verdammt, aber die Ankündigung wurde nicht dauerhaft umgesetzt, denn 2017 liefen SMIL-Animationen auch wieder in Chrome. IE11 und Microsoft Edge haben SMIL-Animationen nie unterstützt.

Am Rande: Wie wird ein Offset Path erzeugt?

XML-Editor (Shift +Ctrl+X) <svg:svg id=“svg1595″> <svg:defs:id=“1589″> <sodipodi:namedview=“base“> <svg:metadata id=“metadata1592″> <svg:g id=“layer1″ inkscape:label=“Ebene 1″> <svg:path id=“path2140″> Name Wert d id inkscape:connector-curvature style M 197.3,43.76 C 164.1,53.58 136.1,70,97 147 path2140 0 fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.2645px;

Adobe Photoshop CC exportiert Pfade (»Form« – nicht »Pfad«) als SVG. Genauso wie bei Inkscape oder Adobe Illustrator wird nur das d-Attribut des Pfad-Elements als Motion Path übernommen.

offset-path, offset-distance und offset-rotate agieren sowohl als pures CSS als auch via Javascript. Wie immer, wenn im CSS-Namen ein Bindestrich steht, wird es ein CamelCase (camel case: Weil Javascript keine Bindestriche toleriert, entfallen Bindestriche und der erste Buchstabe nach dem Bindestrich wird groß geschrieben).

Offset Path Responsive

Alles ist einfach, wenn das animierte Element in einem SVG-Element sitzt: Dann passt sich die Grafik dank viewBox-Attribut mit all ihren Elementen an den umfassenden Block an.

Wenn Motion Path HTML-Elemente animiert, übernimmt der Pfad die Maßeinheiten des Viewports als absolute Werte. Im einfachsten Fall tauscht eine Media Query den Pfad an den Breakpoints aus.

#aero { 
   offset-path: path('m 33,70.1 c 0,43 43,46 65,33 C 120,91 186.4,49.12 205,38 c 18.4,-10.6 63,-10.6 63,32.7 0,43 -45,43 -63,32.58 C 187.2,92.72 115.6,49 97.37,38.42 79,28 32.43,28 32.43,70.72 Z');
   animation: acht 10s; 
}

@media (min-width: 720px) {
   #aero { 
      offset-path: path('m 65,140 c 0,86 86,92 130,66 45,-26 178,-109 215,-130 37,-21 125,-21 125,65 0,86 -90,86 -125,65 C 374.3,183.7 231.1,96.47 194.7,75.17 158.3,53.87 64.85,53.87 64.85,139.7 Z'); 
   }
}

Pfad-Animation mit getPointAtLength und getTotalLength

Mit dem Web Animation API bekommen wir einen runden und flexiblen Nachfolger für Flash und Action Script. Bei Microsoft steht CSS Motion Path „Under consideration“ – MS hat nicht einmal den Namen der CSS-Eigenschaft geändert. Firefox wollte der Bewegung entlang eines Pfads mit Version 48 beitreten (jetzt sind wir bei 67 … ?), bei Webkit steht ebenfalls „Under consideration“.

Es gibt ein Trostpflaster: Zwei Javascript-Methoden des Pfades steuern die Animation entlang eines Pfads.

(function() { 
 var p = document.createElementNS('http://www.w3.org/2000/svg','path');
 p.setAttribute('d','M 746.1,57.41 C 637.5,248.8 115.7,-87.43 229.9,343.9');
 var ff = document.getElementById('ff');
 var head = document.getElementById('head');
 head.setAttribute('transform','translate(140,220) rotate(0)');
 var len = p.getTotalLength();
 var ic = 0;
 var repeater;
 var open = 0;
 function swallow () {
    var pct = ic / 250;
    var pt = p.getPointAtLength(pct * len);
    ff.setAttribute('transform','translate(' + pt.x + ',' + pt.y + ') rotate(' + ic + ')');
    if (ic > 50 && ic < 130) {
       head.setAttribute('transform','translate(140,220) rotate(' + open + ')');
       open = open - 1; 
    }
    if (ic > 210) {
       head.setAttribute('transform','translate(140,220) rotate(' + open + ')');
       open = open + 2;
    }
    ic++;
    if (ic > 250) {
       ic = 0;
       open = 0; 
    } 
    repeater = requestAnimationFrame(swallow);
 }
 swallow();
 } () );

Animationen mit getTotalLength und getPointAtLength funktionieren in allen Browsern, die SVG unterstützen – lt. Microsoft selbst in IE9. Sie animieren nicht nur SVG, sondern auch HTML-Elemente wie Bilder und Text. Allerdings gibt getPointAtLength nur das her, was der Name besagt: einen Punkt im Koordinatensystem. Die Richtung fehlt – also keine einfache Anpassung der Ausrichtung.

Gracefully degrading

Die Alternative für Browser ohne Motion / Offset Path-Support ist … na gut … ein SVG-Standbild. Wie elegant ist das denn? Eine SMIL-Animation erreicht immer noch mehr Benutzter als offset-path.

Mehr zu Animationen

Seit gut vier Jahren hat sich rund um offset-path nicht viel (besser: gar nichts) geändert: Unterstützung gibt es nur in Chrome und Opera. Firefox und Microsoft geben „Under Consideration“ an, Safari hält sich bedeckt. Ende 2018 hat Microsoft angekündigt, dass Edge zugunsten von Chromium aufgegeben wird.

SMIL funktioniert immer noch in allen Browsern außer IE11 und EDGE. IE11 ist so gut wie begraben, aus EDGE wird Chromium. Die Glaskugel ruckelt und rauscht und spuckt ein paar Nebelschwaden: Dann hätten wir tatsächlich flächendeckende Unterstützung für SMIL.

Mehr zu CSS Motion Path

SITEMAP BLOG