Animatie

Geavanceerd animatiesysteem voor het creëren van dynamische, procedurele en op expressies gebaseerde animaties die verder gaan dan eenvoudige keyframes.

Animatietypen

Het animatiesysteem ondersteunt verschillende types naast traditionele keyframes:

  • Expressie: JavaScript-expressies die per frame worden geëvalueerd
  • Procedureel: Ingebouwde procedurele animatiepatronen
  • Volgorde: Stapgebaseerde sequentiële animaties
  • Pad: Beweging langs Bezier-paden

Deze geavanceerde animaties worden gedefinieerd in de animations array-eigenschap van elementen.

Node-animaties vs Keyframes

Node-animaties (animations array):

  • Procedurele, op expressies gebaseerde of padvolgende animaties
  • Worden elke frame geëvalueerd
  • Hogere prioriteit dan keyframes
  • Kunnen keyframewaarden overschrijven

Keyframes (keyframes array):

  • Eenvoudige eigenschapinterpolatie tussen gedefinieerde punten
  • Lagere prioriteit
  • Voorspelbaar, gemakkelijk te bewerken

Animatieprioriteit

Wanneer meerdere animatiemethoden hetzelfde eigenschap doelwit zijn:

  1. Hoogste: Node-animaties (expressie, procedureel, pad, volgorde)
  2. Gemiddeld: Keyframe-animaties
  3. Laagste: Statische eigenschapswaarden
EigenschapTypeVereistVoorbeeldWaardenbereikOmschrijving
typestringtrue-expression | procedural | sequence | pathHet type animatie.
enabledbooleanfalse--Of de animatie actief is.
targetstringtrue--Het eigenschapspad om te animeren (bijv. "x", "rotation", "scaleX").
startTimenumberfalse--Starttijd van de animatie relatief aan het begin van het element, in seconden.
durationnumberfalse--Duur van de animatie in seconden. Voor herhalende animaties is dit de herhalingsperiode.
loopbooleanfalse--Of de animatie herhaalt.
blendModestringfalse-replace | add | multiplyHoe deze animatie combineert met andere: vervangen (overschrijven), toevoegen (som), vermenigvuldigen (schaal).
blendWeightnumberfalse--De sterkte/invloed van deze animatie (0-1). Gebruikt voor het mengen van meerdere animaties.

Expressie-animaties

Expressies zijn JavaScript-code die per frame wordt geëvalueerd, met toegang tot animatiecontextvariabelen.

Beschikbare contextvariabelen

{
  time: number; // Huidige absolute tijd (seconden)
  localTime: number; // Tijd ten opzichte van het begin van het element
  duration: number; // Duur van het element
  progress: number; // Genormaliseerde voortgang (0-1)
  index: number; // Elementindex in de groep
  total: number; // Totaal aantal elementen in de groep
  fps: number; // Frames per seconde
  width: number; // Canvasbreedte
  height: number; // Canvashoogte
  value: any; // Huidige eigenschapswaarde
}

Voorbeeld van een expressie

Bounce-animatie met behulp van Math-functies:

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
  }
]
}

Complexe expressie

Combineer meerdere effecten:

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
  }
]
}

Procedurele animaties

Ingebouwde animatiepatronen met configureerbare parameters.

Procedurele types

  • wiggle: Willekeurige oscillatie (nuttig voor handheld camera-effecten)
  • wave: Sinus-/cosinusgolfbeweging
  • bounce: Elastisch bounce-effect
  • pulse: Ritmische schaling

Wiggle voorbeeld

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

Sequentie-animaties

Stapgebaseerde animaties die waarden op specifieke intervallen veranderen.

EigenschapTypeVereistVoorbeeldWaardenbereikOmschrijving
valuesarraytrue--Array van waarden om doorheen te stappen.
stepDurationnumbertrue--Duur van elke stap in seconden.
loopbooleanfalse--Of de sequentie moet herhalen.

Voorbeeld van een sequentie

Tekst die door verschillende groottes cycled:

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

Pad-animaties

Animeer elementen langs Bezier-krommingen.

EigenschapTypeVereistVoorbeeldWaardenbereikOmschrijving
pathstring | arraytrue--SVG-padgegevens (d-attribuut) of array van padpunten.
autoRotatebooleanfalse--Of het element automatisch moet draaien om de padtangens te volgen.
durationnumbertrue--Tijd om het volledige pad te voltooien.

Voorbeeld van een pad

Circulaire beweging:

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
  }
]
}

Eigenschapspad-syntaxis

De target eigenschap gebruikt puntnotatie om geneste eigenschappen aan te geven:

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

Voorbeelden van doelresolutie

{
  "target": "x"              // De x-positie van het element
  "target": "scaleX"         // Horizontale schaling
  "target": "alpha"          // Opacity
  "target": "fill.color"     // Opvulkleur (als fill een object is)
  "target": "points[0].x"    // X-coördinaat van het eerste punt
}

Mengmodi

Beheer hoe animaties combineren wanneer meerdere hetzelfde eigenschap doelwit zijn:

Vervangen (Standaard)

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

Vervangt volledig de eigenschapswaarde.

Toevoegen

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

Voegt toe aan de bestaande waarde (gewogen). Nuttig voor het accumuleren van offsetwaarden.

Vermenigvuldigen

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

Vermenigvuldigt de bestaande waarde. Nuttig voor schaaleffecten.

Voorbeeld van meerdere animaties

Het combineren van verschillende animatietypen:

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 dit voorbeeld:

  • Expressie bestuurt de horizontale positie (vervangmodus)
  • Procedurele wiggle voegt subtiele rotatievariatie toe
  • Sequentie pulseert de opacity
  • Keyframe schaalt het element (laagste prioriteit)

Belangrijke notities

Expressie-sandbox

  • Expressies worden uitgevoerd in een beperkte context voor beveiliging
  • Toegang tot animatiecontextvariabelen alleen
  • Geen toegang tot DOM, externe bibliotheken of Node.js-API's
  • Evaluatiefouten schakelen de animatie uit

Prestaties

  • Expressies: Elke frame geëvalueerd - houd ze eenvoudig
  • Procedureel: Geoptimaliseerde ingebouwde functies - zeer efficiënt
  • Sequentie: Minimale overhead, goed voor discrete veranderingen
  • Pad: Gemiddelde kosten, afhankelijk van de complexiteit van het pad

Timing

  • startTime en duration zijn relatief aan de start tijd van het element
  • localTime in expressies begint bij 0 wanneer het element begint
  • Animaties respecteren de algemene duration grens van het element

Debuggen

  • Als een animatie niet werkt, controleer:
    • enabled: true
    • target eigenschap bestaat op het element
    • Expressiesyntaxis is geldige JavaScript
    • startTime ligt binnen de duur van het element
    • Geen typfouten in de eigenschapspaden

Veelvoorkomende gebruiksgevallen

Soepele volg-effect

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

Elastische bounce

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

Camera-trilling

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

Verspreide animatie (in groepen)

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