UNPKG

@twistezo/react-text-scramble

Version:
176 lines (172 loc) 5.08 kB
var __defProp = Object.defineProperty; var __getOwnPropNames = Object.getOwnPropertyNames; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __hasOwnProp = Object.prototype.hasOwnProperty; var __moduleCache = /* @__PURE__ */ new WeakMap; var __toCommonJS = (from) => { var entry = __moduleCache.get(from), desc; if (entry) return entry; entry = __defProp({}, "__esModule", { value: true }); if (from && typeof from === "object" || typeof from === "function") __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable })); __moduleCache.set(from, entry); return entry; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true, configurable: true, set: (newValue) => all[name] = () => newValue }); }; // src/vanilla.ts var exports_vanilla = {}; __export(exports_vanilla, { createTextScramble: () => createTextScramble, TextScrambleAnimator: () => TextScrambleAnimator, SYMBOLS: () => SYMBOLS, DEFAULT_PAUSE_TIME: () => DEFAULT_PAUSE_TIME, DEFAULT_PAUSED: () => DEFAULT_PAUSED, DEFAULT_NEXT_LETTER_SPEED: () => DEFAULT_NEXT_LETTER_SPEED, DEFAULT_LETTER_SPEED: () => DEFAULT_LETTER_SPEED }); module.exports = __toCommonJS(exports_vanilla); // src/constants.ts var DEFAULT_LETTER_SPEED = 5; var DEFAULT_NEXT_LETTER_SPEED = 100; var DEFAULT_PAUSE_TIME = 1500; var DEFAULT_PAUSED = false; var SYMBOLS = "!<>-_\\/[]{}—=+*^?#".split(""); // src/utils.ts var randomItem = (array) => array[Math.floor(Math.random() * array.length)]; var nextItem = (array, currentItem) => { const currentIndex = array.indexOf(currentItem); const bound = array.length; const nextIndex = (currentIndex + bound + 1) % bound; return array[nextIndex]; }; // src/TextScrambleAnimator.ts class TextScrambleAnimator { bakeLetterInterval = null; bakeTextInterval = null; currentText; displayedText; element; leftIndexes = []; letterSpeed; nextLetterSpeed; paused; pauseTime; pauseTimeout = null; texts; constructor(element, options) { this.element = element; this.texts = options.texts; this.letterSpeed = options.letterSpeed ?? DEFAULT_LETTER_SPEED; this.nextLetterSpeed = options.nextLetterSpeed ?? DEFAULT_NEXT_LETTER_SPEED; this.pauseTime = options.pauseTime ?? DEFAULT_PAUSE_TIME; this.paused = options.paused ?? DEFAULT_PAUSED; this.currentText = this.texts[0]; this.displayedText = this.initSymbols(); this.render(); if (!this.paused) { this.animate(); } } destroy() { this.clearAllIntervals(); } pause() { this.paused = true; if (this.pauseTimeout) { clearTimeout(this.pauseTimeout); this.pauseTimeout = null; } } play() { this.paused = false; this.clearAllIntervals(); this.animate(); } reset() { this.clearAllIntervals(); this.currentText = this.texts[0]; this.displayedText = this.initSymbols(); this.render(); this.leftIndexes = []; if (!this.paused) { this.animate(); } } setTexts(texts) { this.texts = texts; this.reset(); } animate() { this.bakeText(); } bakeLetter() { this.bakeLetterInterval = setInterval(() => { if (!this.paused) { const updatedText = []; this.currentText.split("").forEach((char, i) => { if (!this.leftIndexes.includes(i)) { updatedText[i] = this.currentText[i]; return; } updatedText[i] = randomItem(SYMBOLS); }); this.displayedText = updatedText; this.render(); } }, this.letterSpeed); } bakeText() { this.leftIndexes = this.currentText.split("").map((_, i) => i); this.bakeLetter(); this.bakeTextInterval = setInterval(() => { if (!this.paused) { if (this.leftIndexes.length === 0) { this.clearAllIntervals(); this.pauseTimeout = setTimeout(() => { this.currentText = nextItem(this.texts, this.currentText); this.displayedText = this.initSymbols(); this.render(); this.animate(); }, this.pauseTime); return; } this.leftIndexes.shift(); } }, this.nextLetterSpeed); } clearAllIntervals() { if (this.bakeLetterInterval) { clearInterval(this.bakeLetterInterval); this.bakeLetterInterval = null; } if (this.bakeTextInterval) { clearInterval(this.bakeTextInterval); this.bakeTextInterval = null; } if (this.pauseTimeout) { clearTimeout(this.pauseTimeout); this.pauseTimeout = null; } } initSymbols() { return Array(this.currentText.length).fill(0).map(() => randomItem(SYMBOLS)); } render() { this.element.textContent = this.displayedText.join(""); } } function createTextScramble(element, options) { return new TextScrambleAnimator(element, options); }