Eine Einführung in mo.js

Avatar of Sarah Drasner
Sarah Drasner am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

mo.js ist eine JavaScript-Bibliothek, die sich der Bewegung im Web widmet. Sie bietet eine deklarative Syntax für Bewegung und die Erstellung von Elementen für Animationen. Obwohl mo.js noch in der Beta-Phase ist, gibt es bereits eine Fülle erstaunlicher Funktionen zum Ausprobieren. Sein Autor, Oleg Solomoka (auch bekannt als @legomushroom), erstellt unglaublich beeindruckende Demos und Tutorials für die Angebote der Bibliothek, die Sie sich ansehen sollten. In diesem Artikel geben wir jedoch einen sehr schnellen Überblick über die Funktionen und Tutorials, um Ihnen den Einstieg zu erleichtern.

Grundlegende Prämissen

mo.js bietet im Grunde zwei Möglichkeiten, etwas zu bewegen. Sie können wie bei anderen Bibliotheken den DOM oder SVG-DOM manipulieren und ihn bewegen, oder Sie können ein spezielles mo.js-Objekt erstellen, das einige wirklich einzigartige Angebote hat. Für beide Arbeitsweisen stehen grundlegende Funktionen zur Verfügung, wie z. B. benutzerdefinierte Pfad-Easing-Effekte oder Zeitachsen. Die Pfad-Easing-Effekte und Zeitachsen verfügen außerdem über ziemlich beeindruckende Werkzeuge, die ihre Anpassung während der Arbeit erleichtern.

Form

Je nachdem, was Sie animieren, können die Formen und andere Objekte, die mo.js Ihnen erlaubt zu erstellen, Ihren Workflow vereinfachen. mo.js bietet eine deklarative Syntax, die es sehr einfach macht, etwas spontan zu erstellen.

Hier ist ein sehr einfaches Beispiel

Siehe den Pen mo.js Form 1 von Sarah Drasner (@sdras) auf CodePen.

Hier sind einige der grundlegenden Dinge, die Sie wissen müssen

  • Die Ihnen zur Verfügung stehenden Formen sind: Kreis, Rechteck, Kreuz, Gleichheitszeichen, Zickzack und Polygon. (Standard ist ein Kreis)
  • Sie definieren eine Füllung, einen Strich und eine Strichstärke (Standard ist eine Füllung ohne Strich oder Strichstärke. Gleichheitszeichen und Kreuz haben keinen Platz zum Füllen, daher erscheinen sie nicht, es sei denn, ein Strich wird angegeben.)
  • Sie definieren einen Radius für die Form und passen ihn auf einer Achse mit einem zusätzlichen RadiusX oder RadiusY an. (Standard ist 50)
  • Sie geben an, ob Sie die Form anzeigen möchten isShowStart, dies ist ein boolescher Wert (true oder false). Dadurch können Sie sie sehen, wenn Sie die Form nicht animieren. (Standard ist false)
  • Polygone, Zickzack und Gleichheitszeichen ermöglichen es Ihnen, eine Anzahl von Punkten auszuwählen, um verschiedene Arten von Formen zu erstellen (Standard ist drei).
  • Alle Formen werden mit absoluter Positionierung in der Mitte des Bildschirms platziert, es sei denn, Sie geben oben, links usw. an.

Hier ist ein Beispiel für alle Formen

Siehe den Pen mo.js Form 2 von Sarah Drasner (@sdras) auf CodePen.

Sie werden vielleicht bemerken, wenn Sie sich den DOM ansehen, dass es sich um SVG-Formen handelt, die zur Positionierung in einem Div platziert sind. Sie können auch ein übergeordnetes Element übergeben, z. B. parent: '#id-to-be-placed-under', wenn Sie die Form irgendwo im DOM platzieren möchten. Sie können auch jeden beliebigen DOM-Knoten als übergeordnetes Element übergeben, sodass `parent: someEl` ebenfalls funktioniert. Irgendwann werden Sie auch zwischen der Verwendung eines Divs oder SVGs wählen können, was großartig sein wird, da es die Erstellung einer skalierbaren Animation für Mobilgeräte erleichtert, wenn Sie sie mit einer SVG-ViewBox platzieren können.

