TextEffects
Advanced scroll-driven text effects including warp, morph, scramble, glitch, 3D flip, and rainbow animations
TextEffects provides ready-to-use advanced typography effects optimized for scroll-driven animations. All effects work with split text elements (from TextSplitter) and progress values (0-1).
Basic Usage
import { TextSplitter, TextEffects } from 'faster-motion';
// 1. Split text into characters
// IMPORTANT: Use className: 'ft' so TextEffects can find .ft-char elements
const result = TextSplitter.split('#title', {
type: 'chars',
className: 'ft' // Required for TextEffects
});
// 2. Apply effect with scroll progress (0-1)
window.addEventListener('scroll', () => {
const progress = Math.min(1, window.scrollY / 500);
TextEffects.warp(result.parent, progress, {
type: 'sine',
amplitude: 20
});
});Important: When using TextEffects with TextSplitter, you must pass className: 'ft' to TextSplitter. This creates elements with .ft-char class that TextEffects methods look for.
Try it: Warp Effect
const result = TextSplitter.split('#title', { type: 'chars', className: 'ft' });
TextEffects.warp(result.parent, progress, { type: 'sine', amplitude: 20 });TextEffects.warp()
Warp text along a curve based on progress value.
Syntax
TextEffects.warp(
element: HTMLElement,
progress: number,
options?: {
amplitude?: number;
frequency?: number;
type?: 'sine' | 'wave' | 'arc' | 'spiral';
}
): voidParameters
element-HTMLElement- Parent element containing.ft-split-charchildrenprogress-number- Animation progress (0-1)options-object(optional) - Configuration optionsamplitude- Wave height in pixels (default: 20)frequency- Number of waves (default: 1)type- Warp type:'sine','wave','arc','spiral'(default:'sine')
Warp Types
| Type | Description |
|---|---|
sine | Smooth sine wave oscillation |
wave | Scrolling wave that moves with progress |
arc | Arc/rainbow curve shape |
spiral | Spiral outward from center |
Example
// Sine wave
TextEffects.warp(element, progress, {
type: 'sine',
amplitude: 20,
frequency: 1
});
// Arc curve
TextEffects.warp(element, progress, {
type: 'arc',
amplitude: 50
});
// Spiral
TextEffects.warp(element, progress, {
type: 'spiral',
amplitude: 30,
frequency: 2
});Try it: All Warp Types
// Try: 'sine', 'wave', 'arc', 'spiral'
TextEffects.warp(element, progress, { type: 'sine', amplitude: 25 });TextEffects.morph()
Morph text from one transform state to another with staggered timing.
Syntax
TextEffects.morph(
element: HTMLElement,
progress: number,
from: TextTransform,
to: TextTransform
): voidParameters
element-HTMLElement- Parent element with.ft-split-charchildrenprogress-number- Animation progress (0-1)from-TextTransform- Starting transform stateto-TextTransform- Ending transform state
Example
TextEffects.morph(element, progress,
// From state
{
x: -100,
y: 50,
scale: 0,
rotation: -90,
opacity: 0,
color: '#ff0000'
},
// To state
{
x: 0,
y: 0,
scale: 1,
rotation: 0,
opacity: 1,
color: '#00ff00'
}
);Try it: Morph Effect
TextEffects.morph(element, progress,
{ y: 50, scale: 0, rotation: -90, opacity: 0 },
{ y: 0, scale: 1, rotation: 0, opacity: 1 }
);TextEffects.typeVariable()
Create a variable-speed typing effect where characters appear at different speeds.
Syntax
TextEffects.typeVariable(
element: HTMLElement,
progress: number,
options?: {
minSpeed?: number;
maxSpeed?: number;
acceleration?: 'linear' | 'ease' | 'bounce';
}
): voidParameters
element-HTMLElement- Parent element with.ft-split-charchildrenprogress-number- Animation progress (0-1)options-object(optional)minSpeed- Minimum speed multiplier (default: 0.5)maxSpeed- Maximum speed multiplier (default: 2)acceleration- Speed curve type (default:'ease')
Acceleration Types
| Type | Description |
|---|---|
linear | Constant speed increase |
ease | Speeds up then slows down |
bounce | Bouncy speed variations |
Example
// Eased typing (speeds up, then slows down)
TextEffects.typeVariable(element, progress, {
minSpeed: 0.3,
maxSpeed: 3,
acceleration: 'ease'
});
// Bouncy typing
TextEffects.typeVariable(element, progress, {
acceleration: 'bounce'
});Try it: TypeVariable Effect
TextEffects.typeVariable(element, progress, {
minSpeed: 0.3,
maxSpeed: 2.5,
acceleration: 'ease'
});TextEffects.scramble()
Scramble text reveal effect - characters show as random symbols before revealing.
Syntax
TextEffects.scramble(
element: HTMLElement,
progress: number,
options?: {
characters?: string;
speed?: number;
}
): voidParameters
element-HTMLElement- Text element (works on unsplit text too)progress-number- Animation progress (0-1)options-object(optional)characters- Characters to use for scrambling (default: alphanumeric + symbols)speed- Scramble speed (default: 10)
Example
// Default scramble
TextEffects.scramble(element, progress);
// Binary scramble (Matrix-style)
TextEffects.scramble(element, progress, {
characters: '01',
speed: 20
});
// Letters only
TextEffects.scramble(element, progress, {
characters: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
});Try it: Scramble Effect
TextEffects.scramble(element, progress, {
characters: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
speed: 15
});TextEffects.glitch()
Create a digital glitch distortion effect with chromatic aberration.
Syntax
TextEffects.glitch(
element: HTMLElement,
progress: number,
intensity?: number
): voidParameters
element-HTMLElement- Text elementprogress-number- Animation progress (0-1, kept for API consistency)intensity-number(optional) - Glitch intensity from 0-1 (default: 1)
Effect Details
The glitch effect applies:
- Random offset and skew transforms
- RGB chromatic aberration (red/cyan text shadows)
- Auto-resets after 50-150ms
Example
// Call repeatedly for glitch effect
setInterval(() => {
TextEffects.glitch(element, 0, 0.8); // 80% intensity
}, 100);
// High intensity
TextEffects.glitch(element, 0, 1);
// Subtle glitch
TextEffects.glitch(element, 0, 0.2);Try it: Glitch Effect
// Glitch with 80% intensity
TextEffects.glitch(element, 0, 0.8);TextEffects.flip3D()
3D flip animation with perspective transforms.
Syntax
TextEffects.flip3D(
element: HTMLElement,
progress: number,
axis?: 'x' | 'y' | 'both'
): voidParameters
element-HTMLElement- Parent element with.ft-split-charchildrenprogress-number- Animation progress (0-1)axis-'x' | 'y' | 'both'(optional) - Flip axis (default:'y')
Axis Options
| Axis | Description |
|---|---|
x | Vertical flip (rotateX) |
y | Horizontal flip (rotateY) |
both | Flip on both axes |
Example
// Horizontal flip (card-flip style)
TextEffects.flip3D(element, progress, 'y');
// Vertical flip
TextEffects.flip3D(element, progress, 'x');
// Both axes
TextEffects.flip3D(element, progress, 'both');Try it: 3D Flip Effect
TextEffects.flip3D(element, progress, 'y');TextEffects.rainbow()
Animated rainbow color effect cycling through the hue spectrum.
Syntax
TextEffects.rainbow(
element: HTMLElement,
progress: number,
speed?: number
): voidParameters
element-HTMLElement- Parent element with.ft-split-charchildrenprogress-number- Animation progress (0-1)speed-number(optional) - Animation speed multiplier (default: 1)
Example
// Standard rainbow
TextEffects.rainbow(element, progress);
// Fast rainbow (2x speed)
TextEffects.rainbow(element, progress, 2);
// Slow rainbow (0.5x speed)
TextEffects.rainbow(element, progress, 0.5);Try it: Rainbow Effect
TextEffects.rainbow(element, progress, 1.5);TextEffects.alongPath()
Move text characters along an SVG path.
Syntax
TextEffects.alongPath(
element: HTMLElement,
progress: number,
pathData: string
): voidParameters
element-HTMLElement- Parent element with.ft-split-charchildrenprogress-number- Animation progress (0-1)pathData-string- SVG path data (d attribute)
Example
// Simple curve
const pathData = 'M0,50 Q100,0 200,50';
TextEffects.alongPath(element, progress, pathData);
// Complex path
const complexPath = 'M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40';
TextEffects.alongPath(element, progress, complexPath);Try it: Path Effect
const pathData = 'M0,100 Q150,0 300,100';
TextEffects.alongPath(element, progress, pathData);TextTransform Interface
All transform properties supported by morph() and internal methods:
interface TextTransform {
// Position & Scale
x?: number;
y?: number;
z?: number;
scale?: number;
scaleX?: number;
scaleY?: number;
// Rotation (degrees)
rotation?: number;
rotationX?: number;
rotationY?: number;
rotationZ?: number;
// Skew (degrees)
skewX?: number;
skewY?: number;
// Typography
letterSpacing?: number;
wordSpacing?: number;
lineHeight?: number;
fontSize?: number;
fontWeight?: number;
// Colors
color?: string;
backgroundColor?: string;
borderColor?: string;
// Effects
opacity?: number;
blur?: number;
brightness?: number;
contrast?: number;
grayscale?: number;
hueRotate?: number;
saturate?: number;
sepia?: number;
// Text effects
strokeWidth?: number;
strokeColor?: string;
shadowX?: number;
shadowY?: number;
shadowBlur?: number;
shadowColor?: string;
// Perspective
perspective?: number;
perspectiveOrigin?: string;
transformOrigin?: string;
}Scroll Integration
TextEffects are designed to work with scroll progress. Here's how to integrate with scroll:
Using Window Scroll
const result = TextSplitter.split('#title', { type: 'chars' });
window.addEventListener('scroll', () => {
const progress = Math.min(1, window.scrollY / 500);
TextEffects.warp(result.parent, progress, { type: 'wave' });
});Using requestAnimationFrame
const result = TextSplitter.split('#title', { type: 'chars' });
function animate() {
const progress = Math.min(1, window.scrollY / 500);
TextEffects.rainbow(result.parent, progress, 1.5);
requestAnimationFrame(animate);
}
animate();Combining Effects
const result = TextSplitter.split('#title', { type: 'chars' });
window.addEventListener('scroll', () => {
const progress = Math.min(1, window.scrollY / 500);
// Apply multiple effects
TextEffects.morph(result.parent, progress,
{ scale: 0, rotation: -90 },
{ scale: 1, rotation: 0 }
);
TextEffects.rainbow(result.parent, progress, 0.5);
});Performance Tips
Use RAF for Smooth Updates
window.addEventListener('scroll', () => {
requestAnimationFrame(() => {
TextEffects.warp(element, progress, { type: 'sine' });
});
});Cache Path Data
// Good: Define path outside handler
const pathData = 'M10,80 Q95,10 180,80';
window.addEventListener('scroll', () => {
TextEffects.alongPath(element, progress, pathData);
});
// Bad: Don't recreate path each frame
window.addEventListener('scroll', () => {
const pathData = generatePath(); // Expensive!
TextEffects.alongPath(element, progress, pathData);
});Limit Effect Combinations
// Good: 1-2 effects
TextEffects.morph(element, progress, from, to);
TextEffects.rainbow(element, progress);
// Bad: Too many effects
TextEffects.warp(element, progress);
TextEffects.morph(element, progress, from, to);
TextEffects.flip3D(element, progress);
TextEffects.rainbow(element, progress); // Overkill!Examples
- Warp Effects - Sine, wave, arc, spiral warping
- Morph Transform - Transform state morphing
- TypeVariable - Variable-speed typing effect
- Scramble Reveal - Text scramble effect
- Glitch Effect - Digital glitch distortion
- 3D Flip - Perspective flip animation
- Rainbow Colors - Animated rainbow hues
- Text Along Path - Text following SVG path
See Also
- TextSplitter - Split DOM text for animation
- Text Animation - Canvas-based text animation
- Timeline - Sequencing animations