UNPKG

vuestic-ui

Version:
102 lines (101 loc) 3.12 kB
import { ref, watchEffect } from "vue"; const parseRgba = (rgba) => { let values; if (rgba.startsWith("rgba")) { values = rgba.substring(5, rgba.length - 1).split(","); } else { values = rgba.substring(4, rgba.length - 1).split(","); } values[0] = Number(values[0]); values[1] = Number(values[1]); values[2] = Number(values[2]); if (values[3] === void 0) { values[3] = 1; } else { values[3] = Number(values[3]); } return values; }; const toHex = (color) => { return "#" + (color[0] | 1 << 8).toString(16).slice(1) + (color[1] | 1 << 8).toString(16).slice(1) + (color[2] | 1 << 8).toString(16).slice(1) + (color[3] * 255 | 1 << 8).toString(16).slice(1); }; const getParentsWithBackground = (el) => { const parents = []; let currentEl = el; while (currentEl) { if (!(currentEl instanceof HTMLElement) || !currentEl) { return parents; } const { backgroundColor, willChange } = window.getComputedStyle(currentEl); const bgWillChange = willChange.includes("background"); const parsedColor = parseRgba(backgroundColor); if (parsedColor[3] === 1 && !bgWillChange) { parents.push(currentEl); return parents; } if (parsedColor[3] !== 0 || bgWillChange) { parents.push(currentEl); } currentEl = currentEl.parentElement; } return parents; }; const WATCHER_CLASS = "va-background-watcher"; const watchElementBackground = (el, cb) => { el.className = WATCHER_CLASS + " " + el.className; el.addEventListener("transitionend", (e) => { if (e.target !== el) { return; } cb(); }); return () => { el.className = el.className.replace(WATCHER_CLASS, ""); el.removeEventListener("transitionend", cb); }; }; const watchElementsBackground = (els, cb) => { const unwatchers = els.map((el) => watchElementBackground(el, cb)); return () => { unwatchers.forEach((unwatch) => unwatch()); }; }; const applyColors = (color1, color2) => { const weight = color2[3]; if (weight === 1) { return color2; } if (weight === 0) { return color1; } const c1 = Math.round(color1[0] * (1 - weight) + color2[0] * weight); const c2 = Math.round(color1[1] * (1 - weight) + color2[1] * weight); const c3 = Math.round(color1[2] * (1 - weight) + color2[2] * weight); return [c1, c2, c3, 1]; }; const getColorFromElements = (els) => { let currentColor = [0, 0, 0, 0]; for (let i = els.length - 1; i >= 0; i--) { currentColor = applyColors(currentColor, parseRgba(window.getComputedStyle(els[i]).backgroundColor)); } return currentColor; }; const useElementBackground = (el) => { const color = ref("#000000"); let unWatchAll = () => void 0; watchEffect(() => { unWatchAll(); if (el.value) { const parents = getParentsWithBackground(el.value); unWatchAll = watchElementsBackground(parents, () => { color.value = toHex(getColorFromElements(parents)); }); color.value = toHex(getColorFromElements(parents)); } }); return color; }; export { useElementBackground as u }; //# sourceMappingURL=useElementBackground.mjs.map