Animation

Fortgeschrittenes Animationssystem zur Erstellung dynamischer, prozeduraler und ausdrucksbasierter Animationen, die über einfache Keyframes hinausgehen.

Animationstypen

Das Animationssystem unterstützt mehrere Typen über traditionelle Keyframes hinaus:

  • Ausdruck: JavaScript-Ausdrücke, die pro Frame ausgewertet werden
  • Prozedural: Eingebaute prozedurale Animationsmuster
  • Sequenz: Schrittbasierte sequentielle Animationen
  • Pfad: Bewegung entlang von Bezier-Pfaden

Diese fortgeschrittenen Animationen werden im animations Array-Attribut von Elementen definiert.

Knotenanimationen vs. Keyframes

Knotenanimationen (animations Array):

  • Prozedurale, ausdrucksbasierte oder pfadverfolgende Animationen
  • Jede Frame ausgewertet
  • Höhere Priorität als Keyframes
  • Können Keyframe-Werte überschreiben

Keyframes (keyframes Array):

  • Einfache Interpolation von Eigenschaften zwischen definierten Punkten
  • Niedrigere Priorität
  • Vorhersehbar, leicht zu bearbeiten

Animationspriorität

Wenn mehrere Animationsmethoden dasselbe Attribut anvisieren:

  1. Höchste: Knotenanimationen (Ausdruck, prozedural, Pfad, Sequenz)
  2. Mittel: Keyframe-Animationen
  3. Niedrigste: Statische Eigenschaftswerte
EigenschaftTypErforderlichBeispielWertbereichBeschreibung
typestringtrue-expression | procedural | sequence | pathDer Typ der Animation.
enabledbooleanfalse--Ob die Animation aktiv ist.
targetstringtrue--Der Eigenschaftspfad, der animiert werden soll (z. B. "x", "rotation", "scaleX").
startTimenumberfalse--Startzeit der Animation relativ zum Elementstart, in Sekunden.
durationnumberfalse--Dauer der Animation in Sekunden. Bei sich wiederholenden Animationen ist dies die Schleifenperiode.
loopbooleanfalse--Ob die Animation in einer Schleife ausgeführt wird.
blendModestringfalse-replace | add | multiplyWie diese Animation mit anderen kombiniert wird: ersetzen (überschreiben), hinzufügen (summe), multiplizieren (skalieren).
blendWeightnumberfalse--Die Stärke/Einfluss dieser Animation (0-1). Wird zum Mischen mehrerer Animationen verwendet.

Ausdrucksanimationen

Ausdrücke sind JavaScript-Code, der pro Frame ausgewertet wird und Zugriff auf Animationskontextvariablen hat.

Verfügbare Kontextvariablen

{
  time: number; // Aktuelle absolute Zeit (Sekunden)
  localTime: number; // Zeit relativ zum Elementstart
  duration: number; // Elementdauer
  progress: number; // Normalisierter Fortschritt (0-1)
  index: number; // Elementindex in der Gruppe
  total: number; // Gesamte Elemente in der Gruppe
  fps: number; // Bilder pro Sekunde
  width: number; // Canvas-Breite
  height: number; // Canvas-Höhe
  value: any; // Aktueller Eigenschaftswert
}

Ausdrucksbeispiel

Bounce-Animation unter Verwendung von Math-Funktionen:

expressionAnimation.json
{
"id": "element-1",
"type": "Image",
"start": 0,
"duration": 5,
"animations": [
  {
    "type": "expression",
    "target": "y",
    "enabled": true,
    "expression": "100 + Math.abs(Math.sin(localTime * 3)) * 200",
    "startTime": 0,
    "duration": 5,
    "loop": true
  }
]
}

Komplexer Ausdruck

Kombinieren Sie mehrere Effekte:

complexExpression.json
{
"animations": [
  {
    "type": "expression",
    "target": "rotation",
    "expression": "(localTime * 2 * Math.PI / duration) + Math.sin(localTime * 4) * 0.1",
    "loop": true
  },
  {
    "type": "expression",
    "target": "scaleX",
    "expression": "1 + Math.sin(localTime * 5) * 0.2",
    "loop": true
  }
]
}

Prozeduralen Animationen

Eingebaute Animationsmuster mit konfigurierbaren Parametern.

Prozedurale Typen

  • wiggle: Zufällige Oszillation (nützlich für Handkamerawirkungen)
  • wave: Sinus/Cosinus-Wellenbewegung
  • bounce: Elastischer Bounce-Effekt
  • pulse: Rhythmisches Skalieren

Wiggle-Beispiel

wiggleAnimation.json
{
"animations": [
  {
    "type": "procedural",
    "proceduralType": "wiggle",
    "target": "rotation",
    "enabled": true,
    "frequency": 2,
    "amplitude": 0.1,
    "loop": true
  }
]
}

Sequenzanimationen

Schrittbasierte Animationen, die Werte in bestimmten Intervallen ändern.

EigenschaftTypErforderlichBeispielWertbereichBeschreibung
valuesarraytrue--Array von Werten, durch die geschritten werden soll.
stepDurationnumbertrue--Dauer jedes Schrittes in Sekunden.
loopbooleanfalse--Ob die Sequenz in einer Schleife ausgeführt wird.

Sequenzbeispiel

Text, der durch verschiedene Größen wechselt:

sequenceAnimation.json
{
"animations": [
  {
    "type": "sequence",
    "target": "fontSize",
    "enabled": true,
    "values": [24, 32, 40, 32, 24],
    "stepDuration": 0.5,
    "loop": true
  }
]
}

