FrostedGlass#

A container that blurs the 3D scene behind it, creating a frosted glass effect. The blur pipeline is fully automatic — no camera or render texture setup needed.

Import#

import { FrostedGlass } from "onejs-react"

Basic Usage#

<FrostedGlass style={{ width: 300, height: 200, borderRadius: 16 }}>
    <Label text="Hello from behind the glass" />
</FrostedGlass>

Props#

PropTypeDefaultDescription
blurnumber10Blur radius in screen pixels. Higher = more blurry
tintstring"rgba(255,255,255,0.15)"Tint color overlaid on the blurred background
styleViewStyleInline styles
classNamestringUSS class name(s)

Tint Color#

The tint prop accepts a CSS color string. Use alpha to control how much the tint blends with the blurred background:

// Subtle white frost
<FrostedGlass tint="rgba(255,255,255,0.15)" />

// Colored glass
<FrostedGlass tint="rgba(25,200,240,0.2)" />

// Heavy tint
<FrostedGlass tint="rgba(0,0,0,0.5)" />

Dynamic Blur#

The blur radius can be adjusted at runtime:

function BlurPanel() {
    const [blur, setBlur] = useState(10)

    return (
        <View>
            <FrostedGlass blur={blur}
                style={{ width: 300, height: 200, borderRadius: 16 }}>
                <Label text={`Blur: ${Math.round(blur)}`} />
            </FrostedGlass>
            <Slider
                value={blur}
                lowValue={0}
                highValue={40}
                onChange={(e) => setBlur(e.value)}
                style={{ width: 300, marginTop: 16 }}
            />
        </View>
    )
}

How It Works#

FrostedGlass captures the 3D scene using a lightweight clone camera (excluding UI), downsamples it, and applies a two-pass Gaussian blur. The blurred result is UV-mapped to the element's screen position so it always reflects what's directly behind it.

Multiple FrostedGlass elements share a single blur pass for efficiency.

Rotation Example#

The blur stays screen-aligned even when the element is rotated:

function App() {
    const [blur, setBlur] = useState(10)
    const [rotation, setRotation] = useState(0)
    const rafRef = useRef<number>(0)

    useEffect(() => {
        const animate = () => {
            setRotation(r => (r + 0.5) % 360)
            rafRef.current = requestAnimationFrame(animate)
        }
        rafRef.current = requestAnimationFrame(animate)
        return () => cancelAnimationFrame(rafRef.current)
    }, [])

    return (
        <View style={{ justifyContent: "center", alignItems: "center",
            width: "100%", height: "100%" }}>
            <FrostedGlass blur={blur} tint="rgba(25, 243, 243, 0.15)"
                style={{ justifyContent: "center", alignItems: "center",
                    width: 300, height: 200, borderRadius: 16, rotate: rotation }}>
                <Label>Blur: {Math.round(blur)}</Label>
            </FrostedGlass>
            <Slider lowValue={0} highValue={40} value={blur}
                onChange={(e) => setBlur(e.value)}
                style={{ width: 300, marginTop: 16 }} />
        </View>
    )
}