@arwes/text
Version:
Futuristic Sci-Fi UI Web Framework
67 lines (66 loc) • 2.77 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.animateTextDecipher = void 0;
const tools_1 = require("@arwes/tools");
const animated_1 = require("@arwes/animated");
const index_js_1 = require("../internal/walkTextNodes/index.js");
const index_js_2 = require("../internal/setTextNodesContent/index.js");
const CIPHERED_CHARACTERS = ' ----____abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
const animateTextDecipher = (props) => {
const { rootElement, contentElement, duration, easing = 'linear', isEntering = true, hideOnExited = true, hideOnEntered, characters = CIPHERED_CHARACTERS } = (0, tools_1.filterProps)(props);
if (!rootElement || !contentElement) {
throw new Error('ARWES animateTextDecipher() requires valid DOM elements.');
}
const cloneElement = contentElement.cloneNode(true);
Object.assign(cloneElement.style, {
position: 'absolute',
inset: 0,
visibility: 'visible',
opacity: 1
});
const textNodes = [];
const textsReal = [];
(0, index_js_1.walkTextNodes)(cloneElement, (child) => {
textNodes.push(child);
textsReal.push(child.textContent || '');
});
const length = textsReal.join('').length;
const indexes = (0, tools_1.randomizeList)(Array(length)
.fill(null)
.map((_, i) => i));
const deciphered = {};
rootElement.appendChild(cloneElement);
contentElement.style.visibility = 'hidden';
return (0, animated_1.createAnimation)({
duration,
easing,
direction: isEntering ? 'normal' : 'reverse',
onUpdate: (progress) => {
const newPositionsLength = Math.round(length * progress);
for (let index = 0; index < length; index++) {
deciphered[indexes[index]] = index < newPositionsLength;
}
const textsCurrent = textsReal.map((text) => text
.split('')
.map((char, index) => {
if (char === ' ')
return ' ';
if (deciphered[index])
return char;
return characters[Math.round(Math.random() * (characters.length - 1))];
})
.join(''));
(0, index_js_2.setTextNodesContent)(textNodes, textsCurrent, length);
},
onFinish: () => {
contentElement.style.visibility =
(isEntering && hideOnEntered) || (!isEntering && hideOnExited) ? 'hidden' : '';
cloneElement.remove();
},
onCancel: () => {
contentElement.style.visibility = '';
cloneElement.remove();
}
});
};
exports.animateTextDecipher = animateTextDecipher;