update ai commerce section
This commit is contained in:
66
src/components/home/voice/VoiceWaves.tsx
Normal file
66
src/components/home/voice/VoiceWaves.tsx
Normal file
@@ -0,0 +1,66 @@
|
||||
"use client";
|
||||
|
||||
import { motion, useReducedMotion } from "framer-motion";
|
||||
|
||||
// A 2400-wide path holding six 400px periods. Sliding it exactly -1200
|
||||
// (three periods) loops seamlessly, so the drift never visibly restarts.
|
||||
const WAVE =
|
||||
"M0 150 Q100 80 200 150 T400 150 T600 150 T800 150 T1000 150 T1200 150 T1400 150 T1600 150 T1800 150 T2000 150 T2200 150 T2400 150";
|
||||
|
||||
const LAYERS = [
|
||||
{ y: 0, scaleY: 1, opacity: 0.18, duration: 12, width: 2 },
|
||||
{ y: 26, scaleY: 0.62, opacity: 0.13, duration: 16, width: 1.5 },
|
||||
{ y: -22, scaleY: 1.35, opacity: 0.1, duration: 21, width: 1.5 },
|
||||
];
|
||||
|
||||
// Elegant voice waves behind the phone. Purely decorative, low opacity, and
|
||||
// animated on transform only — it should reinforce "this is voice" without
|
||||
// ever pulling attention off the screen.
|
||||
export function VoiceWaves({ className = "" }: { className?: string }) {
|
||||
const reduced = useReducedMotion();
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className={`pointer-events-none absolute inset-0 overflow-hidden ${className}`}
|
||||
style={{
|
||||
maskImage: "radial-gradient(60% 55% at 50% 50%, #000 35%, transparent 100%)",
|
||||
WebkitMaskImage: "radial-gradient(60% 55% at 50% 50%, #000 35%, transparent 100%)",
|
||||
}}
|
||||
>
|
||||
{LAYERS.map((layer, i) => (
|
||||
<motion.svg
|
||||
key={i}
|
||||
viewBox="0 0 2400 300"
|
||||
preserveAspectRatio="none"
|
||||
className="absolute left-1/2 top-1/2 h-[52%] w-[200%]"
|
||||
style={{
|
||||
x: "-50%",
|
||||
y: `calc(-50% + ${layer.y}px)`,
|
||||
opacity: layer.opacity,
|
||||
}}
|
||||
animate={reduced ? undefined : { translateX: ["0%", "-25%"] }}
|
||||
transition={{ duration: layer.duration, repeat: Infinity, ease: "linear" }}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={`voice-wave-${i}`} x1="0" y1="0" x2="1" y2="0">
|
||||
<stop offset="0%" stopColor="#7C3AED" stopOpacity="0" />
|
||||
<stop offset="35%" stopColor="#A855F7" stopOpacity="1" />
|
||||
<stop offset="65%" stopColor="#C084FC" stopOpacity="1" />
|
||||
<stop offset="100%" stopColor="#7C3AED" stopOpacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
d={WAVE}
|
||||
fill="none"
|
||||
stroke={`url(#voice-wave-${i})`}
|
||||
strokeWidth={layer.width}
|
||||
strokeLinecap="round"
|
||||
vectorEffect="non-scaling-stroke"
|
||||
transform={`translate(0 ${150 - 150 * layer.scaleY}) scale(1 ${layer.scaleY})`}
|
||||
/>
|
||||
</motion.svg>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user