Wir können auch benutzerdefinierte Formen zur Animation erstellen und sie als Formobjekt hinzufügen.

//custom shape
class OneNote extends mojs.CustomShape {
  getShape () { return '<path d="M18.709
	...
"/>'; }
}
mojs.addShape( 'oneNote', OneNote ); 

const note1 = new mojs.ShapeSwirl({
  shape:    'oneNote',
  ...
});

Form-Bewegung

Um eine Animation mit einer Form in mo.js zu erstellen, würden wir ein Objekt übergeben, wobei der Schlüssel und der Wert ausdrücken, was wir von und zu twenen möchten. Wir können Transformationseigenschaften wie Skalierung und Winkel (in CSS als Drehung bekannt), Deckkraft verwenden und Farben interpolieren, wie hier mit der Füllung gezeigt.

scale:        { 0 : 1.5 },
angle:        { 0 : 180 },
fill:         { '#721e5f' : '#a5efce' },

Siehe den Pen mo.js Form 3 von Sarah Drasner (@sdras) auf CodePen.

Wir können auch einige andere Parameter angeben

  • Dauer
  • Verzögerung
  • repeat
  • Geschwindigkeit - 1 ist die Standardgeschwindigkeit, also wäre 0,5 halbe Geschwindigkeit und 1,5 wäre 1,5 mal schneller
  • isYoyo - ob es hin und her tweent
  • Easing - geschrieben als Objekt wie ease.in, ease.out oder ease.inout
  • backwardEasing – eine Konfiguration, wenn Sie möchten, dass die Rückwärtsbewegung des Yoyo anders ist. Dies funktioniert nur, wenn Sie isYoyo: true verwenden. Wenn Sie möchten, dass die Art und Weise, wie es zurückkehrt, anders ist als die Art und Weise, wie es vorwärts geht, würden Sie dies mit dieser Methode angeben. Standardmäßig wird Easing verwendet, wenn nicht anders angegeben.
  • isSoftHide - ob die Form mit Transformationen statt mit Anzeige ausgeblendet wird (boolean, Standard ist true)

Zufällig

Wir können auch ziemlich einfach **zufällige Werte** übergeben, indem wir diesen String schreiben - property : 'rand(min, max)', zum Beispiel angle: ‘rand(0, 360)’

Verkettung

Wenn wir zwei Animationen auf einer Form verketten möchten, können wir wie folgt .then() auf dem ursprünglichen Tween aufrufen

const polygon = new mojs.Shape({
  shape:        'polygon',
  points:       5,
  stroke:       '#A8CABA',
  scale:        { 0 : 1.5 },
  angle:        { 0 : 180 },
  fill:         { '#721e5f' : '#a5efce' },
  radius:       25,
  duration:     1200,
  easing:       'sin.out'
}).then ({
  stroke:       '#000',
  angle:        [-360],
  scale:        0,
  easing:       'sin.in'
});

Siehe den Pen mo.js Form 4 von Sarah Drasner (@sdras) auf CodePen.

Wirbel

Dinge wie Wirbel und Explosionen sind ziemlich interessante Teile von mo.js, sie sind direkt einsatzbereit ziemlich schön. Wirbel ist sehr ähnlich zu einem regulären Formular-Objekt, aber die Bewegung ist ziemlich selbsterklärend – die Form wirbelt herum. Sie haben einige Parameter, mit denen Sie für einen Wirbel arbeiten können, und sie basieren alle auf dem Sinus, mit dem der Wirbel arbeitet.

