or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

animatable.mdanimation.mddraggable.mdeasings.mdengine.mdindex.mdscope.mdscroll.mdsvg.mdtext.mdtimeline.mdtimer.mdutilities.mdwaapi.md
tile.json

text.mddocs/

Text

Text splitting and animation system for creating character, word, and line-based text animations with accessibility support.

Capabilities

splitText Function

Split text into animatable lines, words, and characters with customizable templates and accessibility features.

/**
 * Split text into animatable segments (lines, words, characters)
 * @param target - Element(s) containing text to split
 * @param parameters - Text splitting configuration
 * @returns TextSplitter instance
 */
function splitText(
  target: HTMLElement | NodeList | string | Array<HTMLElement>,
  parameters?: TextSplitterParams
): TextSplitter;

/** Alias for splitText */
function split(
  target: HTMLElement | NodeList | string | Array<HTMLElement>,
  parameters?: TextSplitterParams
): TextSplitter;

Usage Example:

import { splitText, animate } from "animejs";

// Split text into words and characters
const splitter = splitText(".heading", {
  type: "words, chars",
});

// Animate characters with stagger
animate(splitter.chars, {
  opacity: [0, 1],
  translateY: [20, 0],
  stagger: 20,
});

TextSplitter Class

Split text into animated segments with full control over output structure and behavior.

/**
 * TextSplitter class for text animation preparation
 */
class TextSplitter {
  // ===== Properties =====

  /** Target element containing the text */
  $target: HTMLElement;

  /** Original HTML before splitting */
  html: string;

  /** Array of split line elements */
  lines: Array<HTMLElement>;

  /** Array of split word elements */
  words: Array<HTMLElement>;

  /** Array of split character elements */
  chars: Array<HTMLElement>;

  /** Whether splitter is ready (split completed) */
  ready: boolean;

  // ===== Configuration Properties =====

  /**
   * Include space characters as separate elements
   * When true, spaces become animatable elements
   */
  includeSpaces: boolean;

  /**
   * Maintain accessibility for screen readers
   * Preserves original text structure for assistive technologies
   */
  accessible: boolean;

  /**
   * Only split into lines, skip words and characters
   * Performance optimization when only line splitting needed
   */
  linesOnly: boolean;

  /**
   * Template for line wrapper elements
   * String: HTML template with {{line}} placeholder
   * Function: Receives line element, returns wrapper element
   * false: No line wrapper
   */
  lineTemplate: string | false | SplitFunctionValue;

  /**
   * Template for word wrapper elements
   * String: HTML template with {{word}} placeholder
   * Function: Receives word element, returns wrapper element
   * false: No word wrapper
   */
  wordTemplate: string | false | SplitFunctionValue;

  /**
   * Template for character wrapper elements
   * String: HTML template with {{char}} placeholder
   * Function: Receives char element, returns wrapper element
   * false: No character wrapper
   */
  charTemplate: string | false | SplitFunctionValue;

  /**
   * Enable debug mode
   * Shows visual boundaries of split elements
   */
  debug: boolean;

  // ===== Methods =====

  /**
   * Perform text split operation
   * @param clearCache - Clear internal cache before splitting
   * @returns TextSplitter instance for chaining
   */
  split(clearCache?: boolean): TextSplitter;

  /**
   * Add animation effect to split text
   * @param effect - Effect configuration
   * @returns TextSplitter instance for chaining
   */
  addEffect(effect: TextEffectParams): TextSplitter;

  /**
   * Refresh split after content or layout changes
   * @returns TextSplitter instance for chaining
   */
  refresh(): TextSplitter;

  /**
   * Revert to original text and cleanup
   * @returns TextSplitter instance for chaining
   */
  revert(): TextSplitter;
}

Usage Examples:

import { splitText, animate, stagger } from "animejs";

// Basic character split
const chars = splitText(".title", {
  type: "chars",
});

animate(chars.chars, {
  opacity: [0, 1],
  stagger: 50,
});

// Word and character split
const text = splitText(".paragraph", {
  type: "words, chars",
});

animate(text.words, {
  opacity: [0, 1],
  translateY: [20, 0],
  stagger: 30,
});

