Skip to content

Commit e7cfa5d

Browse files
author
Ritika Mishra
committed
updated flame ui
1 parent 4197283 commit e7cfa5d

File tree

2 files changed

+125
-116
lines changed

2 files changed

+125
-116
lines changed

src/components/CandleLit.tsx

Lines changed: 69 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaP
2626

2727
const generateFlamePath = () => {
2828
const basePoints = [
29-
{ x: 100, y: 50 },
30-
{ x: 70, y: 100 },
31-
{ x: 100, y: 180 },
32-
{ x: 130, y: 100 }
29+
{ x: 100, y: 120 },
30+
{ x: 70, y: 220 },
31+
{ x: 100, y: 280 },
32+
{ x: 130, y: 220 }
3333
];
3434
const controlPoints = basePoints.map(point => ({
3535
x: point.x + (Math.random() - 0.5) * (10 * brightness),
@@ -44,59 +44,77 @@ const BrightCandleView: React.FC<BrightCandleViewProps> = ({ fftData = [], betaP
4444

4545
return (
4646
<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-[38%]' : '-top-[25%] sm:-top-[18%] md:-top-[14%] lg:-top-[2%]'} 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-
>
54-
<defs>
55-
<linearGradient id="outerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
56-
<stop offset="0%" stopColor={`rgba(255,140,0, ${brightness * 0.6})`} />
57-
<stop offset="100%" stopColor={`rgba(255,69,0, ${brightness * 0.3})`} />
58-
</linearGradient>
59-
<linearGradient id="innerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
60-
<stop offset="0%" stopColor={`rgba(255,165,0, ${brightness * 0.8})`} />
61-
<stop offset="100%" stopColor={`rgba(255,99,71, ${brightness * 0.5})`} />
62-
</linearGradient>
63-
<filter id="flameBlur">
64-
<feGaussianBlur stdDeviation="7" />
65-
</filter>
66-
<filter id="innerGlow">
67-
<feGaussianBlur stdDeviation="4" result="coloredBlur" />
68-
<feMerge>
69-
<feMergeNode in="coloredBlur" />
70-
<feMergeNode in="SourceGraphic" />
71-
</feMerge>
72-
</filter>
73-
</defs>
74-
<path
75-
d={generateFlamePath()}
76-
fill="url(#outerFlameGradient)"
77-
filter="url(#flameBlur)"
78-
className="transition-all duration-300 animate-flicker opacity-70"
79-
/>
80-
<path
81-
d={generateFlamePath()}
82-
fill="url(#innerFlameGradient)"
83-
filter="url(#innerGlow)"
84-
className="transition-all duration-300 animate-flicker"
85-
/>
86-
</svg>
87-
<div className={`absolute bottom-0 w-full ${isFullPage ? 'h-full' : 'h-[30%] sm:h-[32%] md:h-[34%] lg:h-[26%]'} bg-gradient-to-b from-gray-100 to-gray-200 dark:from-stone-600 dark:to-stone-700 rounded-t-md 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`}>
88-
<div className="absolute inset-0 overflow-hidden rounded-t-md bg-gradient-to-b from-cyan-300 via-blue-400 to-gray-900">
89-
<div className={`absolute inset-0 ${isFullPage ? 'flex flex-row justify-center pt-10' : 'flex items-center justify-center'} `}>
90-
<div className="text-sm sm:text-xl md:text-xl lg:text-3xl font-semibold text-gray-800 px-2 sm:px-3 py-1 ">
91-
{Number.isFinite(betaPower) ? String(Math.floor(betaPower)).padStart(2, '0') : '00'}
47+
<div className={`relative ${
48+
isFullPage
49+
? 'w-1/4 h-3/5 sm:w-1/5 sm:h-3/5 md:w-1/5 md:h-3/5 lg:w-1/5 lg:h-2/3 xl:w-1/6 xl:h-2/3 2xl:w-1/6 2xl:h-2/3'
50+
: 'w-1/4 h-4/5 sm:w-1/5 sm:h-4/5 md:w-1/6 md:h-5/6 lg:w-1/6 lg:h-5/6 xl:w-1/6 xl:h-5/6'
51+
}`}
52+
>
53+
{/* Container wrapper with relative positioning */}
54+
<div className="relative w-full h-full flex flex-col">
55+
{/* Flame should take up approximately 60% of the total height */}
56+
<div style={{ height: '60%' }} className="relative w-full">
57+
<svg
58+
xmlns="http://www.w3.org/2000/svg"
59+
viewBox="0 0 200 300"
60+
className="absolute bottom-0 w-full"
61+
preserveAspectRatio="xMidYMid meet"
62+
>
63+
<defs>
64+
<linearGradient id="outerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
65+
<stop offset="0%" stopColor={`rgba(255,140,0, ${brightness * 0.6})`} />
66+
<stop offset="100%" stopColor={`rgba(255,69,0, ${brightness * 0.3})`} />
67+
</linearGradient>
68+
<linearGradient id="innerFlameGradient" x1="0%" y1="0%" x2="0%" y2="100%">
69+
<stop offset="0%" stopColor={`rgba(255,165,0, ${brightness * 0.8})`} />
70+
<stop offset="100%" stopColor={`rgba(255,99,71, ${brightness * 0.5})`} />
71+
</linearGradient>
72+
<filter id="flameBlur">
73+
<feGaussianBlur stdDeviation="7" />
74+
</filter>
75+
<filter id="innerGlow">
76+
<feGaussianBlur stdDeviation="4" result="coloredBlur" />
77+
<feMerge>
78+
<feMergeNode in="coloredBlur" />
79+
<feMergeNode in="SourceGraphic" />
80+
</feMerge>
81+
</filter>
82+
</defs>
83+
<path
84+
d={generateFlamePath()}
85+
fill="url(#outerFlameGradient)"
86+
filter="url(#flameBlur)"
87+
className="transition-all duration-300 animate-flicker opacity-70"
88+
/>
89+
<path
90+
d={generateFlamePath()}
91+
fill="url(#innerFlameGradient)"
92+
filter="url(#innerGlow)"
93+
className="transition-all duration-300 animate-flicker"
94+
/>
95+
</svg>
96+
</div>
97+
98+
{/* Candle should take up approximately 40% of the total height */}
99+
<div style={{ height: '80%' }} className="w-full bg-gradient-to-b from-gray-100 to-gray-200 dark:from-stone-600 dark:to-stone-700 rounded-t-md backdrop-blur-md shadow-xl relative">
100+
<div className="absolute inset-0 overflow-hidden rounded-t-md bg-gradient-to-b from-cyan-300 via-blue-400 to-gray-900">
101+
<div className={`absolute inset-0 ${
102+
isFullPage
103+
? 'flex flex-row justify-center items-center'
104+
: 'flex items-center justify-center'
105+
}`}
106+
>
107+
<div className="text-xs sm:text-sm md:text-lg lg:text-xl xl:text-2xl font-semibold text-gray-800 px-1 sm:px-2 md:px-3 py-1">
108+
{Number.isFinite(betaPower) ? String(Math.floor(betaPower)).padStart(2, '0') : '00'}
109+
</div>
92110
</div>
93111
</div>
94-
112+
<div className="absolute inset-0 bg-white/10 opacity-40 rounded-b-xl rounded-t-md"></div>
95113
</div>
96114
</div>
97115
</div>
98116
</div>
99117
);
100118
};
101119

102-
export default BrightCandleView;
120+
export default BrightCandleView;

src/components/FFT.tsx

Lines changed: 56 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -376,53 +376,41 @@ const FFT = forwardRef(
376376
const canvas = canvasRef.current;
377377
const container = containerRef.current;
378378
if (!canvas || !container) return;
379-
379+
380380
const ctx = canvas.getContext("2d");
381381
if (!ctx) return;
382-
383-
const containerWidth = container.clientWidth;
384-
const containerHeight = Math.min(containerWidth * 0.6, 500);
385-
canvas.width = containerWidth;
386-
canvas.height = containerHeight;
387-
388-
const width = canvas.width;
382+
383+
canvas.width = container.clientWidth;
384+
canvas.height = container.clientHeight;
385+
386+
const width = canvas.width - 20;
389387
const height = canvas.height;
390-
391-
ctx.clearRect(0, 0, width, height);
392-
393-
// Unified padding and spacing logic
394-
const padding = Math.min(width, height) * 0.08;
395-
const yAxisLabelOffset = 30;
396-
const leftMargin = padding + yAxisLabelOffset + 20;
397-
const rightMargin = padding;
398-
const topMargin = padding;
399-
const bottomMargin = padding + 40;
400-
401-
// Axis color and font setup
388+
389+
const leftMargin = 90;
390+
const bottomMargin = 50;
391+
const topMargin = 30; // added top margin
392+
393+
ctx.clearRect(0, 0, canvas.width, height);
394+
402395
const axisColor = theme === "dark" ? "white" : "black";
403-
const fontSize = width < 640 ? 12 : width < 768 ? 14 : width < 1024 ? 16 : 18;
404-
const labelFont = `${fontSize}px Arial`;
405-
const titleFont = `${fontSize + 2}px Arial`;
406-
407-
ctx.strokeStyle = axisColor;
408-
ctx.fillStyle = axisColor;
409-
ctx.font = labelFont;
410-
411-
// Draw axes
396+
412397
ctx.beginPath();
413-
ctx.moveTo(leftMargin, topMargin);
398+
ctx.moveTo(leftMargin, topMargin); // use topMargin
414399
ctx.lineTo(leftMargin, height - bottomMargin);
415-
ctx.lineTo(width - rightMargin, height - bottomMargin);
400+
ctx.lineTo(width - 10, height - bottomMargin);
401+
ctx.strokeStyle = axisColor;
416402
ctx.stroke();
417-
403+
418404
const freqStep = currentSamplingRate / fftSize;
419405
const displayPoints = Math.min(Math.ceil(maxFreq / freqStep), fftSize / 2);
420-
const xScale = (width - leftMargin - rightMargin) / displayPoints;
421-
422-
let yMax = Math.max(...fftData.flat(), 1);
423-
const yScale = (height - topMargin - bottomMargin) / yMax;
424-
425-
// Plot lines
406+
407+
const xScale = (width - leftMargin - 10) / displayPoints;
408+
409+
let yMax = 1; // Default to prevent division by zero
410+
yMax = Math.max(...fftData.flat());
411+
412+
const yScale = (height - bottomMargin - topMargin) / yMax;
413+
426414
fftData.forEach((channelData, index) => {
427415
ctx.beginPath();
428416
ctx.strokeStyle = channelColors[index];
@@ -433,46 +421,49 @@ const FFT = forwardRef(
433421
}
434422
ctx.stroke();
435423
});
436-
437-
// Y-axis labels
424+
425+
ctx.fillStyle = axisColor;
426+
ctx.font = "12px Arial";
427+
438428
ctx.textAlign = "right";
439429
ctx.textBaseline = "middle";
440-
const yTicks = 5;
441-
for (let i = 0; i <= yTicks; i++) {
442-
const value = (yMax * i) / yTicks;
443-
const labelY = height - bottomMargin - (i / yTicks) * (height - topMargin - bottomMargin);
444-
ctx.fillText(value.toFixed(2), leftMargin - 10, labelY);
430+
for (let i = 0; i <= 5; i++) {
431+
const labelY = height - bottomMargin - (i / 5) * (height - bottomMargin - topMargin);
432+
ctx.fillText(((yMax * i) / 5).toFixed(3), leftMargin - 10, labelY);
445433
}
446-
447-
// X-axis labels (Frequency)
434+
448435
ctx.textAlign = "center";
449436
ctx.textBaseline = "top";
450-
const minLabelSpacing = fontSize * 4;
451-
const labelFreqStep = Math.ceil((minLabelSpacing / xScale) / 10) * 10;
452-
const maxFreqToLabel = Math.floor(Math.min(maxFreq, currentSamplingRate / 2));
453-
454-
for (let freq = 0; freq <= maxFreqToLabel; freq += labelFreqStep) {
437+
const numLabels = Math.min(maxFreq / 10, Math.floor(currentSamplingRate / 2 / 10));
438+
let lastLabelX = -Infinity;
439+
const labelSpacing = 50; // Increased spacing
440+
441+
for (let i = 0; i <= numLabels; i++) {
442+
const freq = i * 10;
455443
const labelX = leftMargin + (freq / freqStep) * xScale;
456-
ctx.fillText(freq.toString(), labelX, height - bottomMargin + 5);
444+
445+
// Only draw label if it is far enough from the last one
446+
if (labelX - lastLabelX >= labelSpacing) {
447+
ctx.fillText(freq.toString(), labelX, height - bottomMargin + 10); // Moved label further up
448+
lastLabelX = labelX;
449+
}
457450
}
458-
459-
// X-axis title
460-
ctx.font = titleFont;
451+
452+
ctx.font = "14px Arial";
461453
ctx.textAlign = "center";
462-
ctx.textBaseline = "top";
463-
ctx.fillText("Frequency (Hz)", width / 2, height - padding * 0.9);
464-
465-
// Y-axis title
454+
ctx.textBaseline = "bottom";
455+
ctx.fillText("Frequency (Hz)", (width + leftMargin) / 2, height - 10);
456+
466457
ctx.save();
467458
ctx.rotate(-Math.PI / 2);
468-
ctx.font = titleFont;
459+
ctx.font = "14px Arial";
469460
ctx.textAlign = "center";
470-
ctx.textBaseline = "bottom";
471-
ctx.fillText("Magnitude", -height / 2, padding);
461+
ctx.textBaseline = "top";
462+
ctx.fillText("Magnitude", -height / 2, topMargin - 5);
472463
ctx.restore();
473464
}, [fftData, theme, maxFreq, currentSamplingRate, fftSize, channelColors]);
474-
475-
465+
466+
476467
useEffect(() => {
477468
if (fftData.some((channel) => channel.length > 0)) {
478469
plotData();

0 commit comments

Comments
 (0)