  • swirlSize – dies ist die Abweichung, also die horizontale Wirbel-Größe
  • swirlFrequency – Frequenz des Sinus
  • pathScale – Skalierung der Sinuslänge
  • degreeShift – dies kann die Richtung des Sinus verschieben, wenn Sie ihn in eine andere Richtung auf 360 Grad bewegen möchten, besonders nützlich für die Verwendung von Wirbel mit einem Ausbruch
  • direction – Richtung des Sinus, entweder -1 oder 1 (gut, um etwas in die andere Richtung zu setzen, wenn Sie möchten, dass es ein wenig zufällig aussieht)
  • isSwirl: Ob die Form dem Sinuspfad folgen soll (boolean – true oder false)

Diese können ein wenig verwirrend zu lesen und zu verstehen sein, daher habe ich eine Demo erstellt, damit Sie mit den Werten spielen können, um sie besser zu verstehen.

Siehe den Pen Mo.js Wirbel-Form-Optionen von Sarah Drasner (@sdras) auf CodePen.

Außerdem können Sie einige Basis-Konfigurationen verwenden, wie z. B. eine benutzerdefinierte Form oder ein Objekt mit einigen Konfigurationen, die für einige verschiedene SwirlShape-Optionen (oder jede andere Form) wiederverwendet werden können, mit einem ES6-Spread-Operator wie diesem, was sehr gut ist, wenn Sie einige ähnliche Objekte haben.

const note_opts_two = {
  shape:    'twoNote',
  scale:    { 5 : 20 },
  y:        { 20: -10 },
  duration:  3000,
  easing: 'sin.out'
};

const note1 = new mojs.ShapeSwirl({
  ...note_opts_two,
  fill:     { 'cyan' : color2 },
  swirlSize:      15, 
  swirlFrequency: 20
}).then({
  opacity:  0,
  duration: 200,
  easing: 'sin.in'
});

Siehe den Pen Kleines hüpfendes Radio von Sarah Drasner (@sdras) auf CodePen.

Ausbruch

Ein Ausbruch ist auch von Haus aus ziemlich schön. Wenn Sie die Standardkonfiguration verwenden, würden Sie dies sagen

const burst = new mojs.Burst().play();

Und es würde dies zurückgeben (klicken Sie auf die Schaltfläche Wiederholen)

Siehe den Pen Einfachster Mo.js Ausbruch von Sarah Drasner (@sdras) auf CodePen.

Um einen Ausbruch zu konfigurieren, haben Sie einige Optionen

