59 lines
1.9 KiB
TypeScript
59 lines
1.9 KiB
TypeScript
|
|
import React from "react";
|
||
|
|
import "./RightVisual.less";
|
||
|
|
|
||
|
|
export default function RightVisual() {
|
||
|
|
const BAR_COUNT = 48;
|
||
|
|
|
||
|
|
// Calculate a Gaussian envelope for the soundwave so the center is tallest
|
||
|
|
const getEnvelope = (i: number) => {
|
||
|
|
const center = BAR_COUNT / 2;
|
||
|
|
const x = (i - center) / (center * 0.8);
|
||
|
|
// Gaussian bell curve
|
||
|
|
const envelope = Math.exp(-Math.pow(x, 2));
|
||
|
|
return Math.max(0.05, envelope);
|
||
|
|
};
|
||
|
|
|
||
|
|
// Deterministic pseudo-random duration for a more organic, less rigid feel
|
||
|
|
const getDuration = (i: number) => {
|
||
|
|
return 0.9 + (Math.sin(i * 76543) * 0.5 + 0.5) * 0.6; // between 0.9s and 1.5s
|
||
|
|
};
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="home-right-visual" aria-hidden="true">
|
||
|
|
{/* Soundwave Animation */}
|
||
|
|
<div className="home-right-visual__soundwave">
|
||
|
|
{Array.from({ length: BAR_COUNT }).map((_, i) => {
|
||
|
|
const envelope = getEnvelope(i);
|
||
|
|
const duration = getDuration(i);
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
key={i}
|
||
|
|
className="home-right-visual__bar"
|
||
|
|
style={{
|
||
|
|
"--index": i,
|
||
|
|
"--envelope": envelope,
|
||
|
|
"--duration": `${duration}s`,
|
||
|
|
} as React.CSSProperties}
|
||
|
|
/>
|
||
|
|
);
|
||
|
|
})}
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Floating Glass Droplets for ambient feel */}
|
||
|
|
<div className="home-right-visual__drop home-right-visual__drop--1">
|
||
|
|
<div className="home-right-visual__drop-inner" />
|
||
|
|
</div>
|
||
|
|
<div className="home-right-visual__drop home-right-visual__drop--2">
|
||
|
|
<div className="home-right-visual__drop-inner" />
|
||
|
|
</div>
|
||
|
|
<div className="home-right-visual__drop home-right-visual__drop--3">
|
||
|
|
<div className="home-right-visual__drop-inner" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
{/* Light Glare / Glows */}
|
||
|
|
<div className="home-right-visual__glow home-right-visual__glow--main" />
|
||
|
|
<div className="home-right-visual__glow home-right-visual__glow--secondary" />
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|