Glass Panel

A visually stunning glass panel that reacts to mouse movements and scrolls, perfect for modern UIs.

Glass Panel

This is a cool glass panel that reacts to mouse movements and scrolls.

Installation

First, install the necessary dependencies for the glass panel effect.

tsx
1npm install react-parallax-tilt framer-motion clsx

Next, copy and paste the following component code into your project.

components/ui/glass-panel.tsx
1'use client';
2
3import React, { useRef, useEffect } from 'react';
4import { motion, useInView } from 'framer-motion';
5import { clsx } from 'clsx';
6import ParallaxTilt from 'react-parallax-tilt';
7
8const PanelStyles = () => (
9  <style jsx global>{`
10
11    .kinetic-panel-aurora-border {
12      position: relative;
13      overflow: hidden; 
14      border-radius: 24px;
15    }
16
17    .kinetic-panel-aurora-border::before {
18      content: '';
19      position: absolute;
20      top: 0;
21      left: 0;
22      right: 0;
23      bottom: 0;
24      z-index: 0; 
25
26      background: radial-gradient(
27        350px circle at var(--mouse-x) var(--mouse-y),
28        rgba(148, 163, 184, 0.25), 
29        transparent 80%
30      );
31      
32      padding: 1px; 
33      border-radius: inherit; 
34      
35      -webkit-mask: 
36        linear-gradient(#fff 0 0) content-box, 
37        linear-gradient(#fff 0 0);
38      mask: 
39        linear-gradient(#fff 0 0) content-box, 
40        linear-gradient(#fff 0 0);
41      -webkit-mask-composite: xor;
42      mask-composite: exclude;
43    }
44  `}</style>
45);
46
47interface GlassPanelProps {
48  children: React.ReactNode;
49  className?: string;
50  tiltEnable?: boolean;
51}
52
53export const GlassPanel: React.FC<GlassPanelProps> = ({
54  children,
55  className,
56  tiltEnable = true,
57}) => {
58  const ref = useRef<HTMLDivElement>(null);
59  const isInView = useInView(ref, { once: true, amount: 0.2 });
60
61  useEffect(() => {
62    const el = ref.current;
63    if (!el) return;
64
65    const handleMouseMove = (e: MouseEvent) => {
66      const rect = el.getBoundingClientRect();
67      el.style.setProperty('--mouse-x', `${e.clientX - rect.left}px`);
68      el.style.setProperty('--mouse-y', `${e.clientY - rect.top}px`);
69    };
70
71    el.addEventListener('mousemove', handleMouseMove);
72    return () => {
73      if (el) {
74        el.removeEventListener('mousemove', handleMouseMove);
75      }
76    };
77  }, []);
78
79  const contentPanel = (
80    <motion.div
81      ref={ref}
82      initial={{ opacity: 0, y: 50, filter: 'blur(8px)' }}
83      animate={isInView ? { opacity: 1, y: 0, filter: 'blur(0px)' } : {}}
84      transition={{ duration: 1.2, ease: [0.16, 1, 0.3, 1] }}
85      className={clsx(
86        'kinetic-panel-aurora-border',
87        'relative bg-white/5 backdrop-blur-xl',
88        'border border-white/10 rounded-3xl p-8',
89        'shadow-2xl shadow-black/40',
90        className 
91      )}
92    >
93      <div className="relative z-10">{children}</div>
94    </motion.div>
95  );
96
97  return (
98    <>
99      <PanelStyles />
100
101      {tiltEnable ? (
102        <ParallaxTilt
103          tiltMaxAngleX={4}
104          tiltMaxAngleY={4}
105          glareEnable={true}
106          glareMaxOpacity={0.1}
107          glarePosition="all"
108          scale={1.02}
109          transitionSpeed={3000}
110        >
111          {contentPanel}
112        </ParallaxTilt>
113      ) : (
114        contentPanel
115      )}
116    </>
117  );
118};
Popular Components