Build New Optic website
This commit is contained in:
92
components/LiquidGlass.tsx
Normal file
92
components/LiquidGlass.tsx
Normal file
@@ -0,0 +1,92 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
liquidGL?: ((options: Record<string, unknown>) => unknown) & {
|
||||
registerDynamic?: (elements: string | Element[]) => void;
|
||||
syncWith?: () => unknown;
|
||||
};
|
||||
html2canvas?: unknown;
|
||||
}
|
||||
}
|
||||
|
||||
export default function LiquidGlass() {
|
||||
useEffect(() => {
|
||||
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
||||
if (!window.matchMedia("(min-width: 1024px)").matches) return;
|
||||
|
||||
let cancelled = false;
|
||||
let attempts = 0;
|
||||
|
||||
function loadScript(src: string) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const existing = document.querySelector<HTMLScriptElement>(`script[src="${src}"]`);
|
||||
if (existing) {
|
||||
if (existing.dataset.loaded === "true") resolve();
|
||||
existing.addEventListener("load", () => resolve(), { once: true });
|
||||
existing.addEventListener("error", () => reject(new Error(`Failed to load ${src}`)), { once: true });
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement("script");
|
||||
script.src = src;
|
||||
script.async = true;
|
||||
script.dataset.liquidDependency = "true";
|
||||
script.addEventListener("load", () => {
|
||||
script.dataset.loaded = "true";
|
||||
resolve();
|
||||
});
|
||||
script.addEventListener("error", () => reject(new Error(`Failed to load ${src}`)));
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
attempts += 1;
|
||||
if (cancelled) return;
|
||||
|
||||
if (!window.liquidGL || !window.html2canvas) {
|
||||
if (attempts < 50) window.setTimeout(init, 120);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
window.liquidGL({
|
||||
snapshot: "body",
|
||||
target: ".liquidGL-pane",
|
||||
resolution: 1.2,
|
||||
refraction: 0.012,
|
||||
bevelDepth: 0.052,
|
||||
bevelWidth: 0.18,
|
||||
frost: 0.85,
|
||||
shadow: true,
|
||||
specular: true,
|
||||
reveal: "fade",
|
||||
tilt: window.innerWidth >= 768,
|
||||
tiltFactor: 3.5,
|
||||
magnify: 1.01
|
||||
});
|
||||
|
||||
window.liquidGL.registerDynamic?.(".liquid-dynamic");
|
||||
window.liquidGL.syncWith?.();
|
||||
} catch (error) {
|
||||
console.warn("liquidGL could not initialise; CSS glass fallback remains active.", error);
|
||||
}
|
||||
};
|
||||
|
||||
Promise.all([
|
||||
loadScript("https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"),
|
||||
loadScript("/scripts/liquidGL.js")
|
||||
])
|
||||
.then(init)
|
||||
.catch((error) => console.warn("liquidGL dependencies could not load; CSS glass fallback remains active.", error));
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user