solid-glass
Version:
A lightweight glass effect library for web apps, supporting React and Vue.
84 lines (83 loc) • 3.24 kB
JavaScript
class o {
constructor(t, e = {}) {
this.element = t, this.options = {
// Inner shadow
shadowColor: "rgba(255, 255, 255, 0.7)",
shadowBlur: 7,
shadowSpread: 0,
shadowOffset: 0,
// Glass tint
tintColor: "255, 255, 255",
tintOpacity: 0.04,
// Frost blur
frostBlur: 2,
// Noise distortion
noiseFrequency: 8e-3,
distortionStrength: 77,
// Shape
borderRadius: 28,
...e
}, this.svgId = `glass-distortion-${Math.random().toString(36).substr(2, 9)}`, this.init();
}
init() {
this.element.classList.add("solid-glass"), this.createSVGFilter(), this.updateStyles();
}
createSVGFilter() {
if (!document.getElementById(this.svgId)) {
const t = document.createElementNS("http://www.w3.org/2000/svg", "svg");
t.setAttribute("width", "0"), t.setAttribute("height", "0"), t.style.position = "absolute", t.style.overflow = "hidden", t.innerHTML = `
<defs>
<filter id="${this.svgId}" x="0%" y="0%" width="100%" height="100%">
<feTurbulence type="fractalNoise" baseFrequency="${this.options.noiseFrequency} ${this.options.noiseFrequency}" numOctaves="2" seed="92" result="noise" />
<feGaussianBlur in="noise" stdDeviation="2" result="blurred" />
<feDisplacementMap in="SourceGraphic" in2="blurred" scale="${this.options.distortionStrength}" xChannelSelector="R" yChannelSelector="G" />
</filter>
</defs>
`, document.body.appendChild(t);
}
}
updateStyles() {
const t = {
"--lg-shadow-color": this.options.shadowColor,
"--lg-shadow-blur": `${this.options.shadowBlur}px`,
"--lg-shadow-spread": `${this.options.shadowSpread}px`,
"--lg-shadow-offset": this.options.shadowOffset,
"--lg-tint-color": this.options.tintColor,
"--lg-tint-opacity": this.options.tintOpacity,
"--lg-frost-blur": `${this.options.frostBlur}px`,
"--lg-border-radius": `${this.options.borderRadius}px`,
"--lg-filter-id": `url(#${this.svgId})`
};
Object.entries(t).forEach(([e, i]) => {
this.element.style.setProperty(e, i);
});
}
updateOption(t, e) {
this.options[t] = e, (t === "noiseFrequency" || t === "distortionStrength") && this.updateSVGFilter(), this.updateStyles();
}
updateSVGFilter() {
const t = document.getElementById(this.svgId);
if (t) {
const e = t.querySelector("feTurbulence"), i = t.querySelector("feDisplacementMap");
e && e.setAttribute("baseFrequency", `${this.options.noiseFrequency} ${this.options.noiseFrequency}`), i && i.setAttribute("scale", this.options.distortionStrength);
}
}
destroy() {
var e;
this.element.classList.remove("solid-glass");
const t = (e = document.getElementById(this.svgId)) == null ? void 0 : e.parentElement;
t && t.remove();
}
}
function r(s) {
const t = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(s);
return t ? `${parseInt(t[1], 16)}, ${parseInt(t[2], 16)}, ${parseInt(t[3], 16)}` : "255, 255, 255";
}
function n(s) {
return "#" + s.split(",").map((e) => parseInt(e.trim())).map((e) => e.toString(16).padStart(2, "0")).join("");
}
export {
o as L,
r as h,
n as r
};