// Line split only
const lines = splitText(".content", {
  type: "lines",
  linesOnly: true, // Performance optimization
});

animate(lines.lines, {
  translateX: [-100, 0],
  opacity: [0, 1],
  stagger: 100,
});

Split Types

Configure which text segments to create:

// Split into characters only
splitText(".text", {
  type: "chars",
});

// Split into words only
splitText(".text", {
  type: "words",
});

// Split into lines only
splitText(".text", {
  type: "lines",
});

// Combine multiple types
splitText(".text", {
  type: "lines, words, chars",
});

// Alternative syntax
splitText(".text", {
  type: ["lines", "words", "chars"],
});

Custom Templates

Customize wrapper elements with templates:

// String templates with placeholders
splitText(".text", {
  type: "chars",
  charTemplate: '<span class="char">{{char}}</span>',
});

splitText(".text", {
  type: "words, chars",
  wordTemplate: '<span class="word" data-word="{{word}}">{{word}}</span>',
  charTemplate: '<span class="char" data-char="{{char}}">{{char}}</span>',
});

// Function templates for dynamic control
splitText(".text", {
  type: "chars",
  charTemplate: (char, index) => {
    const span = document.createElement("span");
    span.className = "char";
    span.textContent = char.textContent;
    span.style.setProperty("--index", index);
    return span;
  },
});

// Disable wrappers
splitText(".text", {
  type: "words",
  wordTemplate: false, // No wrapper for words
});

Include Spaces

Make spaces animatable:

const text = splitText(".heading", {
  type: "chars",
  includeSpaces: true, // Spaces become separate elements
});

// Now spaces can be animated independently
animate(text.chars, {
  opacity: [0, 1],
  stagger: 20,
  delay: (el, i) => {
    return el.textContent === " " ? i * 30 : i * 20;
  },
});

Accessibility Support

Maintain screen reader compatibility:

splitText(".content", {
  type: "words, chars",
  accessible: true, // Preserves text for screen readers
});

// Accessible mode adds aria attributes and preserves
// original text structure for assistive technologies

Lines Only Optimization

Performance optimization for line splitting:

// When you only need lines, skip word/char processing
const lines = splitText(".article", {
  type: "lines",
  linesOnly: true, // Faster splitting
});

animate(lines.lines, {
  opacity: [0, 1],
  stagger: 200,
});

Animation Effects

Add pre-configured effects to split text:

/**
 * Add animation effect to split text
 */
interface TextEffectParams {
  /** Effect name or custom animation */
  name?: string;

  /** Target segment: 'lines', 'words', 'chars' */
  target?: "lines" | "words" | "chars";

  /** Animation parameters */
  [key: string]: any;
}

Usage Example:

const text = splitText(".heading", {
  type: "words, chars",
});

// Add effect
text.addEffect({
  target: "chars",
  opacity: [0, 1],
  translateY: [50, 0],
  stagger: 20,
  ease: "outQuad",
});

Accessing Split Elements

Access split segments for animation:

const text = splitText(".content", {
  type: "lines, words, chars",
});

// Access split elements
console.log(text.lines); // Array of line elements
console.log(text.words); // Array of word elements
console.log(text.chars); // Array of character elements

// Animate different segments
animate(text.lines, {
  opacity: [0, 1],
  stagger: 200,
});

animate(text.chars, {
  scale: [0, 1],
  stagger: 10,
  delay: 500,
});

Refresh After Changes

Update split after content changes:

const text = splitText(".dynamic-text");

// Update text content
document.querySelector(".dynamic-text").textContent = "New text";

// Refresh split
text.refresh();

Revert to Original

Restore original text structure:

const text = splitText(".text", {
  type: "chars",
});

// Animate...

// Restore original
text.revert();

Debug Mode

Visual debugging of split elements:

splitText(".text", {
  type: "words, chars",
  debug: true, // Shows element boundaries
});

Common Animation Patterns

Fade In Stagger

const text = splitText(".title", { type: "chars" });

animate(text.chars, {
  opacity: [0, 1],
  translateY: [20, 0],
  stagger: 30,
  ease: "outQuad",
});

