vuestic-ui
Version:
Vue 3 UI Framework
102 lines (101 loc) • 3.12 kB
JavaScript
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