Skip to content

Commit 3e9f110

Browse files
author
Ritika Mishra
committed
Add dimensions for responsive UI
1 parent 8f15247 commit 3e9f110

File tree

2 files changed

+588
-613
lines changed

2 files changed

+588
-613
lines changed

src/components/CandleLit.tsx

Lines changed: 85 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -4,126 +4,100 @@ type FFTChannel = number[];
44
type FFTData = FFTChannel[];
55

66
interface BrightCandleViewProps {
7-
fftData?: FFTData;
8-
betaPower: number;
7+
fftData?: FFTData;
8+
betaPower: number;
9+
isFullPage?: boolean;
910
}
1011

11-
interface CandleLitProps {
12-
betaPower: number;
13-
}
14-
15-
const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaPower }) => {
16-
const brightness = Math.max(0, betaPower / 100); // Normalize brightness
17-
// Add smoothing and minimum brightness
18-
const [displayBrightness, setDisplayBrightness] = useState(0.1); // Start with small flame
19-
20-
useEffect(() => {
21-
// Always show at least a small flame (0.1) and cap at 1.0
22-
const target = Math.max(0.1, Math.min(1, betaPower / 100));
12+
const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaPower, isFullPage }) => {
13+
const brightness = Math.max(0, betaPower / 100);
14+
const [displayBrightness, setDisplayBrightness] = useState(0.1);
2315

24-
// Smooth transition
25-
const timer = setInterval(() => {
26-
setDisplayBrightness(prev => {
27-
const diff = target - prev;
28-
return Math.abs(diff) < 0.01 ? target : prev + diff * 0.1;
29-
});
30-
}, 16); // ~60fps
16+
useEffect(() => {
17+
const target = Math.max(0.1, Math.min(1, betaPower / 100));
18+
const timer = setInterval(() => {
19+
setDisplayBrightness(prev => {
20+
const diff = target - prev;
21+
return Math.abs(diff) < 0.01 ? target : prev + diff * 0.1;
22+
});
23+
}, 16);
24+
return () => clearInterval(timer);
25+
}, [betaPower]);
3126

32-
return () => clearInterval(timer);
33-
}, [betaPower]);
34-
35-
// Generate a slightly randomized organic flame path
36-
const generateFlamePath = () => {
37-
const basePoints = [
38-
{ x: 100, y: 50 },
39-
{ x: 70, y: 100 },
40-
{ x: 100, y: 180 },
41-
{ x: 130, y: 100 }
42-
];
43-
const controlPoints = basePoints.map(point => ({
44-
x: point.x + (Math.random() - 0.5) * (10 * brightness),
45-
y: point.y + (Math.random() - 0.5) * (10 * brightness)
46-
}));
47-
return `
48-
M${controlPoints[0].x} ${controlPoints[0].y}
27+
const generateFlamePath = () => {
28+
const basePoints = [
29+
{ x: 100, y: 50 },
30+
{ x: 70, y: 100 },
31+
{ x: 100, y: 180 },
32+
{ x: 130, y: 100 }
33+
];
34+
const controlPoints = basePoints.map(point => ({
35+
x: point.x + (Math.random() - 0.5) * (10 * brightness),
36+
y: point.y + (Math.random() - 0.5) * (10 * brightness)
37+
}));
38+
return `
39+
M${controlPoints[0].x} ${controlPoints[0].y}
4940
Q${controlPoints[1].x} ${controlPoints[1].y}, ${controlPoints[2].x} ${controlPoints[2].y}
5041
Q${controlPoints[3].x} ${controlPoints[3].y}, ${controlPoints[0].x} ${controlPoints[0].y}
5142
`;
52-
};
53-
54-
return (
55-
<div className="w-full h-full flex items-center justify-center min-h-0 min-w-0">
56-
{/* Candle Container - responsive width for different screen sizes */}
57-
<div className="relative w-24 sm:w-28 md:w-32 lg:w-36 h-64 group">
58-
{/* Candle Holder with a glassy, frosted look */}
59-
<div className="absolute bottom-0 w-full h-24 sm:h-28 md:h-32
60-
bg-gradient-to-b from-gray-100 to-gray-200 dark:from-stone-600 dark:to-stone-700
61-
rounded-b-xl rounded-t-md
62-
border border-gray-300 dark:border-white/20
63-
backdrop-blur-md shadow-xl
64-
transition-transform duration-300
65-
before:absolute before:inset-0 before:bg-white/10 before:opacity-40 before:rounded-b-xl before:rounded-t-md"
66-
>
67-
<div className="absolute inset-0 overflow-hidden rounded-b-xl rounded-t-md bg-gradient-to-b from-cyan-300 via-blue-400 to-blue-400">
68-
<div className="absolute top-2 left-1/2 transform -translate-x-1/2 text-center">
69-
<div className="text-base sm:text-lg font-semibold text-gray-700 px-1 sm:px-2 py-1 rounded-md">
70-
{String(Math.floor(betaPower)).padStart(2, '0')}
71-
</div>
72-
</div>
73-
</div>
74-
</div>
75-
76-
{/* Yellow-Themed Animated Flame */}
77-
<svg
78-
xmlns="http://www.w3.org/2000/svg"
79-
viewBox="0 0 200 300"
80-
className="absolute top-0 left-1/2 transform -translate-x-1/2 w-full h-36 sm:h-40 md:h-44 lg:h-48 z-10 drop-shadow-xl"
81-
>
82-
<defs>
83-
{/* Outer Flame Gradient: Rich, Realistic Candle Flame Colors */}
84-
<linearGradient id="outerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
85-
<stop offset="0%" stopColor={`rgba(255,140,0, ${brightness * 0.6})`} />
86-
<stop offset="100%" stopColor={`rgba(255,69,0, ${brightness * 0.3})`} />
87-
</linearGradient>
88-
89-
{/* Inner Flame Gradient: Warm, Luminous Colors */}
90-
<linearGradient id="innerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
91-
<stop offset="0%" stopColor={`rgba(255,165,0, ${brightness * 0.8})`} />
92-
<stop offset="100%" stopColor={`rgba(255,99,71, ${brightness * 0.5})`} />
93-
</linearGradient>
43+
};
9444

95-
{/* Filters for Enhanced Realism */}
96-
<filter id="flameBlur">
97-
<feGaussianBlur stdDeviation="7" />
98-
</filter>
99-
<filter id="innerGlow">
100-
<feGaussianBlur stdDeviation="4" result="coloredBlur" />
101-
<feMerge>
102-
<feMergeNode in="coloredBlur" />
103-
<feMergeNode in="SourceGraphic" />
104-
</feMerge>
105-
</filter>
106-
</defs>
45+
return (
46+
<div className="w-full h-full flex items-end justify-center min-h-0 min-w-0">
47+
<div className={`relative ${isFullPage ? 'w-[20%] sm:w-[18%] md:w-[20%] lg:w-[25%] h-[30%] sm:h-[40%] md:h-[50%] lg:h-[60%]' : 'w-[20%] sm:w-[18%] md:w-[15%] lg:w-[20%] h-[60%] sm:h-[70%] md:h-[80%] lg:h-[95%]'} group overflow-visible`}>
48+
<svg
49+
xmlns="http://www.w3.org/2000/svg"
50+
viewBox="0 0 200 300"
51+
className={`absolute ${isFullPage ? '-top-[42%] sm:-top-[40%] md:-top-[50%] lg:-top-[40%]' : '-top-[25%] sm:-top-[18%] md:-top-[14%] lg:-top-[24%]'} left-1/2 transform -translate-x-1/2 w-full h-auto z-50 drop-shadow-xl pointer-events-none`}
52+
preserveAspectRatio="xMidYMid meet"
53+
>
10754

108-
{/* Outer Flame Layer */}
109-
<path
110-
d={generateFlamePath()}
111-
fill="url(#outerFlameGradient)"
112-
filter="url(#flameBlur)"
113-
className="transition-all duration-300 animate-flicker opacity-70"
114-
/>
55+
<defs>
56+
<linearGradient id="outerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
57+
<stop offset="0%" stopColor={`rgba(255,140,0, ${brightness * 0.6})`} />
58+
<stop offset="100%" stopColor={`rgba(255,69,0, ${brightness * 0.3})`} />
59+
</linearGradient>
60+
<linearGradient id="innerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
61+
<stop offset="0%" stopColor={`rgba(255,165,0, ${brightness * 0.8})`} />
62+
<stop offset="100%" stopColor={`rgba(255,99,71, ${brightness * 0.5})`} />
63+
</linearGradient>
64+
<filter id="flameBlur">
65+
<feGaussianBlur stdDeviation="7" />
66+
</filter>
67+
<filter id="innerGlow">
68+
<feGaussianBlur stdDeviation="4" result="coloredBlur" />
69+
<feMerge>
70+
<feMergeNode in="coloredBlur" />
71+
<feMergeNode in="SourceGraphic" />
72+
</feMerge>
73+
</filter>
74+
</defs>
75+
<path
76+
d={generateFlamePath()}
77+
fill="url(#outerFlameGradient)"
78+
filter="url(#flameBlur)"
79+
className="transition-all duration-300 animate-flicker opacity-70"
80+
/>
81+
<path
82+
d={generateFlamePath()}
83+
fill="url(#innerFlameGradient)"
84+
filter="url(#innerGlow)"
85+
className="transition-all duration-300 animate-flicker"
86+
/>
87+
</svg>
88+
<div className={`absolute bottom-0 w-full ${isFullPage ? 'h-full' : 'h-[30%] sm:h-[32%] md:h-[34%] lg:h-[36%]'} bg-gradient-to-b from-gray-100 to-gray-200 dark:from-stone-600 dark:to-stone-700 rounded-b-xl rounded-t-md border border-gray-300 dark:border-white/20 backdrop-blur-md shadow-xl before:absolute before:inset-0 before:bg-white/10 before:opacity-40 before:rounded-b-xl before:rounded-t-md`}>
89+
<div className="absolute inset-0 overflow-hidden rounded-b-xl rounded-t-md bg-gradient-to-b from-cyan-300 via-blue-400 to-blue-400">
90+
<div className="absolute inset-0 flex items-center justify-center">
91+
<div className="text-sm sm:text-xl md:text-xl lg:text-2xl font-semibold text-gray-700 px-2 sm:px-3 py-1 ">
92+
{Number.isFinite(betaPower) ? String(Math.floor(betaPower)).padStart(2, '0') : '00'}
93+
</div>
94+
</div>
11595

116-
{/* Inner Flame Layer */}
117-
<path
118-
d={generateFlamePath()}
119-
fill="url(#innerFlameGradient)"
120-
filter="url(#innerGlow)"
121-
className="transition-all duration-300 animate-flicker"
122-
/>
123-
</svg>
124-
</div>
125-
</div>
126-
);
96+
</div>
97+
</div>
98+
</div>
99+
</div>
100+
);
127101
};
128102

129-
export default BrightCandleView;
103+
export default BrightCandleView;

0 commit comments

Comments
 (0)