@arwes/text
Version:
Futuristic Sci-Fi UI Web Framework
88 lines (87 loc) • 3.38 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.animateTextSequence = 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 animateTextSequence = (props) => {
const { rootElement, contentElement, duration, easing = 'linear', blink = true, blinkDuration = 0.1, isEntering = true, hideOnExited = true, hideOnEntered } = (0, tools_1.filterProps)(props);
if (!rootElement || !contentElement) {
throw new Error('ARWES animateTextSequence() requires valid DOM elements.');
}
let blinkElement;
let blinkAnimation;
const cloneElement = contentElement.cloneNode(true);
Object.assign(cloneElement.style, {
position: 'absolute',
inset: 0,
visibility: 'visible',
opacity: 1
});
if (blink) {
blinkElement = document.createElement('span');
blinkElement.classList.add('arwes-text__blink');
blinkElement.innerHTML = '▎';
Object.assign(blinkElement.style, {
position: 'relative',
display: 'inline-block',
width: 0,
height: 0,
lineHeight: '0',
color: 'inherit'
});
}
const textNodes = [];
const texts = [];
(0, index_js_1.walkTextNodes)(cloneElement, (child) => {
textNodes.push(child);
texts.push(child.textContent || '');
if (isEntering) {
child.textContent = '';
}
});
const length = texts.join('').length;
rootElement.appendChild(cloneElement);
contentElement.style.visibility = 'hidden';
if (blink && blinkElement) {
const blinkAnimationEaseColor = (0, animated_1.easeAmong)([0, 1, 2]);
const blinkAnimationColors = ['transparent', 'inherit', 'transparent'];
blinkAnimation = (0, animated_1.createAnimation)({
duration: blinkDuration,
easing: 'linear',
repeat: Infinity,
onUpdate(progress) {
const index = Math.round(blinkAnimationEaseColor(progress));
blinkElement.style.color = blinkAnimationColors[index];
}
});
}
return (0, animated_1.createAnimation)({
duration,
easing,
direction: isEntering ? 'normal' : 'reverse',
onUpdate: (progress) => {
const newLength = Math.round(progress * length);
(0, index_js_2.setTextNodesContent)(textNodes, texts, newLength, (textNode) => {
if (blinkElement &&
textNode.parentNode &&
textNode.parentNode !== blinkElement.parentNode) {
textNode.parentNode.appendChild(blinkElement);
}
});
},
onFinish: () => {
contentElement.style.visibility =
(isEntering && hideOnEntered) || (!isEntering && hideOnExited) ? 'hidden' : '';
cloneElement.remove();
blinkAnimation?.cancel();
},
onCancel: () => {
contentElement.style.visibility = '';
cloneElement.remove();
blinkAnimation?.cancel();
}
});
};
exports.animateTextSequence = animateTextSequence;