Tutorial: Morphing " Sequenced Animations
Cree transformaciones de forma mesmerizantes y animaciones de varios elementos coreografiadas.
Tiempo: 20 minutos Dificultad Avances
Lo que crearás
Una secuencia dinámica en la que las formas se transforman entre sí mientras que el texto revela con el tiempo escalofriante.
Características cubiertas
- Mortalización de la forma — Transiciones de la espuma entre diferentes formas
- Animaciones activadas — Tiempo secuenciado para múltiples elementos
- Transiciones de color — Cambios de color gradiente animado
- Mask revela — Toallaje cinematográfico y efectos iris
- Choreographed sequences — Precisely timed multi-element dance
Parte 1: Morphing de forma
Paso 1: Crear forma de fuente
- Crear un círculo en el centro:
- Radius: 80
- Color:
#3b82f6(azul) - Position: (400, 300)
const circle = app.create('circle', {
x: 400, y: 300,
radius: 80,
color: '#3b82f6'
});
Paso 2: Crear forma de objetivo
- Crear una estrella (será el objetivo morfista):
- Puntos: 5
- Radius: 100
- Color:
#f59e0b(amber) - Position: (400, 300)
const star = app.create('star', {
x: 400, y: 300,
points: 5,
radius1: 100,
radius2: 40,
color: '#f59e0b'
});
Paso 3: Agregar la relación morph
La relación morphs_to crea transiciones de forma suave:
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
});
Paso 4: Cadena Múltiples Morphs
Crear una secuencia de morfología: Círculo → Estrella → Triángulo → Círculo
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
});
Parte 2: Revelación de texto en estadio
Paso 5: Crear el Collage de Carta
const collage = app.letterCollage.create('TRANSFORM', {
style: 'gradient',
gradientPalette: 'cyberpunk',
gradientDirection: 'horizontal',
fontSize: 64,
x: 400, y: 500
});
Paso 6: Aplicar la animación apilada
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'
});
Patrones de secuencia
| Patrón | Efecto |
|---|---|
linear |
Izquierda a derecha |
reverse |
Derecho a la izquierda |
center |
Center outward |
random |
Orden aleatoria |
wave |
Tiempo de onda sine |
fibonacci |
Ritmo natural |
Parte 3: Revelaciones de máscara
Paso 7: Add Dramatic Reveal
Revelar la forma de morder con un efecto iris:
// Apply animated mask to the shape container
app.applyAnimatedMask(shapes[0], 'iris', {
startTime: 0,
duration: 0.8,
easing: 'easeOut'
});
Paso 8: Revelación de cuerda para texto
// Reveal text with horizontal wipe
app.applyAnimatedMask(collage.group, 'wipeLeft', {
startTime: 0.5, // Start after shape reveals
duration: 0.6,
easing: 'easeInOut'
});
Máscara disponible
| Preset | Efecto |
|---|---|
iris |
Circle que se expande desde el centro |
wipeLeft |
Revelación horizontal de izquierda |
wipeUp |
Revelación vertical desde abajo |
star |
La forma de estrella se expande |
heart |
Forma del corazón expandiendo |
curtainHorizontal |
Abre del centro |
diagonalWipe |
Revelación enraizada |
Parte 4: Coreografía completa
Full Animation Script
// === 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);
Ajustes de exportación
Para mejores resultados con animaciones de morfología:
| Ajuste | Valor | Razón |
|---|---|---|
| Formato | WebM | La mejor calidad para los gradientes |
| Tasa de fractura | 60 fps | Morfinas madre |
| Duración | 6 segundos | Ciclo completo |
| Calidad | Alto | Transiciones Preserve color |
Consejos Pro
Overlap timing — Comience la siguiente animación 0.1-0.2s antes de los extremos anteriores para el flujo sin costuras.
Utilizar colores complementarios Los morfos de forma se ven mejor cuando se transfiere entre colores que funcionan bien juntos.
Center sequence for impact — El patrón de estancamiento
centerllama la atención sobre el medio del texto.
Revelación al contenido — Use
irispara formas circulares,wipeLeftpara texto.
Variaciones
Visualización de datos 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'
});
Secuencia de Animación Logo
// 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' }
]);
});
Siguientes pasos
- [Animación física] (/tutorials/physics-animation) — Efectos de la recompensa y el elástico
- [Map Animations] (/tutorials/map-animation) — Geográfica de datos
- [Masking System] (/features/masking) — Técnicas avanzadas de revelación