Scribe Effect
Text rendering with configurable granularity (characters, words, or sentences) text animation with action queues and entrance effects.
Domma.effects.scribe()
Creates a character-by-character typing effect with support for action queues, character entrance effects, and text deletion. Perfect for hero sections, terminal interfaces, and storytelling.
// Basic usage
Domma.effects.scribe('.hero-title', {
actions: [
{ render: 'Hello, World!' }
]
});
// Complex sequence with effects
const tw = Domma.effects.scribe('.element', {
speed: 50, // ms per character (typing)
deleteSpeed: 30, // ms per character (deletion)
cursor: true, // show blinking cursor
cursorChar: '|', // cursor character
loop: true, // loop infinitely
actions: [
{ render: 'Hello', effect: 'bounce' },
{ wait: '2s' },
{ undoRender: true }, // delete all from last render
{ render: 'Welcome to Domma', effect: 'fade' },
{ wait: '3s' },
{ undoRender: 5 }, // delete last 5 characters
{ render: 'ma!', effect: 'glow' }
]
});
// Control methods
tw.pause();
tw.resume();
tw.stop();
tw.restart();
tw.destroy();
Action Types
{ render: 'text', effect: 'none|fade|bounce|glow' }- Type text with optional entrance effect{ wait: '2s' }- Pause for duration (supports '2s', '500ms', or number){ undoRender: true }- Delete all characters from last render{ undoRender: N }- Delete last N characters{ undoRender: 'all' }- Delete all characters
Demo: Basic Scribe
Simple typing animation with control methods.
<div class="demo-box" id="scribe-demo-1" style="font-size: 1.5rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary" id="scribe-start-1">Start</button>
<button type="button" class="btn btn-secondary" id="scribe-pause-1">Pause</button>
<button type="button" class="btn btn-secondary" id="scribe-resume-1">Resume</button>
<button type="button" class="btn btn-danger" id="scribe-stop-1">Stop</button>/**
* Demo: Basic Scribe - from public/showcase/effects/scribe.
*/
export function mount(root) {
// Store control objects
let scribe1, scribe2, scribe3, scribe4, scribe5, scribe6;
// scribe() Demo 1 - Basic
$(root).find('#scribe-start-1').on('click', () => {
if (scribe1) scribe1.destroy();
$(root).find('#scribe-demo-1').html('');
scribe1 = Domma.effects.scribe('#scribe-demo-1', {
speed: 50,
deleteSpeed: 30,
respectMotionPreference: false,
actions: [
{ render: 'Hello, World!' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' },
{ render: 'Welcome to DommaJS', effect: 'fade' }
]
});
});
$(root).find('#scribe-pause-1').on('click', () => {
if (scribe1) scribe1.pause();
});
$(root).find('#scribe-resume-1').on('click', () => {
if (scribe1) scribe1.resume();
});
$(root).find('#scribe-stop-1').on('click', () => {
if (scribe1) {
scribe1.stop();
scribe1 = null;
}
});
}Domma.effects.scribe('#scribe-demo-1', {
speed: 50,
deleteSpeed: 30,
actions: [
{ render: 'Hello, World!' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' },
{ render: 'Welcome to DommaJS', effect: 'fade' }
]
});
Demo: Character Effects
Compare different character entrance effects.
<div class="demo-box" id="scribe-demo-2" style="font-size: 1.5rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary" id="scribe-effect-none">None</button>
<button type="button" class="btn btn-primary" id="scribe-effect-fade">Fade</button>
<button type="button" class="btn btn-primary" id="scribe-effect-bounce">Bounce</button>
<button type="button" class="btn btn-primary" id="scribe-effect-glow">Glow</button>/**
* Demo: Character Effects - from public/showcase/effects/scribe.
*/
export function mount(root) {
// Store control objects
let scribe1, scribe2, scribe3, scribe4, scribe5, scribe6;
// scribe() Demo 2 - Character Effects
function startScribeEffect(effect) {
if (scribe2) scribe2.destroy();
$(root).find('#scribe-demo-2').html('');
scribe2 = Domma.effects.scribe('#scribe-demo-2', {
speed: 40,
respectMotionPreference: false,
actions: [
{ render: `Effect: ${effect}`, effect: effect }
]
});
}
$(root).find('#scribe-effect-none').on('click', () => startScribeEffect('none'));
$(root).find('#scribe-effect-fade').on('click', () => startScribeEffect('fade'));
$(root).find('#scribe-effect-bounce').on('click', () => startScribeEffect('bounce'));
$(root).find('#scribe-effect-glow').on('click', () => startScribeEffect('glow'));
}// Demonstrate each effect type
Domma.effects.scribe('#demo', {
speed: 40,
actions: [
{ render: `Effect: ${effect}`, effect: effect }
]
});
Demo: Action Sequence
Complex sequence with render, wait, and undo actions.
<div class="demo-box" id="scribe-demo-3" style="font-size: 1.5rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary" id="scribe-start-3">Start Sequence</button>/**
* Demo: Action Sequence - from public/showcase/effects/scribe.
*/
export function mount(root) {
// Store control objects
let scribe1, scribe2, scribe3, scribe4, scribe5, scribe6;
// scribe() Demo 3 - Action Sequence
$(root).find('#scribe-start-3').on('click', () => {
if (scribe3) scribe3.destroy();
$(root).find('#scribe-demo-3').html('');
scribe3 = Domma.effects.scribe('#scribe-demo-3', {
speed: 50,
deleteSpeed: 30,
respectMotionPreference: false,
actions: [
{ render: 'Hello', effect: 'bounce' },
{ wait: '1.5s' },
{ undoRender: true },
{ render: 'Welcome to Domma', effect: 'fade' },
{ wait: '2s' }
]
});
});
}Domma.effects.scribe('#scribe-demo-3', {
speed: 50,
deleteSpeed: 30,
actions: [
{ render: 'Hello', effect: 'bounce' },
{ wait: '1.5s' },
{ undoRender: true },
{ render: 'Welcome to Domma', effect: 'fade' },
{ wait: '2s' }
]
});
Demo: Rendering Modes
Control rendering granularity with mode: character-by-character, word-by-word, or sentence-by-sentence.
Character Mode (default)
<div class="demo-box" id="scribe-mode-char" style="font-size: 1.3rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary btn-sm mb-3" id="scribe-start-mode-char">Start Character Mode</button>/**
* Character Mode (default) - from public/showcase/effects/scribe.
*/
export function mount(root) {
let scribeModeChar, scribeModeWord, scribeModeSentence;
// Mode Demos - Character Mode
$(root).find('#scribe-start-mode-char').on('click', () => {
if (scribeModeChar) scribeModeChar.destroy();
$(root).find('#scribe-mode-char').html('');
scribeModeChar = Domma.effects.scribe('#scribe-mode-char', {
mode: 'typewriter',
speed: 50,
respectMotionPreference: false,
actions: [{ render: 'Hello World!', effect: 'fade' }]
});
});
}Domma.effects.scribe('#demo', {
mode: 'typewriter', // Character-by-character
actions: [{ render: 'Hello World!' }]
});
Word Mode
<div class="demo-box" id="scribe-mode-word" style="font-size: 1.3rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary btn-sm mb-3" id="scribe-start-mode-word">Start Word Mode</button>/**
* Word Mode - from public/showcase/effects/scribe.
*/
export function mount(root) {
let scribeModeChar, scribeModeWord, scribeModeSentence;
// Mode Demos - Word Mode
$(root).find('#scribe-start-mode-word').on('click', () => {
if (scribeModeWord) scribeModeWord.destroy();
$(root).find('#scribe-mode-word').html('');
scribeModeWord = Domma.effects.scribe('#scribe-mode-word', {
mode: 'word',
speed: 100,
respectMotionPreference: false,
actions: [{ render: 'Welcome to the Domma framework!', effect: 'bounce' }]
});
});
}Domma.effects.scribe('#demo', {
mode: 'word', // Word-by-word
speed: 100, // Per word, not per character
actions: [{ render: 'Welcome to the Domma framework!', effect: 'bounce' }]
});
Sentence Mode
<div class="demo-box" id="scribe-mode-sentence" style="font-size: 1.3rem; min-height: 4rem;"></div>
<button type="button" class="btn btn-primary btn-sm mb-3" id="scribe-start-mode-sentence">Start Sentence Mode</button>/**
* Sentence Mode - from public/showcase/effects/scribe.
*/
export function mount(root) {
let scribeModeChar, scribeModeWord, scribeModeSentence;
// Mode Demos - Sentence Mode
$(root).find('#scribe-start-mode-sentence').on('click', () => {
if (scribeModeSentence) scribeModeSentence.destroy();
$(root).find('#scribe-mode-sentence').html('');
scribeModeSentence = Domma.effects.scribe('#scribe-mode-sentence', {
mode: 'sentence',
speed: 200,
respectMotionPreference: false,
actions: [{ render: 'First sentence. Second sentence! Third sentence?', effect: 'fade' }]
});
});
}Domma.effects.scribe('#demo', {
mode: 'sentence', // Sentence-by-sentence
speed: 200, // Per sentence
actions: [{ render: 'First sentence. Second sentence! Third sentence?', effect: 'fade' }]
});
Demo: Partial Undo
Demonstrate selective unit deletion. In word mode, undoRender deletes words. In sentence mode, it deletes sentences.
<div class="demo-box" id="scribe-demo-4" style="font-size: 1.5rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary" id="scribe-start-4">Start Partial Undo</button>/**
* Demo: Partial Undo - from public/showcase/effects/scribe.
*/
export function mount(root) {
// Store control objects
let scribe1, scribe2, scribe3, scribe4, scribe5, scribe6;
// scribe() Demo 4 - Partial Undo
$(root).find('#scribe-start-4').on('click', () => {
if (scribe4) scribe4.destroy();
$(root).find('#scribe-demo-4').html('');
scribe4 = Domma.effects.scribe('#scribe-demo-4', {
speed: 50,
deleteSpeed: 30,
respectMotionPreference: false,
actions: [
{ render: 'Domma Framework', effect: 'fade' },
{ wait: '1s' },
{ undoRender: 9 }, // Delete "Framework"
{ wait: '500ms' },
{ render: 'Effects!', effect: 'glow' },
{ wait: '2s' }
]
});
});
}Domma.effects.scribe('#scribe-demo-4', {
speed: 50,
deleteSpeed: 30,
actions: [
{ render: 'Domma Framework', effect: 'fade' },
{ wait: '1s' },
{ undoRender: 9 }, // Delete "Framework"
{ wait: '500ms' },
{ render: 'Effects!', effect: 'glow' },
{ wait: '2s' }
]
});
Demo: Hero Banner Loop
Infinite looping scribe for hero sections.
<div class="demo-box" id="scribe-demo-5" style="font-size: 2rem; font-weight: bold; min-height: 4rem; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white;"></div>
<button type="button" class="btn btn-light" id="scribe-start-5">Start Loop</button>
<button type="button" class="btn btn-light" id="scribe-stop-5">Stop Loop</button>/**
* Demo: Hero Banner Loop - from public/showcase/effects/scribe.
*/
export function mount(root) {
// Store control objects
let scribe1, scribe2, scribe3, scribe4, scribe5, scribe6;
// scribe() Demo 5 - Hero Banner Loop
$(root).find('#scribe-start-5').on('click', () => {
if (scribe5) scribe5.destroy();
$(root).find('#scribe-demo-5').html('');
scribe5 = Domma.effects.scribe('#scribe-demo-5', {
speed: 60,
deleteSpeed: 40,
loop: true,
loopDelay: 2000,
respectMotionPreference: false,
actions: [
{ render: 'Build Faster', effect: 'bounce' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' },
{ render: 'Code Smarter', effect: 'fade' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' },
{ render: 'Ship Better', effect: 'glow' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' }
]
});
});
$(root).find('#scribe-stop-5').on('click', () => {
if (scribe5) {
scribe5.stop();
scribe5 = null;
}
});
}Domma.effects.scribe('#scribe-demo-5', {
speed: 60,
deleteSpeed: 40,
loop: true,
loopDelay: 2000,
actions: [
{ render: 'Build Faster', effect: 'bounce' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' },
{ render: 'Code Smarter', effect: 'fade' },
{ wait: '2s' },
{ undoRender: 'all' },
{ wait: '500ms' }
]
});
Demo: Cursor Types
Different cursor styles with smooth fade animation.
<div class="demo-box" id="scribe-demo-6" style="font-size: 1.5rem; min-height: 3rem;"></div>
<button type="button" class="btn btn-primary" id="scribe-cursor-caret">Caret |</button>
<button type="button" class="btn btn-primary" id="scribe-cursor-block">Block █</button>
<button type="button" class="btn btn-primary" id="scribe-cursor-underline">Underline _</button>
<button type="button" class="btn btn-secondary" id="scribe-cursor-noblink">No Blink</button>/**
* Demo: Cursor Types - from public/showcase/effects/scribe.
*/
export function mount(root) {
// Store control objects
let scribe1, scribe2, scribe3, scribe4, scribe5, scribe6;
// scribe() Demo 6 - Cursor Types
function startCursorDemo(cursorType, cursorChar, cursorBlink = true) {
if (scribe6) scribe6.destroy();
$(root).find('#scribe-demo-6').html('');
scribe6 = Domma.effects.scribe('#scribe-demo-6', {
speed: 50,
cursorType: cursorType,
cursorChar: cursorChar,
cursorBlink: cursorBlink,
respectMotionPreference: false,
actions: [
{ render: 'Cursor type: ' + cursorType }
]
});
}
$(root).find('#scribe-cursor-caret').on('click', () => startCursorDemo('caret', '|'));
$(root).find('#scribe-cursor-block').on('click', () => startCursorDemo('block', '█'));
$(root).find('#scribe-cursor-underline').on('click', () => startCursorDemo('underline', '_'));
$(root).find('#scribe-cursor-noblink').on('click', () => startCursorDemo('caret', '|', false));
}// Different cursor styles
Domma.effects.scribe('#demo', {
speed: 50,
cursorType: 'caret', // or 'block', 'underline'
cursorChar: '|', // or '█', '_'
cursorBlink: true, // or false
actions: [
{ render: 'Cursor type: caret' }
]
});