Tutoriel: Morphing & Animations séquentielles

Créez des transformations de forme envoûtantes et des animations chorégraphiées à plusieurs éléments.

Heure: 20 minutes Difficulté: Avancé

Ce que vous allez créer

Une séquence dynamique où les formes se transforment l’une en l’autre tandis que le texte se révèle avec un timing décalé.

Modification de la forme avec le texte décalé révèle

Caractéristiques couvertes

  • Modification de la forme — Transitions lisses entre différentes formes
  • Animations stagnées — Calendrier séquentiel pour plusieurs éléments
  • Transitions de couleurs — Changements de couleur de dégradé animés
  • Le masque révèle — Effacement cinématographique et effets iris
  • Séquences chorégraphiées — Danse multi-éléments chronométrée avec précision

Partie 1: Morphing de forme

Étape 1: Créer une forme de source

  1. Créer un cercle au centre :
    • Rayon: 80
    • Couleur: #3b82f6 (bleu)
    • Position: (400, 300)
const circle = app.create('circle', {
  x: 400, y: 300,
  radius: 80,
  color: '#3b82f6'
});

Étape 2: Créer une forme de cible

  1. Créer une étoile (ce sera la cible morph):
    • Points: 5
    • Rayon: 100
    • Couleur : #f59e0b (ambre)
    • Position: (400, 300)
const star = app.create('star', {
  x: 400, y: 300,
  points: 5,
  radius1: 100,
  radius2: 40,
  color: '#f59e0b'
});

Étape 3: Ajouter une relation morphologique

La relation morphs_to crée des transitions en forme lisse :

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
});

Étape 4: Morphs multiples en chaîne

Créer une séquence de morphing: Circle → Star → Triangle → 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
});

Partie 2: Reveal de texte décalé

Étape 5: Créer un collage de lettres

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

Étape 6: Appliquer l’animation décalée

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'
});

Modèles de séquence

Modèle Effet
linear De gauche à droite
reverse De droite à gauche
center Centre vers l’extérieur
random Ordre aléatoire
wave Calage des ondes sinusoïdales
fibonacci Rythme naturel

Troisième partie: Révélateurs de masques

Étape 7: Ajouter une révélation dramatique

Révélez la forme de morphage avec un effet iris:

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

Étape 8 : Révèlez le texte

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

Préréglages de masque disponibles

Préréglage Effet
iris Circle en expansion depuis le centre
wipeLeft Dévoilement horizontal de gauche
wipeUp Dévoilement vertical du bas
star Forme de l’étoile en expansion
heart Forme du cœur en expansion
curtainHorizontal Ouvre depuis le centre
diagonalWipe Dévoilement en angle

Partie 4: Chorégraphie complète

Script complet d’animation

// === 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);

Paramètres d’exportation

Pour de meilleurs résultats avec des animations de transformation :

Réglage Valeur Motifs
Format WebM Meilleure qualité pour les gradients
Taux-cadre 60 fps Morphs plus doux
Durée 6 secondes Cycle complet
Qualité Élevé Préserver les transitions de couleur

Conseils pro

Calendrier d’overlap — Commencer l’animation suivante 0.1-0.2s avant la fin précédente pour un flux continu.

Utiliser des couleurs complémentaires — Les morphs de forme semblent les plus beaux lors de la transition entre les couleurs qui fonctionnent bien ensemble.

Center la séquence pour l’impact — Le schéma de décalage center attire l’attention sur le milieu du texte.

Match discover to content — Utilisez iris pour les formes circulaires, wipeLeft pour le texte.


Variations

Morph de visualisation des données

// 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 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' }
  ]);
});

Prochaines étapes

  • [Animation physique] (/tutorials/physics-animation) — Effets rebonds et élastiques
  • [Map Animations] (/tutorials/map-animation) — Histoire de données géographiques
  • [Masking System] (/features/masking) — Techniques de révélation avancées