Install @specy/liquid-glass-react
mainInstall the React wrapper for the liquid glass effect using npm:
npm install @specy/liquid-glass-reactrepository·main·Indexed 41 days ago
https://github.com/specy/liquid-glassA library for rendering high-quality liquid glass visual effects over content. Includes a core JavaScript API via @specy/liquid-glass and a React component wrapper via @specy/liquid-glass-react. Features include customizable GlassStyle properties (roughness, transmission, ior, thickness), PillGeometry for rounded shapes, and a takeElementScreenshot utility.
Install the React wrapper for the liquid glass effect using npm:
npm install @specy/liquid-glass-reactInstall the package using npm to use the liquid glass effects in your project.
npm install @specy/liquid-glassTo enforce React-specific best practices, you can integrate eslint-plugin-react-x and eslint-plugin-react-dom into your eslint.config.js. This allows you to use recommended TypeScript rules for React and standard recommended rules for React DOM.
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default tseslint.config({
plugins: {
// Add the react-x and react-dom plugins
'react-x': reactX,
'react-dom': reactDom,
},
rules: {
// other rules...
// Enable its recommended typescript rules
...reactX.configs['recommended-typescript'].rules,
...reactDom.configs.recommended.rules,
},
})For production applications, it is recommended to enable type-aware lint rules in your ESLint configuration. This involves replacing standard recommended configs with recommendedTypeChecked, strictTypeChecked, or stylisticTypeChecked and configuring parserOptions to point to your tsconfig files.
export default tseslint.config({
extends: [
// Remove ...tseslint.configs.recommended and replace with this
...tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
...tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
...tseslint.configs.stylisticTypeChecked,
],
languageOptions: {
// other options...
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
},
})To create a liquid glass effect, instantiate the LiquidGlass class by providing a target element (to capture for the background effect), screenshot options, custom CSS for the container, and glass material properties. You must then append glassEffect.element to the DOM and can add content via glassEffect.content.
import { LiquidGlass } from '@specy/liquid-glass';
// Create a glass effect on an element
const glassEffect = new LiquidGlass(
document.body, // Target element
{
// html2canvas options for screenshot
allowTaint: true,
useCORS: true,
scale: 1,
},
`
/* Custom CSS for the glass container */
position: fixed;
bottom: 1rem;
left: 50%;
transform: translateX(-50%);
padding: 1rem 2rem;
border-radius: 16px;
`,
{
// Glass style options
radius: 16,
roughness: 0.2,
transmission: 1,
ior: 1.5,
thickness: 32,
}
);
// Add the glass effect to the DOM
document.body.appendChild(glassEffect.element);
// Add content to the glass container
const content = document.createElement('div');
content.innerHTML = '<h1>Hello, Glass World!</h1>';
glassEffect.content.appendChild(content);To use LiquidGlass, wrap your content inside the component and provide a glassStyle object.
Performance Warning: Initialization is expensive. You must memoize the glassStyle object using useMemo to prevent unnecessary re-renders and unmounts, which can degrade performance.
import React, { useMemo } from 'react';
import { LiquidGlass } from '@specy/liquid-glass-react';
function App() {
// ⚠️ IMPORTANT: Memoize the glassStyle object to prevent unnecessary re-renders
const glassStyle = useMemo(() => ({
depth: 0.5,
segments: 32,
radius: 0.2,
roughness: 0.1,
transmission: 1,
reflectivity: 0.5,
ior: 1.5,
dispersion: 0.1,
thickness: 0.5
}), []);
return (
<LiquidGlass
glassStyle={glassStyle}
wrapperStyle={{
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
width: 'fit-content',
margin: '0 auto',
}}
style={`padding: 1rem;`}
>
<div>
<h1>Hello World!</h1>
<p>This content is rendered inside the liquid glass effect.</p>
</div>
</LiquidGlass>
);
}For advanced interactions, use a ref of type LiquidGlassRef to access the underlying instance and trigger updates like changing styles or updating screenshots.
Performance Warning: When using refs, ensure all objects and callbacks passed to the component are memoized (e.g., using useMemo and useCallback).
import React, { useRef, useMemo, useCallback } from 'react';
import { LiquidGlass, type LiquidGlassRef } from '@specy/liquid-glass-react';
function AdvancedExample() {
const glassRef = useRef<LiquidGlassRef>(null);
// ⚠️ IMPORTANT: Memoize all objects and callbacks
const glassStyle = useMemo(() => ({
depth: 0.8,
segments: 64,
radius: 0.3,
transmission: 0.95,
roughness: 0.05
}), []);
const onReady = useCallback((instance) => {
console.log('LiquidGlass instance ready:', instance);
}, []);
const handleUpdateScreenshot = useCallback(async () => {
await glassRef.current?.updateScreenshot();
}, []);
const handleUpdateStyle = useCallback(() => {
glassRef.current?.updateGlassStyle({
depth: Math.random(),
transmission: 0.8 + Math.random() * 0.2
});
}, []);
return (
<div
>
<LiquidGlass
ref={glassRef}
glassStyle={glassStyle}
onReady={onReady}
>
<div style={{ padding: '30px' }}>
<h2>Interactive Glass Effect</h2>
<button onClick={handleUpdateScreenshot}>
Update Screenshot
</button>
<button onClick={handleUpdateStyle}>
Randomize Style
</button>
</div>
</LiquidGlass>
</div>
);
}The takeElementScreenshot utility function allows you to capture a screenshot of a DOM element as a canvas.
import { takeElementScreenshot } from '@specy/liquid-glass';
const canvas = await takeElementScreenshot(element, {
allowTaint: true,
useCORS: true,
scale: 1
});The LiquidGlass class is the primary interface for creating glass effects.
new LiquidGlass(targetElement: HTMLElement, screenshotOptions?: Partial<Options>, customStyle?: string, glassStyle?: GlassStyle)
targetElement: The HTML element to capture for the background effect.screenshotOptions: Options for html2canvas screenshot capture.customStyle: Custom CSS styles for the glass container.glassStyle: Glass material properties.element: The main glass container element.content: The content container element for adding child elements.destroy(): Clean up and remove the glass effect.The PillGeometry class provides custom Three.js geometry specifically for creating pill-shaped (rounded rectangle) objects.
import { PillGeometry } from '@specy/liquid-glass';
const geometry = new PillGeometry(width, height, depth, segments, radius);The GlassStyle interface defines the material properties of the glass effect. Most values are normalized between 0 and 1.
interface GlassStyle {
depth?: number; // Depth of the glass effect (0-1)
segments?: number; // Number of geometry segments for smoothness
radius?: number; // Border radius (0-1)
tint?: number | null; // Color tint (hex number or null)
roughness?: number; // Surface roughness (0-1)
transmission?: number; // Light transmission (0-1)
reflectivity?: number; // Surface reflectivity (0-1)
ior?: number; // Index of refraction
dispersion?: number; // Chromatic dispersion effect
thickness?: number; // Glass thickness
}The LiquidGlassRef interface provides methods to interact with the active glass instance via a React ref.
interface LiquidGlassRef {
getInstance(): LiquidGlass | null;
updateScreenshot(): Promise<void>;
forceUpdate(): Promise<void>;
updateGlassStyle(style: Partial<GlassStyle>): void;
getGlassStyle(): Required<GlassStyle> | null;
getElement(): HTMLElement | null;
getContent(): HTMLDivElement | null;
}