@twistezo/react-text-scramble
Version:
React text scramble effect
59 lines (58 loc) • 2.5 kB
JavaScript
import React, { useState, useEffect } from 'react';
import { randomItem, nextItem } from './utils';
var symbols = '!<>-_\\/[]{}—=+*^?#'.split('');
var TextScramble = function (_a) {
var texts = _a.texts, className = _a.className, _b = _a.letterSpeed, letterSpeed = _b === void 0 ? 5 : _b, _c = _a.nextLetterSpeed, nextLetterSpeed = _c === void 0 ? 100 : _c, _d = _a.paused, paused = _d === void 0 ? false : _d, _e = _a.pauseTime, pauseTime = _e === void 0 ? 1500 : _e;
var _f = useState(texts[0]), currentText = _f[0], setCurrentText = _f[1];
var initSymbols = Array(currentText.length)
.fill(0)
.map(function () { return randomItem(symbols); });
var _g = useState(initSymbols), displayedText = _g[0], setDisplayedText = _g[1];
var leftIndexes = [];
var defaultLeftIndexes = function () {
currentText.split('').forEach(function (_, i) {
leftIndexes.push(i);
});
};
var bakeLetterInterval = 0;
var bakeTextInterval = 0;
var bakeLetter = function () {
bakeLetterInterval = setInterval(function () {
if (!paused) {
var updatedText_1 = [];
currentText.split('').forEach(function (_, i) {
if (!leftIndexes.includes(i)) {
updatedText_1[i] = currentText[i];
return;
}
var randomSymbol = randomItem(symbols);
updatedText_1[i] = randomSymbol;
});
setDisplayedText(updatedText_1);
}
}, letterSpeed);
};
var bakeText = function () {
defaultLeftIndexes();
bakeLetter();
bakeTextInterval = setInterval(function () {
if (!paused) {
if (leftIndexes.length === 0) {
clearInterval(bakeLetterInterval);
clearInterval(bakeTextInterval);
setTimeout(function () {
setCurrentText(nextItem(texts, currentText));
defaultLeftIndexes();
}, pauseTime);
}
leftIndexes.shift();
}
}, nextLetterSpeed);
};
useEffect(function () {
if (!paused)
bakeText();
}, [currentText, paused]); // eslint-disable-line react-hooks/exhaustive-deps
return React.createElement("div", { className: className }, displayedText);
};
export default TextScramble;