FasterMotion
API ReferenceText

Text Animation

Canvas-based per-character text animation with presets and stagger effects

Text Animation is a canvas-based text animation system that splits text into individual characters, words, or lines for per-element animation. It provides 12+ built-in animation presets and flexible stagger options.

Basic Usage

import { createTextAnimator, TextAnimationPresets } from 'faster-motion';

// Create a text animator
const animator = createTextAnimator('Hello World', {
  x: 200,
  y: 100,
  fontSize: 48,
  fontFamily: 'Arial, sans-serif',
  fontWeight: 'bold',
  fillColor: '#01b2a8',
  textAlign: 'center'
});

// Animate using a preset
const timeline = animator.animatePreset('typewriter');
timeline.play();

// Render in your animation loop
function render() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  animator.render(ctx);
  requestAnimationFrame(render);
}
render();

Try it: Basic Text Animation

const animator = createTextAnimator('Hello World', {
  x: 200, y: 100,
  fontSize: 48,
  fillColor: '#01b2a8'
});
animator.animatePreset('fadeUp').play();

createTextAnimator()

Factory function to create a TextAnimator instance.

Syntax

createTextAnimator(
  text: string,
  options?: TextAnimatorOptions
): TextAnimator

Parameters

  • text - string - The text content to animate
  • options - TextAnimatorOptions (optional) - Configuration object

Returns

TextAnimator - A TextAnimator instance ready for animation

TextAnimatorOptions

PropertyTypeDefaultDescription
splitTypeSplitType'chars'How to split text: 'chars', 'words', 'lines'
fontSizenumber24Font size in pixels
fontFamilystring'Arial, sans-serif'Font family
fontWeightstring | number'normal'Font weight
fillColorstring'#000000'Fill color
strokeColorstring-Stroke color (optional)
strokeWidthnumber0Stroke width in pixels
xnumber0X position of text origin
ynumber0Y position of text origin
textAlign'left' | 'center' | 'right''left'Text alignment
lineHeightnumber1.2Line height multiplier
letterSpacingnumber0Letter spacing in pixels
wordSpacingnumber0Word spacing in pixels
maxWidthnumber-Max width for line wrapping
includeWhitespacebooleanfalseInclude whitespace characters

Split Types

Characters (Default)

Split text into individual characters for per-character animation.

const animator = createTextAnimator('Hello', {
  splitType: 'chars'  // Default
});
// Creates 5 animated elements: H, e, l, l, o

Words

Split text into words for word-by-word animation.

const animator = createTextAnimator('Hello World', {
  splitType: 'words'
});
// Creates 2 animated elements: "Hello", "World"

Try it: Word Animation

const animator = createTextAnimator('The quick brown fox', {
  splitType: 'words',
  fillColor: '#4ecdc4'
});
animator.animatePreset('scaleUp').play();

Lines

Split text by line breaks for line-by-line animation.

const animator = createTextAnimator('Line One\nLine Two\nLine Three', {
  splitType: 'lines'
});
// Creates 3 animated elements (one per line)

Animation Presets

TextAnimator includes 12+ built-in animation presets.

Available Presets

PresetDescriptionStagger
typewriterCharacters appear one by onestart
fadeUpFade in from belowstart
fadeDownFade in from abovestart
fadeLeftFade in from leftstart
fadeRightFade in from rightend
scaleUpScale up from zero with bouncecenter
waveCharacters move up and downstart
rotateInRotate and scale instart
blurInScale in with blur effectstart
elasticInElastic bounce instart
randomRevealRandom order revealrandom
dropFall from above with bouncestart
spreadCenterSpread from centercenter

Using Presets

// Using preset by name
const timeline = animator.animatePreset('typewriter');
timeline.play();

// Using custom preset object
const timeline = animator.animatePreset({
  from: { opacity: 0, y: 30 },
  to: { opacity: 1, y: 0 },
  duration: 500,
  stagger: { each: 40, from: 'start' },
  ease: 'back.out'
});

Try it: All Presets

// Try different presets
animator.animatePreset('typewriter');
animator.animatePreset('fadeUp');
animator.animatePreset('scaleUp');
animator.animatePreset('elasticIn');

Custom Animation

animate()

Create custom animations with full control over properties and stagger.

animate(
  from: Record<string, number>,
  to?: Record<string, number>,
  options?: {
    duration?: number;
    stagger?: TextStaggerOptions;
    ease?: string;
    timeline?: Timeline;
  }
): Timeline

Example

const timeline = animator.animate(
  { opacity: 0, y: 20, scaleX: 0.5, scaleY: 0.5 },  // from
  undefined,  // to (defaults to original values)
  {
    duration: 400,
    stagger: { each: 80, from: 'center' },
    ease: 'back.out'
  }
);
timeline.play();

Animatable Properties

PropertyDefaultDescription
opacity1Character opacity (0-1)
xoriginalX offset from original position
yoriginalY offset from original position
scaleX1Horizontal scale
scaleY1Vertical scale
rotation0Rotation in degrees

