@specy/liquid-glass-react
Version:
React component for @specy/liquid-glass - A Three.js powered library to make apple's liquid with glass effect
157 lines (130 loc) • 5.31 kB
Markdown
# @specy/liquid-glass-react
React wrapper for [@specy/liquid-glass](https://github.com/Specy/liquid-glass) - A Three.js powered glass effect component that recreates apple's liquid glass .
## Installation
```bash
npm install @specy/liquid-glass-react
```
## Basic Usage
Initialization is expensive, try to minimize re-renders and unnecessary unmouts.
The component does it's best to track the position of the target element in the page and update the effect, but it cannot track the `top` or `left` etc.. position changes, if you update them, you should call the `forceUpdate` method on the ref to re-render the effect, or use the `renderKey` prop to force a re-render when needed.
```tsx
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>
);
}
```
## Advanced Usage with Ref
```tsx
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>
)
}
```
## Props
| Prop | Type | Default | Description |
| --------------- | --------------------------------- | --------------- | ------------------------------------------------------------------- |
| `style` | `string` | `''` | Custom CSS styles to apply to the glass container |
| `wrapperStyle` | `React.CSSProperties` | `{}` | React CSS properties to apply to the wrapper div |
| `glassStyle` | `GlassStyle` | `{}` | Glass material properties (see GlassStyle interface) |
| `children` | `React.ReactNode` | `undefined` | Content to render inside the glass container |
| `onReady` | `(instance: LiquidGlass) => void` | `undefined` | Callback when the liquid glass instance is ready |
| `targetElement` | `HTMLElement` | `document.body` | The target element to capture for the glass background effect |
| `renderKey` | `string | number` | Unique key to force re-render the component when changed (manually) |
## GlassStyle Interface
```tsx
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
}
```
## Ref Methods
The component exposes several methods through the ref:
```tsx
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
forcePositionUpdate(): void
forceSizeUpdate(): void
}
```
## Contributing
Issues and pull requests are welcome at the [main repository](https://github.com/Specy/liquid-glass).