Anime.js provides powerful text splitting capabilities that allow you to animate text by lines, words, or individual characters.
Text Splitter
The TextSplitter class wraps text content in elements for granular animation control.
Basic Usage
import { text } from 'animejs' ;
const splitter = new text . TextSplitter ( '.title' , {
chars: true ,
words: true
});
Split by Characters
import { animate , text } from 'animejs' ;
const splitter = new text . TextSplitter ( '.text' , {
chars: true
});
animate ( splitter . chars , {
translateY: [ 40 , 0 ],
opacity: [ 0 , 1 ],
duration: 800 ,
delay : ( el , i ) => i * 30
});
Split by Words
const splitter = new text . TextSplitter ( '.paragraph' , {
words: true
});
animate ( splitter . words , {
scale: [ 0 , 1 ],
opacity: [ 0 , 1 ],
duration: 600 ,
delay : ( el , i ) => i * 50 ,
ease: 'out(3)'
});
Split by Lines
const splitter = new text . TextSplitter ( '.content' , {
lines: true
});
animate ( splitter . lines , {
translateX: [ - 100 , 0 ],
opacity: [ 0 , 1 ],
duration: 1000 ,
delay : ( el , i ) => i * 100
});
Advanced Options
Custom Templates
Customize the wrapper elements:
const splitter = new text . TextSplitter ( '.text' , {
chars: {
class: 'char' ,
wrap: 'clip'
},
words: {
class: 'word' ,
clone: 'bottom'
}
});
Template Parameters
CSS class to apply to wrapper elements
wrap
boolean | 'clip' | string
Wrap elements in additional container. Use ‘clip’ for overflow clipping.
clone
boolean | 'left' | 'right' | 'top' | 'bottom'
Create clone elements for advanced effects. Position determines clone offset direction.
Function Templates
const splitter = new text . TextSplitter ( '.text' , {
chars : ( node ) => {
const char = node . textContent ;
return `<span class="char char- ${ char } ">{value}</span>` ;
}
});
Use {value} as a placeholder for the text content and {i} for the index in custom templates.
Configuration Options
Include Spaces
const splitter = new text . TextSplitter ( '.text' , {
chars: true ,
includeSpaces: true
});
Accessibility
Keep original text accessible for screen readers:
const splitter = new text . TextSplitter ( '.text' , {
chars: true ,
accessible: true // Default: true
});
When accessible is true, the original text is preserved in a visually-hidden element for screen readers.
Debug Mode
Visualize split boundaries:
const splitter = new text . TextSplitter ( '.text' , {
lines: true ,
words: true ,
chars: true ,
debug: true
});
Responsive Behavior
The splitter automatically re-splits text on resize:
const splitter = new text . TextSplitter ( '.text' , {
lines: true ,
words: true
});
// Text will re-split when window resizes
// Line breaks are recalculated automatically
Manual Refresh
// Force a refresh
splitter . refresh ();
Effects with addEffect
Add effects that automatically refresh on resize:
import { animate , text } from 'animejs' ;
const splitter = new text . TextSplitter ( '.text' , {
chars: true
});
splitter . addEffect (( splitter ) => {
return animate ( splitter . chars , {
translateY: [ 20 , 0 ],
opacity: [ 0 , 1 ],
duration: 600 ,
delay : ( el , i ) => i * 20
});
});
Effects added with addEffect() are automatically cleaned up and re-run when the splitter refreshes.
Combining Split Types
const splitter = new text . TextSplitter ( '.text' , {
lines: true ,
words: true ,
chars: true
});
// Animate lines first
animate ( splitter . lines , {
translateY: [ 100 , 0 ],
opacity: [ 0 , 1 ],
duration: 800 ,
delay : ( el , i ) => i * 100
});
// Then animate characters within words
animate ( splitter . chars , {
scale: [ 0 , 1 ],
duration: 400 ,
delay : ( el , i ) => i * 10 + 800
});
Revert Changes
Restore original HTML:
// Clean up and restore original text
splitter . revert ();
Calling revert() removes all split elements and restores the original HTML. Any running animations on split elements will be cancelled.
Stagger Patterns
import { stagger , animate , text } from 'animejs' ;
const splitter = new text . TextSplitter ( '.text' , {
chars: true
});
// Stagger from center
animate ( splitter . chars , {
scale: [ 0 , 1 ],
opacity: [ 0 , 1 ],
duration: 600 ,
delay: stagger ( 50 , { from: 'center' })
});
// Stagger in a grid pattern
animate ( splitter . chars , {
translateY: [ 40 , 0 ],
opacity: [ 0 , 1 ],
duration: 800 ,
delay: stagger ( 30 , { grid: [ 10 , 5 ], from: 'last' })
});
Helper Function
Convenience function for creating text splitters:
import { splitText } from 'animejs' ;
const splitter = splitText ( '.text' , {
words: true ,
chars: true
});
Only split by what you need. Splitting by all three (lines, words, chars) creates many DOM elements: // Only split by chars if that's all you need
const splitter = new text . TextSplitter ( '.text' , {
chars: true
});
The built-in resize observer already debounces with a 150ms delay, but you can disable automatic refreshing: const splitter = new text . TextSplitter ( '.text' , { chars: true });
// Manual control over when to refresh
Call revert() when animations are complete to reduce DOM size: splitter . addEffect (( split ) => {
return animate ( split . chars , {
opacity: [ 0 , 1 ],
duration: 1000 ,
onComplete : () => splitter . revert ()
});
});