  • count – die Anzahl der Kinder im Ausbruch (Standard ist 5)
  • degree – die Anzahl der Grad um das Zentrum, von denen die Kinder kommen
  • Radius – der Radius, auf den sich die Kinder ausbreiten (radiusX und radiusY gelten auch hier)
  • isSoftHide – ob die Kinder mit Transformationen statt mit Anzeige ausgeblendet werden (boolean, Standard ist true) – dies gilt für alle Formen, aber ich erwähne es noch einmal, da es besonders nützlich für einen Ausbruch mit mehreren Kindern ist.

Alle gleichen Regeln für Formen gelten auch für Ausbrüche, und wir können sie als separates Objekt mit children auf die Knoten selbst anwenden, wie hier

const burst = new mojs.Burst({ 
  radius: { 0: 100 },
  count: 12,
  children: {
    shape: 'polygon',
    ...
  }
});

Siehe den Pen Mo.js Ausbruchsspiele von Sarah Drasner (@sdras) auf CodePen.

Zeitachse

In einer Zeitachse können Sie entweder eine Reihe von zuvor als Variable deklarierten Objekten oder Tweens hinzufügen oder sie anhängen und sie in Ordnung bringen lassen.

const timeline = new mojs.Timeline({
  .add( tween ) {}
  .append( tween ) {}
});
  • Add – ermöglicht es Ihnen, alle Objekte oder Formen oben hinzuzufügen – sie werden alle gleichzeitig ausgelöst (aber Sie können immer noch Verzögerungen oder Staggering verwenden, um ihre Timing anzupassen)
  • Append – fügt Objekte hinzu, reiht sie aber in der Reihenfolge, in der sie hinzugefügt werden, aneinander.

Es gibt einige Dinge, die Sie in einer Zeitachse tun können, die erwähnenswert sind: Sie können Wiederholungen, Verzögerungen und Geschwindigkeit wie bei den Objekten selbst als Objektparameter hinzufügen, wie hier

new mojs.Timeline({
  repeat: 3,
  isYoyo: true
});

Sie können auch eine Zeitachse in eine andere Zeitachse verschachteln, Sie können sie sogar unendlich verschachteln.

const subTimeline = new mojs.Timeline();

const master = new mojs.Timeline()
.add( subTimeline );

Tween

Bei all diesen Konstruktoren haben wir noch nicht einmal viel über das Tweening (Animieren) von bereits vorhandenem gesprochen. Alle gleichen Wiederholungen, Dauern und Easing-Effekte sind auch für Tweens verfügbar. Um einen Tween zu verwenden, würden wir Stile oder Attribute (was auch immer Sie ändern möchten) entlang eines Fortschritts aktualisieren, hier ist ein einfaches Beispiel.

var thingtoselect = document.querySelector('#thingtoselect');
new mojs.Tween({
  duration:    2000,
  onUpdate: function (progress) {
    square.style.transform = 'translateY(' + 200*progress + 'px)';
  }
}).play();

In dem untenstehenden Pen habe ich diese Art von Tween verwendet, um den Effekt auf der linken Seite zu erzeugen, wo sich die kleinen Zickzacklinien wiederholt selbst zeichnen (unter Verwendung des SVG-Linienzeichnungs-Tricks mit stroke-dashoffset). Ich verwende auch das Pfad-Easing, das im nächsten Abschnitt besprochen wird. Das Wasser in den Tanks scheint sich durch Aktualisieren von SVG-Pfadattributen zu bewegen.

new mojs.Tween({
  repeat:   999,
  duration: 2000,
  isYoyo: true,
  isShowEnd: false,
  onUpdate: function (progress) {
    var laser1EProgress = laser1E(progress);
    for (var i = 0; i < allSideL.length; i++) {
      allSideL[i].style.strokeDashoffset = 20*laser1EProgress + '%';
      allSideL[i].style.opacity = Math.abs(0.8*laser1EProgress);
    }
  }
}).play();

Siehe den Pen Raygun mit Mo.js von Sarah Drasner (@sdras) auf CodePen.

Tweens haben ziemlich reichhaltige Rückrufe, die feineinstellungen berücksichtigen, die manchmal den Unterschied ausmachen können. Einige Beispiele hierfür sind onStart vs. onRepeatStart, onComplete vs. onRepeatComplete und onPlaybackStart vs. onPlaybackPause. Eine vollständige Liste finden Sie hier in der Dokumentation.

Pfad-Easing

Ein sehr cooles Feature von mo.js ist, dass Sie neben den anderen eingebauten Easing-Werten auch einen SVG-Pfad als Easing-Wert übergeben können. Ich nutze diese Funktion in fast jeder anderen Demo in diesem Beitrag, aber um ehrlich zu sein, könnte ich niemals die Pfad-Easing-Effekte so gut darstellen wie Legomushroom in seinem wunderschönen Tutorial, das er auf dieser Seite vorbereitet hat. Ich werde einfach die grundlegenden Prämissen erklären, um Ihnen den Einstieg zu erleichtern und zu zeigen, wie es funktioniert, aber ich empfehle wirklich, seinen Beitrag durchzugehen.

Bevor wir uns mit der gesamten Pfad-Easing-Funktion befassen, ist es wichtig zu verstehen, dass die Basis-Funktionen Sie sehr weit bringen, wenn Sie etwas aus der Box verwenden möchten. Die Syntax für eingebaute Easing-Effekte ist wie folgt geschrieben.

easing: 'cubic.in'

Das Beherrschen von Easing kann wirklich die Schlüsselzutat sein, um Ihren Animationen Leben einzuhauchen, daher ist die Möglichkeit, Ihre Bewegung mit benutzerdefinierten Pfaden fein abzustimmen, hilfreich. Wenn Sie sich mit Animationen in CSS wohlfühlen, mögen Sie vielleicht das Mo.js Bezier-Easing, das die gleichen Kurvenwerte akzeptiert (ohne einige der gleichen Einschränkungen wie bei CSS's cubic bezier). Hier ist ein Beispiel für diese Art von Easing.

easing: 'bezier( 0.910, 0.000, 0.110, 1.005 )'

Wenn Sie eine feinere Kontrolle wünschen, als es Bezier-Easing bietet, ist Pfad-Easing wirklich gut. Sie übergeben einen SVG-Pfad, und Ihre Form wird aktualisiert, während Sie damit arbeiten. Schauen wir uns noch einmal das Beispiel aus dem Raygun an, das ich früher herausgezogen habe. Wir haben ein Pfad-Easing verwendet, um die Werte während der Aktualisierung zu interpolieren.

const laser1E = mojs.easing.path('M0,400S58,111.1,80.5,175.1s43,286.4,63,110.4,46.3-214.8,70.8-71.8S264.5,369,285,225.5s16.6-209.7,35.1-118.2S349.5,258.5,357,210,400,0,400,0');

new mojs.Tween({
  repeat:   999,
  duration: 2000,
  isYoyo: true,
  isShowEnd: false,
  onUpdate: function (progress) {
    var laser1EProgress = laser1E(progress);
    for (var i = 0; i < allSideL.length; i++) {
      allSideL[i].style.strokeDashoffset = 20*laser1EProgress + '%';
      allSideL[i].style.opacity = Math.abs(0.8*laser1EProgress);
    }
  }
}).play();

Um ein echtes Gefühl dafür zu bekommen, wie sich eine Pfad-Easing-Funktion auf die Bewegung und das Verhalten einer Animation auswirken kann, schauen Sie sich die Beispiel-CodePen-Demo unten im Werkzeugbereich an. Das von Mo.js angebotene Kurveneditor-Werkzeug hilft wirklich, zu visualisieren und sofort ein Gefühl dafür zu bekommen, wie eine Easing-Funktion das, was Sie erstellen, verfeinern kann.

Mo.js Werkzeuge

Eines der beeindruckendsten Dinge an mo.js ist die Tooling. Um sich einen ersten Eindruck zu verschaffen, schauen Sie sich dieses Vimeo-Video an.

Ich habe einen schnellen Pen erstellt, um sowohl das Player-Tool als auch den Kurveneditor zu zeigen, damit Sie damit experimentieren können. Fühlen Sie sich frei, es zu forken oder es einfach live in CodePen anzupassen, es macht Spaß, es auszuprobieren. Das Kurvenwerkzeug befindet sich auf der linken Seite und die Zeitachse ist unten mit einem kleinen Pfeil versteckt.

Siehe den Pen mo.js Form 5 - Kurveneditor von Sarah Drasner (@sdras) auf CodePen.

Hier ist das Coolste: legomushroom ist noch nicht fertig. Er arbeitet jetzt an neuen Tools für die Zeitachse. Schauen Sie sich das tolle Design für dieses Werkzeug hier an und schauen Sie sich das breitere Label "Hilfe gesucht" an. Wenn Sie daran interessiert sind, zu Open Source beizutragen, haben Sie hier die Möglichkeit, sich einzubringen und bei der Erstellung eines wirklich nützlichen Werkzeugs zu helfen!

Die anderen fertigen Werkzeuge sind in ihren eigenen Repositories verfügbar.

Es gibt auch einen Slack-Kanal, dem Sie beitreten können, wenn Sie daran interessiert sind, beizutragen oder zu lernen.

Wenn Sie zu den Leuten gehören, die Dinge lieber ausprobieren als lesen, sind alle CodePen-Demos aus diesem Beitrag in dieser Sammlung verfügbar.

Es gibt natürlich Dinge in der Bibliothek, die ich in diesem Artikel nicht behandelt habe. Ich habe meiner Meinung nach einige der nützlichsten Funktionen von mo.js behandelt, aber es gibt noch mehr zu entdecken. Schauen Sie sich die Dokumentation für weitere Informationen an. Besonderer Dank an legomushroom für die Korrekturlesung dieses Artikels vor der Veröffentlichung.