Add motion to design elements by creating entrance, exit, and loop animations using CE.SDK’s animation system.
CE.SDK provides a unified animation system for adding motion to design elements. Animations are created as separate block instances and attached to target blocks using type-specific methods. You can apply entrance animations (how blocks appear), exit animations (how blocks leave), and loop animations (continuous motion while visible). Text blocks support additional properties for word-by-word or character-by-character reveals.
This guide covers how to create and configure animations programmatically, including entrance, exit, loop, and text animations with customizable timing and easing.
Animation Fundamentals#
We first verify that a block supports animations before creating and attaching them. The basic pattern involves creating an animation instance with engine.block.createAnimation(), then attaching it using the appropriate setter method.
const titleBlock = engine.block.create('text');engine.block.replaceText(titleBlock, 'Create Animations');engine.block.setTextFontSize(titleBlock, 120);engine.block.setTextColor(titleBlock, { r: 1.0, g: 1.0, b: 1.0, a: 1.0 });engine.block.setEnum(titleBlock, 'text/horizontalAlignment', 'Center');engine.block.setWidthMode(titleBlock, 'Auto');engine.block.setHeightMode(titleBlock, 'Auto');engine.block.appendChild(page, titleBlock);engine.block.setDuration(titleBlock, 5.0);
// Check if block supports animations before applyingif (engine.block.supportsAnimation(titleBlock)) { // Create an entrance animation const slideIn = engine.block.createAnimation('slide'); engine.block.setInAnimation(titleBlock, slideIn); engine.block.setDuration(slideIn, 1.2); engine.block.setFloat( slideIn, 'animation/slide/direction', (3 * Math.PI) / 2 ); engine.block.setEnum(slideIn, 'animationEasing', 'EaseOut');}Animation support is available for:
- Graphic blocks with image or video fills
- Text blocks with additional writing style options
- Shape blocks with fills
CE.SDK provides several animation presets:
- Entrance animations: slide, fade, blur, zoom, pop, wipe, pan
- Exit animations: same types as entrance
- Loop animations: breathing_loop, spin_loop, fade_loop, pulsating_loop, jump_loop, squeeze_loop, sway_loop
Entrance Animations#
Entrance animations define how blocks appear on screen. We create the animation with engine.block.createAnimation(), attach it with engine.block.setInAnimation(), and configure the duration with engine.block.setDuration().
// Add fade entrance for the logoconst logoFadeIn = engine.block.createAnimation('fade');engine.block.setInAnimation(logoBlock, logoFadeIn);engine.block.setDuration(logoFadeIn, 0.8);engine.block.setEnum(logoFadeIn, 'animationEasing', 'EaseOut');The animationEasing property controls the animation curve. Available options include Linear, EaseIn, EaseOut, and EaseInOut.
Exit Animations#
Exit animations define how blocks leave the screen. We attach them with engine.block.setOutAnimation(). CE.SDK manages timing automatically to prevent overlap between entrance and exit animations.
const footerBlock = engine.block.create('text');engine.block.replaceText(footerBlock, 'Powered by CE.SDK');engine.block.setTextFontSize(footerBlock, 32);engine.block.setTextColor(footerBlock, { r: 1.0, g: 1.0, b: 1.0, a: 0.7 });engine.block.setEnum(footerBlock, 'text/horizontalAlignment', 'Right');engine.block.setWidthMode(footerBlock, 'Auto');engine.block.setHeightMode(footerBlock, 'Auto');engine.block.appendChild(page, footerBlock);
// Footer appears at start and fades out at the endengine.block.setTimeOffset(footerBlock, 0);engine.block.setDuration(footerBlock, 5.0);
// Create exit animation that plays at the end of the block's durationconst fadeOut = engine.block.createAnimation('fade');engine.block.setOutAnimation(footerBlock, fadeOut);engine.block.setDuration(fadeOut, 1.0);engine.block.setEnum(fadeOut, 'animationEasing', 'EaseIn');When a block has both entrance and exit animations, CE.SDK adjusts their timing based on the block’s duration on the timeline.
Loop Animations#
Loop animations run continuously while the block is visible. We use animation types ending in _loop and attach them with engine.block.setLoopAnimation().
const logoBlock = engine.block.create('graphic');engine.block.setShape(logoBlock, engine.block.createShape('rect'));const logoFill = engine.block.createFill('image');engine.block.setString( logoFill, 'fill/image/imageFileURI', 'https://img.ly/static/ubq_samples/imgly_logo.jpg');engine.block.setFill(logoBlock, logoFill);engine.block.setWidth(logoBlock, 200);engine.block.setHeight(logoBlock, 200);engine.block.appendChild(page, logoBlock);engine.block.setDuration(logoBlock, 5.0);// Contain the image within the block frameengine.block.setEnum(logoBlock, 'contentFill/mode', 'Contain');
// Create a pulsating loop animationconst pulsating = engine.block.createAnimation('pulsating_loop');engine.block.setLoopAnimation(logoBlock, pulsating);engine.block.setDuration(pulsating, 1.5);Loop animations continue throughout the block’s visible duration, creating continuous motion effects like breathing, spinning, or pulsating.
Animation Properties#
Each animation type exposes configurable properties. We use engine.block.setFloat() and engine.block.setEnum() to adjust these properties, and engine.block.findAllProperties() to discover available options.
// Create slide animation and configure direction for titleconst titleInAnim = engine.block.getInAnimation(titleBlock);if (titleInAnim !== 0) { // Discover all available properties for this animation const properties = engine.block.findAllProperties(titleInAnim); console.log('Slide animation properties:', properties);}Common configurable properties include:
- Direction: Set in radians for slide animations (0=right, PI/2=bottom, PI=left, 3*PI/2=top)
- Easing: Linear, EaseIn, EaseOut, EaseInOut
Text Animations#
Text blocks support additional animation properties for granular control over how text appears. The textAnimationWritingStyle property controls whether the animation applies to the entire text, line by line, word by word, or character by character.
const subtitleBlock = engine.block.create('text');engine.block.replaceText(subtitleBlock, 'Entrance • Exit • Loop');engine.block.setTextFontSize(subtitleBlock, 48);engine.block.setTextColor(subtitleBlock, { r: 0.9, g: 0.9, b: 1.0, a: 0.9});engine.block.setEnum(subtitleBlock, 'text/horizontalAlignment', 'Center');engine.block.setWidthMode(subtitleBlock, 'Auto');engine.block.setHeightMode(subtitleBlock, 'Auto');engine.block.appendChild(page, subtitleBlock);engine.block.setDuration(subtitleBlock, 5.0);
// Create text animation with word-by-word revealconst textAnim = engine.block.createAnimation('fade');engine.block.setInAnimation(subtitleBlock, textAnim);engine.block.setDuration(textAnim, 1.5);
// Configure text animation writing style (Line, Word, or Character)engine.block.setEnum(textAnim, 'textAnimationWritingStyle', 'Word');// Set overlap for cascading effect (0 = sequential, 0-1 = cascading)engine.block.setFloat(textAnim, 'textAnimationOverlap', 0.3);Writing style options:
- Line: Animate entire lines together
- Word: Animate word by word
- Character: Animate character by character
The textAnimationOverlap property (0 to 1) controls the cascading effect. A value of 0 means sequential animation, while values closer to 1 create more overlap between segments.
Managing Animation Lifecycle#
We can retrieve current animations using engine.block.getInAnimation(), engine.block.getOutAnimation(), and engine.block.getLoopAnimation(). A return value of 0 indicates no animation is attached.
// Example: Retrieve animations to verify they're attachedconst currentTitleIn = engine.block.getInAnimation(titleBlock);const currentLogoLoop = engine.block.getLoopAnimation(logoBlock);const currentFooterOut = engine.block.getOutAnimation(footerBlock);
console.log( 'Animation IDs - Title In:', currentTitleIn, 'Logo Loop:', currentLogoLoop, 'Footer Out:', currentFooterOut);
// Get available easing optionsconst easingOptions = engine.block.getEnumValues('animationEasing');console.log('Available easing options:', easingOptions);When replacing animations, destroy the old instance with engine.block.destroy() to prevent memory leaks.
Saving the Scene#
After creating animations, we save the scene to a .scene file for later use or distribution. The engine.scene.saveToString() method serializes the scene to a string that can be written to a file.
// Save the scene to a .scene filemkdirSync('output', { recursive: true });const sceneString = await engine.scene.saveToString();writeFileSync('output/animated-scene.scene', sceneString);console.log('Scene saved to output/animated-scene.scene');The saved .scene file can be loaded later using engine.scene.loadFromString() or engine.scene.loadFromURL().
Troubleshooting#
Animation Not Playing#
Verify the block supports animations with engine.block.supportsAnimation(). Ensure the scene is created with engine.scene.createVideo(), as animations require timeline-based playback.
Duration Issues#
Ensure the animation is attached to a block before setting its duration. Duration is set on the animation instance, not the block.
Memory Leaks#
When replacing an animation, destroy the old animation instance before creating a new one:
const current = engine.block.getInAnimation(block);if (current !== 0) { engine.block.destroy(current);}const newAnim = engine.block.createAnimation('fade');engine.block.setInAnimation(block, newAnim);Timing Conflicts#
If entrance and exit animations seem to overlap incorrectly, CE.SDK automatically adjusts durations to prevent conflicts. Reduce individual animation durations if needed.
API Reference#
| Method | Description |
|---|---|
engine.block.createAnimation(type) | Create animation instance |
engine.block.supportsAnimation(block) | Check if block supports animations |
engine.block.setInAnimation(block, anim) | Attach entrance animation |
engine.block.setOutAnimation(block, anim) | Attach exit animation |
engine.block.setLoopAnimation(block, anim) | Attach loop animation |
engine.block.getInAnimation(block) | Get entrance animation (0 if none) |
engine.block.getOutAnimation(block) | Get exit animation (0 if none) |
engine.block.getLoopAnimation(block) | Get loop animation (0 if none) |
engine.block.setDuration(anim, seconds) | Set animation duration |
engine.block.setEnum(anim, prop, value) | Set enum property (easing, writing style) |
engine.block.setFloat(anim, prop, value) | Set float property (direction, overlap) |
engine.block.findAllProperties(anim) | List available properties |
engine.block.getEnumValues(prop) | Get enum options |
engine.block.destroy(anim) | Destroy animation instance |
engine.scene.saveToString() | Save scene to string |