Tutorial: Morphing & Sekventerede Animationer

Opret hypnotiserende form transformationer og koreograferede multielement animationer.

    • Tid: * * 20 minutter
    • Problemer: * * Avanceret

Hvad du vil oprette

En dynamisk sekvens, hvor former morf ind i hinanden, mens tekst afslører med forskudt timing.

Shape morping med forskudt tekst reveal

Funktioner dækket

      • Form morping * * - Glat overgange mellem forskellige former
      • Staggered animationer * * - Sekventeret timing for flere elementer
      • Farveovergange * * - Animerede gradientfarveændringer
      • Mask afslører * * - cinematisk tørre og iris effekter
      • Koreograferede sekvenser * * - Præcis timet multielement dans

Del 1: Form Morphing

Trin 1: Opret kildeform

  1. Opret en cirkel i midten:
    • Radius: * * 80 * *
    • Farve: #3b82f6 (blå)
    • Position: (400, 300)
const circle = app.create('circle', {
  x: 400, y: 300,
  radius: 80,
  color: '#3b82f6'
});

Trin 2: Opret mål form

  1. Opret en stjerne (vil være morfmålet):
    • Point: * * 5 * *
    • Radius: * * 100 * *
    • Farve: #f59e0b (rav)
    • Position: (400, 300)
const star = app.create('star', {
  x: 400, y: 300,
  points: 5,
  radius1: 100,
  radius2: 40,
  color: '#f59e0b'
});

Trin 3: Tilføj Morph Relation

morphs_to forholdet skaber glatte formovergange:

app.addRelation(circle.data.id, star.data.id, 'morphs_to', {
  duration: 1.5,
  easing: 'easeInOut',
  morphColor: true,   // Also transition colors
  morphSize: true     // Also transition size
});

Trin 4: Kæde flere morfer

Opret en morpingsekvens: Circle → Star → Trekant → Circle

const shapes = [];

// Circle
shapes.push(app.create('circle', {
  x: 400, y: 300, radius: 80, color: '#3b82f6'
}));

// Star
shapes.push(app.create('star', {
  x: 400, y: 300, points: 5, radius1: 100, radius2: 40,
  color: '#f59e0b', opacity: 0
}));

// Triangle
shapes.push(app.create('triangle', {
  x: 400, y: 300, radius: 90,
  color: '#10b981', opacity: 0
}));

// Hexagon (back to geometric)
shapes.push(app.create('polygon', {
  x: 400, y: 300, sides: 6, radius: 85,
  color: '#8b5cf6', opacity: 0
}));

// Chain morphs with delays
for (let i = 0; i < shapes.length - 1; i++) {
  app.addRelation(shapes[i].data.id, shapes[i + 1].data.id, 'morphs_to', {
    duration: 1.2,
    delay: i * 1.5,  // Stagger start times
    easing: 'easeInOut',
    morphColor: true
  });
}

// Loop back to first shape
app.addRelation(shapes[shapes.length - 1].data.id, shapes[0].data.id, 'morphs_to', {
  duration: 1.2,
  delay: (shapes.length - 1) * 1.5,
  easing: 'easeInOut',
  morphColor: true
});

Del 2: Steriliseret tekst

Trin 5: Opret brev Collage

const collage = app.letterCollage.create('TRANSFORM', {
  style: 'gradient',
  gradientPalette: 'cyberpunk',
  gradientDirection: 'horizontal',
  fontSize: 64,
  x: 400, y: 500
});

Trin 6: Anvend Staggered Animation

app.letterCollage.applyStaggeredAnimation(collage.collageId, {
  effect: 'fadeSlideUp',
  staggerDelay: 0.06,    // 60ms between letters
  duration: 0.5,
  sequence: 'center',     // Start from center, expand outward
  easing: 'easeOut'
});

Sekvensmønstre

Mønster Virkning
linear Venstre mod højre
reverse Højre mod venstre
center Centrér udad
random Tilfældig rækkefølge
wave Timingen af Sine Wave
fibonacci Naturlig rytme

Del 3: Maske

Trin 7: Tilføj Dramatic Reveal

Afslør morphering form med en iris effekt:

// Apply animated mask to the shape container
app.applyAnimatedMask(shapes[0], 'iris', {
  startTime: 0,
  duration: 0.8,
  easing: 'easeOut'
});

Trin 8: Tør frafald for tekst

// Reveal text with horizontal wipe
app.applyAnimatedMask(collage.group, 'wipeLeft', {
  startTime: 0.5,  // Start after shape reveals
  duration: 0.6,
  easing: 'easeInOut'
});

Tilgængelige Mask Presets

Præset Virkning
iris Circle udvides fra midten
wipeLeft Vandret afsløring fra venstre
wipeUp Lodret afsløring fra bunden
star Stjerneformekspanderende
heart Hjerteform ekspanderende
curtainHorizontal Åbner fra midten
diagonalWipe Vinklet afsløring

Del 4: Komplet koreografi

Fuld Animeringsscript

// === SETUP ===
app.setCanvasSize({ width: 800, height: 600 });
app.setBackgroundColor('#0f172a');