Pfadanimationen

Animation von Elementen entlang von Bezier-Kurvenpfaden.

EigenschaftTypErforderlichBeispielWertbereichBeschreibung
pathstring | arraytrue--SVG-Pfaddaten (d-Attribut) oder Array von Pfunkten.
autoRotatebooleanfalse--Ob das Element automatisch gedreht wird, um dem Pfadtangenten zu folgen.
durationnumbertrue--Zeit, um den gesamten Pfad abzuschließen.

Pfadbeispiel

Kreisbewegung:

pathAnimation.json
{
"animations": [
  {
    "type": "path",
    "target": "position",
    "enabled": true,
    "path": "M 100,100 a 200,200 0 1,1 0,1 Z",
    "autoRotate": true,
    "duration": 4,
    "loop": true
  }
]
}

Eigenschaftspfadsyntax

Das target-Attribut verwendet die Punktnotation, um geschachtelte Eigenschaften anzugeben:

  • Einfach: "x", "y", "rotation"
  • Verschachtelt: "scale.x", "position.y"
  • Array: "colors[0]", "points[2].x"

Zielauflösungsbeispiele

{
  "target": "x"              // x-Position des Elements
  "target": "scaleX"         // Horizontale Skalierung
  "target": "alpha"          // Opazität
  "target": "fill.color"     // Füllfarbe (wenn fill ein Objekt ist)
  "target": "points[0].x"    // x-Koordinate des ersten Punktes
}

Mischmodi

Steuern, wie Animationen kombiniert werden, wenn mehrere dasselbe Attribut anvisieren:

Ersetzen (Standard)

{
  "blendMode": "replace",
  "blendWeight": 1.0
}

Ersetzt den Eigenschaftswert vollständig.

Hinzufügen

{
  "blendMode": "add",
  "blendWeight": 0.5
}

Fügt den bestehenden Wert hinzu (gewichtet). Nützlich zum Ansammeln von Offset.

Multiplizieren

{
  "blendMode": "multiply",
  "blendWeight": 1.0
}

Multipliziert den bestehenden Wert. Nützlich für Skalierungseffekte.

Beispiel für mehrere Animationen

Kombinieren verschiedener Animationstypen:

multipleAnimations.json
{
"id": "animated-element",
"type": "Shape",
"animations": [
  {
    "type": "expression",
    "target": "x",
    "expression": "width / 2 + Math.sin(localTime * 2) * 300",
    "blendMode": "replace",
    "loop": true
  },
  {
    "type": "procedural",
    "proceduralType": "wiggle",
    "target": "rotation",
    "frequency": 3,
    "amplitude": 0.2,
    "blendMode": "add",
    "blendWeight": 0.5
  },
  {
    "type": "sequence",
    "target": "alpha",
    "values": [1, 0.8, 1],
    "stepDuration": 0.3,
    "loop": true,
    "blendMode": "multiply"
  }
],
"keyframes": [
  {
    "id": "kf-1",
    "time": 0,
    "stateObj": { "scaleX": 1 }
  },
  {
    "id": "kf-2",
    "time": 2,
    "stateObj": { "scaleX": 1.5 }
  }
]
}

In diesem Beispiel:

  • Ausdruck steuert die horizontale Position (Ersetzen-Modus)
  • Prozeduraler Wiggle fügt subtile Rotationsvariationen hinzu
  • Sequenz pulsiert die Opazität
  • Keyframe skaliert das Element (niedrigste Priorität)

Wichtige Hinweise

Ausdruckssandbox

  • Ausdrücke laufen in einem eingeschränkten Kontext zur Sicherheit
  • Zugriff nur auf Animationskontextvariablen
  • Kein Zugriff auf DOM, externe Bibliotheken oder Node.js-APIs
  • Bewertungsfehler deaktivieren die Animation

Leistung

  • Ausdrücke: Jede Frame ausgewertet - halte sie einfach
  • Prozedural: Optimierte eingebaute Funktionen - sehr effizient
  • Sequenz: Minimaler Overhead, gut für diskrete Änderungen
  • Pfad: Moderate Kosten, abhängig von der Komplexität des Pfades

Timing

  • startTime und duration sind relativ zur start-Zeit des Elements
  • localTime in Ausdrücken beginnt bei 0, wenn das Element beginnt
  • Animationen respektieren die Gesamtgrenze der duration des Elements

Debugging

  • Wenn eine Animation nicht funktioniert, überprüfen Sie:
    • enabled: true
    • target-Eigenschaft existiert am Element
    • Ausdruckssyntax ist gültiges JavaScript
    • startTime liegt innerhalb der Dauer des Elements
    • Keine Tippfehler im Eigenschaftspfad

Häufige Anwendungsfälle

Sanfter Folgewirkung

{
  "type": "expression",
  "target": "x",
  "expression": "value + (targetX - value) * 0.1"
}

Elastischer Bounce

{
  "type": "expression",
  "target": "scaleY",
  "expression": "1 + Math.exp(-localTime * 3) * Math.cos(localTime * 8) * 0.5"
}

Kamerawackeln

{
  "type": "procedural",
  "proceduralType": "wiggle",
  "target": "x",
  "frequency": 10,
  "amplitude": 5
}

Versetzte Animation (in Gruppen)

{
  "type": "expression",
  "target": "alpha",
  "expression": "Math.max(0, Math.min(1, (localTime - index * 0.1) * 2))"
}