Try it: Custom Animation

animator.animate(
  { opacity: 0, y: 30, rotation: -45 },
  undefined,
  { duration: 500, stagger: { each: 50, from: 'edges' } }
).play();

Stagger Options

Control the timing and order of character animations.

TextStaggerOptions

PropertyTypeDefaultDescription
eachnumber0Delay between each element (ms)
totalnumber-Total duration to spread stagger across
fromFromOption'start'Starting position for stagger
easestring-Easing for stagger timing

From Options

ValueDescription
'start'Animate from first to last character
'end'Animate from last to first character
'center'Animate from center outward
'edges'Animate from edges to center
'random'Random order
numberFrom specific character index
// From center outward
animator.animate(
  { opacity: 0, scaleX: 0, scaleY: 0 },
  undefined,
  { stagger: { each: 50, from: 'center' } }
);

// From edges to center
animator.animate(
  { opacity: 0, y: 20 },
  undefined,
  { stagger: { each: 40, from: 'edges' } }
);

// Random order
animator.animate(
  { opacity: 0 },
  undefined,
  { stagger: { each: 30, from: 'random' } }
);

Try it: Stagger Directions

// Try: 'start', 'end', 'center', 'edges', 'random'
animator.animate(
  { opacity: 0, y: 20 },
  undefined,
  { stagger: { each: 80, from: 'center' } }
).play();

Convenience Methods

animateIn()

Animate characters from hidden to visible.

animator.animateIn({
  duration: 400,
  stagger: { each: 30, from: 'start' },
  ease: 'curve2.out',
  from: { opacity: 0, y: 20 }  // Optional custom from values
}).play();

animateOut()

Animate characters from visible to hidden.

animator.animateOut({
  duration: 400,
  stagger: { each: 30, from: 'end' },
  ease: 'curve2.in',
  to: { opacity: 0, y: -20 }  // Optional custom to values
}).play();

createWave()

Create a continuous wave animation.

animator.createWave({
  amplitude: 10,    // Wave height
  frequency: 0.5,   // Wave frequency
  speed: 1000,      // Animation speed
  axis: 'y'         // 'x' or 'y'
}).play();

Styling

Styled Text

const animator = createTextAnimator('STYLED', {
  x: 200,
  y: 100,
  fontSize: 48,
  fontFamily: 'Georgia, serif',
  fontWeight: 'bold',
  fillColor: '#22d3ee',
  strokeColor: '#0891b2',
  strokeWidth: 2,
  textAlign: 'center'
});

Dynamic Styling

// Change fill color for all characters
animator.setFillColor('#ff6b6b');

// Change stroke for all characters
animator.setStroke('#e94560', 2);

Try it: Styled Text

const animator = createTextAnimator('STYLED', {
  fillColor: '#22d3ee',
  strokeColor: '#0891b2',
  strokeWidth: 2
});

Multi-line Text

TextAnimator supports multi-line text with automatic layout.

const animator = createTextAnimator('Line One\nLine Two\nLine Three', {
  x: 200,
  y: 50,
  fontSize: 24,
  textAlign: 'center',
  lineHeight: 1.4
});

// Each line animates in sequence
animator.animatePreset('fadeUp').play();

Word Wrapping

Enable automatic word wrapping with maxWidth:

const animator = createTextAnimator(
  'This is a long text that will wrap automatically',
  {
    maxWidth: 300,
    lineHeight: 1.3
  }
);

Utility Methods

reset()

Reset all characters to original position and default transforms.

animator.reset();

setText()

Update the text content (re-splits the text).

animator.setText('New Text');

getChar() / getWord() / getLine()

Access individual elements by index.

const firstChar = animator.getChar(0);
const secondWord = animator.getWord(1);
const firstLine = animator.getLine(0);

Properties

Read-only Properties

PropertyTypeDescription
textstringOriginal text content
splitTypeSplitTypeSplit type used
charsTextCharacter[]All character elements
wordsTextCharacter[][]Characters grouped by word
linesTextCharacter[][]Characters grouped by line
charCountnumberTotal character count
wordCountnumberTotal word count
lineCountnumberTotal line count
measuredWidthnumberTotal measured width
measuredHeightnumberTotal measured height

Complete Example

import { createTextAnimator, CanvasRenderer } from 'faster-motion';

// Setup canvas
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// Create animator
const animator = createTextAnimator('FasterMotion', {
  x: canvas.width / 2,
  y: canvas.height / 2,
  fontSize: 48,
  fontWeight: 'bold',
  fillColor: '#01b2a8',
  textAlign: 'center'
});

// Animate with preset
const timeline = animator.animatePreset('elasticIn');
timeline.play();

// Render loop
function render() {
  ctx.fillStyle = '#1a1a2e';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  animator.render(ctx);
  requestAnimationFrame(render);
}
render();

// Reset and replay
document.getElementById('replay').addEventListener('click', () => {
  animator.reset();
  animator.animatePreset('elasticIn').play();
});

Examples

See Also

On this page