// === MORPHING SHAPES ===
const shapeColors = ['#3b82f6', '#f59e0b', '#10b981', '#8b5cf6'];
const shapeTypes = ['circle', 'star', 'triangle', 'polygon'];

const mainShape = app.create('circle', {
  x: 400, y: 250,
  radius: 80,
  color: shapeColors[0]
});

// Keyframe the shape through color transitions
app.addAnimation(mainShape.data.id, [
  { time: 0, properties: { fillColor: '#3b82f6', scale: 1 } },
  { time: 1.5, properties: { fillColor: '#f59e0b', scale: 1.2 }, easing: 'easeInOut' },
  { time: 3, properties: { fillColor: '#10b981', scale: 0.9 }, easing: 'easeInOut' },
  { time: 4.5, properties: { fillColor: '#8b5cf6', scale: 1.1 }, easing: 'easeInOut' },
  { time: 6, properties: { fillColor: '#3b82f6', scale: 1 }, easing: 'easeInOut' }
]);

// Add rotation for visual interest
app.addAnimation(mainShape.data.id, [
  { time: 0, properties: { rotation: 0 } },
  { time: 6, properties: { rotation: 360 }, easing: 'linear' }
]);

// === IRIS REVEAL FOR SHAPE ===
app.applyAnimatedMask(mainShape, 'iris', {
  startTime: 0,
  duration: 0.6,
  easing: 'easeOut'
});

// === STAGGERED TEXT ===
const title = app.letterCollage.create('TRANSFORM', {
  style: 'tile',
  palette: 'neon',
  fontSize: 56,
  x: 400, y: 480
});

app.letterCollage.applyStaggeredAnimation(title.collageId, {
  effect: 'popIn',
  staggerDelay: 0.05,
  duration: 0.4,
  sequence: 'center',
  easing: 'elastic'
});

// === ORBITING ACCENTS ===
const orbitColors = ['#f472b6', '#34d399', '#fbbf24'];
orbitColors.forEach((color, i) => {
  const dot = app.create('circle', {
    x: 400, y: 250,
    radius: 6,
    color: color
  });

  app.addRelation(dot.data.id, mainShape.data.id, 'orbits', {
    radius: 120 + i * 25,
    speed: 0.4 - i * 0.1,
    phase: i * (Math.PI * 2 / 3)
  });

  // Fade in the orbiting dots
  app.addAnimation(dot.data.id, [
    { time: 0.8 + i * 0.2, properties: { opacity: 0, scale: 0 } },
    { time: 1.2 + i * 0.2, properties: { opacity: 1, scale: 1 }, easing: 'elastic' }
  ]);
});

// === CAMERA MOVEMENT ===
app.addRelation('camera', null, 'camera_animates', {
  duration: 6,
  loop: true,
  keyframes: [
    { time: 0, zoom: 1, center: [400, 300] },
    { time: 1.5, zoom: 1.15, center: [400, 280], easing: 'easeOut' },
    { time: 3, zoom: 1.05, center: [400, 320], easing: 'easeInOut' },
    { time: 4.5, zoom: 1.1, center: [400, 300], easing: 'easeInOut' },
    { time: 6, zoom: 1, center: [400, 300], easing: 'easeOut' }
  ]
});

// === PLAY ===
app.playKeyframeTimeline(6, true);

Eksportér indstillinger

For de bedste resultater med morping animationer:

Indstilling Værdi Årsag
Format WebM Bedste kvalitet for gradienter
Rammesats 60 fps Andre morfer
Varighed 6 sekunder Fuld løkke-cyklus
Kvalitet Høj Bevar farveovergange

Pro Tips

    • Overlap timing * * - Start den næste animation 0.1- 0.2s før de foregående ender for problemfri flow.
    • Brug komplementære farver * * - Form morfer ser bedst ud, når overgangen mellem farver, der fungerer godt sammen.
    • Midtersekvens for nedslag * * - center staggermønsteret tiltrækker opmærksomhed til midten af teksten.
    • Match afslører indhold * * - Brug iris til cirkulære former, wipeLeft til tekst.

Ændringer

Data Visualisering Morph

// Bar chart to pie chart transition
const bars = createBarChart(data);
const pie = createPieChart(data);

app.addRelation(bars.data.id, pie.data.id, 'morphs_to', {
  duration: 2,
  easing: 'easeInOut'
});

Logo Animation Sequence

// Logo parts appear in sequence
const logoParts = [shape1, shape2, shape3, text];

logoParts.forEach((part, i) => {
  app.addAnimation(part.data.id, [
    { time: i * 0.3, properties: { opacity: 0, scale: 0.5 } },
    { time: i * 0.3 + 0.4, properties: { opacity: 1, scale: 1 }, easing: 'elastic' }
  ]);
});

Næste skridt

  • [Fysik Animation] (/tutorials/physics-animation) - Bounce og elastiske effekter
  • [Kort Animationer] (/tutorials/map-animation) - Geografiske data historiefortælling
  • [Mask System] (/features/masking) - Avancerede afsløringsteknikker