vevet
Version:
Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.
104 lines • 3.56 kB
JavaScript
import { doc } from '../../../internal/env';
import { isFiniteNumber } from '../../../internal/isFiniteNumber';
export class MarqueeNodes {
constructor(_ctx) {
this._ctx = _ctx;
/** Initial child nodes of the container */
this._initial = [];
/** Elements array */
this._elements = [];
}
/** Elements array */
get elements() {
return this._elements;
}
/* Save initial nodes */
save() {
const { container } = this._ctx.props;
this._initial = [...Array.from(container.childNodes)];
}
/**
* Wraps the first text node in the container in a span if no other elements exist.
*/
wrap() {
const { container } = this._ctx.props;
const nodes = this._initial;
nodes.forEach((node) => {
var _a, _b;
if (node.nodeType === 3) {
if (((_b = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === null || _b === void 0 ? void 0 : _b.length) === 0) {
return;
}
const wrapper = doc.createElement('span');
const { style } = wrapper;
style.position = 'relative';
style.display = 'block';
style.width = 'max-content';
style.whiteSpace = 'nowrap';
container.insertBefore(wrapper, node);
wrapper.appendChild(node);
}
});
this._elements = Array.from(container.children);
}
/**
* Adds necessary styles to all elements.
*/
applyStyles() {
this._elements.forEach((element, index) => this._applyElementStyles(element, index !== 0));
}
/**
* Adds necessary styles to a given element.
*/
_applyElementStyles(element, isAbsolute) {
const { isVertical, props } = this._ctx;
const el = element;
const { style } = el;
style.position = isAbsolute ? 'absolute' : 'relative';
style.top = isAbsolute && !isVertical ? '50%' : '0';
style.left = isAbsolute && isVertical ? '50%' : '0';
style.willChange = props.hasWillChange ? 'transform' : '';
style.flexShrink = '0';
if (isVertical) {
style.height = style.height || 'max-content';
}
else {
style.width = style.width || 'max-content';
}
}
/**
* Clone elements
*/
cloneAll(times) {
if (!isFiniteNumber(times) || times <= 0) {
return;
}
const elements = [...this.elements];
const { container } = this._ctx.props;
for (let i = 0; i < times; i += 1) {
elements.forEach((element) => {
const copy = element.cloneNode(true);
this._applyElementStyles(copy, true);
container.appendChild(copy);
});
}
// Update element references after cloning
this._elements = Array.from(container.children);
}
/** Restores the initial nodes */
destroy() {
const { container } = this._ctx.props;
this._initial.forEach((node) => container.appendChild(node));
this._elements.forEach((element) => {
const { style } = element;
style.position = '';
style.top = '';
style.left = '';
style.flexShrink = '';
style.width = '';
style.transform = '';
style.willChange = '';
});
}
}
//# sourceMappingURL=index.js.map