UNPKG

wotsui-vue-directives

Version:
108 lines (107 loc) 3.22 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const intersection_1 = require("../hooks/intersection"); const baseSettings = { interval: 20, ignorePunctuation: false, }; function typewrite(el, binding) { const typewriteData = parseData(el); const settings = initSettings(binding); const observer = new IntersectionObserver(handleIntersection, { threshold: settings.treshold, }); intersection_1.setIntersectionClasses(el, settings, false); bindsMap.set(el, { data: typewriteData, settings }); observer.observe(el); } exports.default = typewrite; function parseData(el) { let data = []; const nodes = el.childNodes; nodes.forEach((node) => { if (!node.textContent) { return; } if (node.nodeType === 3) { data.push({ node, textContent: node.textContent, }); node.textContent = ''; } else { data = data.concat(parseData(node)); } }); return data; } function initSettings(binding) { const settings = { ...intersection_1.intersectionSettings, ...baseSettings }; if (typeof binding.value === 'number') { settings.interval = binding.value; } if (typeof binding.value === 'object') { Object.assign(settings, binding.value); } if (binding.modifiers.ignorePunctuation) { settings.ignorePunctuation = true; } return settings; } function handleIntersection(entries, observer) { entries.forEach((entry) => { if (entry.isIntersecting) { const el = entry.target; const { data, settings } = bindsMap.get(el); if (!settings) { observer.unobserve(el); return; } intersection_1.setIntersectionClasses(el, settings, true); typeText(data, settings); bindsMap.delete(el); observer.unobserve(el); } }); } async function typeText(data, settings) { for (const nodeData of data) { try { const { node, textContent } = nodeData; if (!textContent) { continue; } for (const char of textContent) { node.textContent += char; let estimatedTime = settings.interval; if (!settings.ignorePunctuation) { estimatedTime *= getCharMultiplier(char); } try { await new Promise((resolve) => { setTimeout(() => { resolve(null); }, estimatedTime); }); } catch (error) { continue; } } } catch (error) { continue; } } } function getCharMultiplier(char) { if (char.match(/\.!\?/)) { return 10; } if (char.match(/[;:]/)) { return 5; } return 1; } const bindsMap = new Map();