UNPKG

vevet

Version:

Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.

134 lines 5.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.childOf = childOf; exports.wrapLines = wrapLines; var cn_1 = require("../../../internal/cn"); var env_1 = require("../../../internal/env"); var getTextAlignment_1 = require("./getTextAlignment"); /** * Recursively retrieves the top parent element of a given element within a container. */ function getTopParent(ref, topParent) { var _a; if (!(ref === null || ref === void 0 ? void 0 : ref.parentElement)) { return null; } if (ref.parentElement === topParent) { return ref; } return getTopParent((_a = ref === null || ref === void 0 ? void 0 : ref.parentElement) !== null && _a !== void 0 ? _a : null, topParent); } function childOf(element, parent) { if (element === parent) { return true; } if (element !== null) { return childOf(element.parentNode, parent); } return false; } /** * Wraps each word in the container into lines, based on their vertical position. */ function wrapLines(_a) { var container = _a.container, hasLinesWrapper = _a.hasLinesWrapper, wordsMeta = _a.wordsMeta, lineClassName = _a.lineClassName, lineWrapperClassName = _a.lineWrapperClassName, tagName = _a.tagName; var direction = (0, getTextAlignment_1.getTextAlignment)(container); var linesMeta = []; var lineIndex = -1; var lastBounding = null; var baseElement = env_1.doc.createElement(tagName); baseElement.style.display = 'block'; baseElement.setAttribute('aria-hidden', 'true'); (0, cn_1.cnAdd)(baseElement, lineClassName); var boundings = wordsMeta.map(function (wordMeta) { return wordMeta.element.getBoundingClientRect(); }); // Create lines by wrapping words wordsMeta.forEach(function (wordMeta, index) { var _a; var bounds = boundings[index]; var topParent = getTopParent(wordMeta.element, container); if (!topParent) { return; } // create new line if the top position changes var isNextTop = lastBounding && bounds.top > lastBounding.top; var isNextLeft = lastBounding && bounds.left >= lastBounding.left; var isPrevLeft = lastBounding && bounds.left <= lastBounding.left; if (!lastBounding || (isNextTop && isPrevLeft && direction === 'left') || (isNextTop && isNextLeft && direction === 'right') || (isNextTop && direction === 'center')) { lineIndex += 1; var element = baseElement.cloneNode(false); var wrapper = void 0; if (hasLinesWrapper) { wrapper = env_1.doc.createElement(tagName); wrapper.style.display = 'block'; (0, cn_1.cnAdd)(wrapper, lineWrapperClassName); wrapper.appendChild(element); } linesMeta[lineIndex] = { element: element, wrapper: wrapper, nodes: [], words: [] }; } lastBounding = bounds; var currentLine = linesMeta[lineIndex]; var isInList = !!linesMeta.find(function (_a) { var nodes = _a.nodes; return nodes.includes(topParent); }); if (!isInList) { currentLine.nodes.push(topParent); if (((_a = topParent.nextSibling) === null || _a === void 0 ? void 0 : _a.nodeType) === 3) { currentLine.nodes.push(topParent.nextSibling); } } }); // Append line elements to the container linesMeta.forEach(function (line) { var _a; container.insertBefore((_a = line.wrapper) !== null && _a !== void 0 ? _a : line.element, line.nodes[0]); var fragment = env_1.doc.createDocumentFragment(); fragment.append.apply(fragment, line.nodes); line.element.append(fragment); }); // Hide any extra <br> elements after lines var hiddenBr = []; linesMeta.forEach(function (line) { var _a; var nextSibling = ((_a = line.wrapper) !== null && _a !== void 0 ? _a : line.element).nextElementSibling; if (nextSibling instanceof HTMLBRElement) { nextSibling.style.display = 'none'; hiddenBr.push(nextSibling); } }); // Associate words with the corresponding lines linesMeta.forEach(function (line) { var _a; (_a = line.words).push.apply(_a, wordsMeta.filter(function (word) { return childOf(word.element, line.element); })); }); // Destroy method to undo the line wrapping var destroy = function () { var isSuccess = true; hiddenBr.forEach(function (br) { br.style.display = ''; }); linesMeta.forEach(function (line) { var _a; line.nodes.forEach(function (node) { var _a; var reference = (_a = line.wrapper) !== null && _a !== void 0 ? _a : line.element; if (reference.parentElement) { container.insertBefore(node, reference); } else { isSuccess = false; } }); line.element.remove(); (_a = line.wrapper) === null || _a === void 0 ? void 0 : _a.remove(); }); return isSuccess; }; return { linesMeta: linesMeta, destroy: destroy }; } //# sourceMappingURL=wrapLines.js.map