Wave Effect

const text = splitText(".heading", { type: "chars" });

animate(text.chars, {
  translateY: [0, -20, 0],
  duration: 600,
  stagger: {
    value: 50,
    from: "center",
  },
  loop: true,
});

Reveal from Left

const text = splitText(".text", { type: "words" });

animate(text.words, {
  opacity: [0, 1],
  translateX: [-50, 0],
  stagger: 50,
  ease: "outCubic",
});

Rotate In

const text = splitText(".title", {
  type: "chars",
  charTemplate: '<span class="char-wrap">{{char}}</span>',
});

animate(text.chars, {
  opacity: [0, 1],
  rotate: [-90, 0],
  stagger: 40,
  ease: "outBack",
});

Random Shuffle

import { splitText, animate, random } from "animejs";

const text = splitText(".text", { type: "chars" });

animate(text.chars, {
  opacity: [0, 1],
  translateX: () => random(-50, 50),
  translateY: () => random(-50, 50),
  rotate: () => random(-180, 180),
  stagger: 20,
  ease: "outQuad",
});

Line by Line Reveal

const text = splitText(".article", {
  type: "lines",
  linesOnly: true,
});

animate(text.lines, {
  opacity: [0, 1],
  translateY: [30, 0],
  stagger: 150,
  ease: "outCubic",
});

Scramble Effect

const text = splitText(".code", {
  type: "chars",
  includeSpaces: true,
});

const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
const originals = text.chars.map((el) => el.textContent);

animate(text.chars, {
  duration: 2000,
  stagger: 50,
  update: (anim) => {
    text.chars.forEach((el, i) => {
      if (anim.progress < 0.7) {
        el.textContent = chars[Math.floor(Math.random() * chars.length)];
      } else {
        el.textContent = originals[i];
      }
    });
  },
});

Split by Word, Animate Chars

const text = splitText(".heading", {
  type: "words, chars",
});

// Animate each word's characters sequentially
text.words.forEach((word, wordIndex) => {
  const wordChars = word.querySelectorAll(".char");

  animate(wordChars, {
    opacity: [0, 1],
    scale: [0, 1],
    stagger: 20,
    delay: wordIndex * 200, // Delay between words
  });
});

Responsive Text Splitting

Handle responsive layouts:

const text = splitText(".responsive-text", {
  type: "lines, words",
});

// Refresh on resize to recalculate lines
let resizeTimer;
window.addEventListener("resize", () => {
  clearTimeout(resizeTimer);
  resizeTimer = setTimeout(() => {
    text.refresh();
  }, 200);
});

Multiple Text Elements

Split multiple elements at once:

// Split all headings
const headings = splitText(".heading", {
  type: "words",
});

// Animate each separately
document.querySelectorAll(".heading").forEach((heading, i) => {
  const words = heading.querySelectorAll(".word");

  animate(words, {
    opacity: [0, 1],
    translateY: [20, 0],
    stagger: 30,
    delay: i * 500,
  });
});

Types

/**
 * Text splitter configuration parameters
 */
interface TextSplitterParams {
  /** Split type: 'lines', 'words', 'chars' or combinations */
  type?: string | Array<"lines" | "words" | "chars">;

  /** Include space characters as elements */
  includeSpaces?: boolean;

  /** Maintain accessibility for screen readers */
  accessible?: boolean;

  /** Only split lines (performance optimization) */
  linesOnly?: boolean;

  /** Line wrapper template */
  lineTemplate?: string | false | SplitFunctionValue;

  /** Word wrapper template */
  wordTemplate?: string | false | SplitFunctionValue;

  /** Character wrapper template */
  charTemplate?: string | false | SplitFunctionValue;

  /** Enable debug mode */
  debug?: boolean;
}

/**
 * Split template function type
 */
type SplitFunctionValue = (
  element: HTMLElement,
  index: number,
  total: number
) => HTMLElement;

/**
 * Text effect parameters
 */
interface TextEffectParams {
  /** Target segment type */
  target?: "lines" | "words" | "chars";

  /** Effect name */
  name?: string;

  /** Animation parameters */
  [key: string]: any;
}