168 lines
5.2 KiB
TypeScript
168 lines
5.2 KiB
TypeScript
interface Candle {
|
|
id: number
|
|
x: number
|
|
y: number
|
|
open: number
|
|
close: number
|
|
high: number
|
|
low: number
|
|
delay: number
|
|
duration: number
|
|
}
|
|
|
|
// Generate static candlesticks once
|
|
const generateCandles = (): Candle[] => {
|
|
const newCandles: Candle[] = []
|
|
const numCandles = 15
|
|
|
|
for (let i = 0; i < numCandles; i++) {
|
|
const open = Math.random() * 60 + 20
|
|
const movement = (Math.random() - 0.5) * 40
|
|
const close = open + movement
|
|
const high = Math.max(open, close) + Math.random() * 20
|
|
const low = Math.min(open, close) - Math.random() * 20
|
|
|
|
newCandles.push({
|
|
id: i,
|
|
x: Math.random() * 100,
|
|
y: Math.random() * 100,
|
|
open,
|
|
close,
|
|
high,
|
|
low,
|
|
delay: Math.random() * 5,
|
|
duration: 8 + Math.random() * 4,
|
|
})
|
|
}
|
|
return newCandles
|
|
}
|
|
|
|
const CANDLES = generateCandles()
|
|
|
|
const TradingBackground = () => {
|
|
|
|
return (
|
|
<div className="absolute inset-0 overflow-hidden pointer-events-none">
|
|
<svg className="w-full h-full" viewBox="0 0 100 100" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<linearGradient id="bullishGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
<stop offset="0%" stopColor="rgba(16, 185, 129, 0.5)" />
|
|
<stop offset="100%" stopColor="rgba(16, 185, 129, 0.2)" />
|
|
</linearGradient>
|
|
<linearGradient id="bearishGradient" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
<stop offset="0%" stopColor="rgba(239, 68, 68, 0.5)" />
|
|
<stop offset="100%" stopColor="rgba(239, 68, 68, 0.2)" />
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
{CANDLES.map((candle) => {
|
|
const isBullish = candle.close > candle.open
|
|
const color = isBullish ? 'url(#bullishGradient)' : 'url(#bearishGradient)'
|
|
const strokeColor = isBullish ? 'rgba(16, 185, 129, 0.6)' : 'rgba(239, 68, 68, 0.6)'
|
|
|
|
const bodyTop = Math.min(candle.open, candle.close)
|
|
const bodyHeight = Math.abs(candle.close - candle.open)
|
|
const bodyWidth = 1.5
|
|
|
|
return (
|
|
<g
|
|
key={candle.id}
|
|
className="animate-pulse"
|
|
style={{
|
|
animationDelay: `${candle.delay}s`,
|
|
animationDuration: `${candle.duration}s`,
|
|
}}
|
|
>
|
|
{/* High-Low line (wick) */}
|
|
<line
|
|
x1={candle.x}
|
|
y1={candle.y - (candle.high - candle.close) / 3}
|
|
x2={candle.x}
|
|
y2={candle.y + (candle.close - candle.low) / 3}
|
|
stroke={strokeColor}
|
|
strokeWidth="0.3"
|
|
/>
|
|
|
|
{/* Candle body */}
|
|
<rect
|
|
x={candle.x - bodyWidth / 2}
|
|
y={candle.y - (bodyTop - candle.close) / 3}
|
|
width={bodyWidth}
|
|
height={bodyHeight / 3}
|
|
fill={color}
|
|
stroke={strokeColor}
|
|
strokeWidth="0.15"
|
|
rx="0.15"
|
|
/>
|
|
</g>
|
|
)
|
|
})}
|
|
|
|
{/* Animated trend lines - now spanning full width */}
|
|
<g className="animate-pulse" style={{ animationDuration: '6s' }}>
|
|
<path
|
|
d="M 0,30 Q 25,15 50,20 T 100,10"
|
|
stroke="rgba(96, 165, 250, 0.4)"
|
|
strokeWidth="0.5"
|
|
fill="none"
|
|
strokeDasharray="3,3"
|
|
vectorEffect="non-scaling-stroke"
|
|
>
|
|
<animate
|
|
attributeName="stroke-dashoffset"
|
|
from="0"
|
|
to="6"
|
|
dur="3s"
|
|
repeatCount="indefinite"
|
|
/>
|
|
</path>
|
|
</g>
|
|
|
|
<g className="animate-pulse" style={{ animationDuration: '8s', animationDelay: '1s' }}>
|
|
<path
|
|
d="M 0,70 Q 25,85 50,80 T 100,95"
|
|
stroke="rgba(168, 85, 247, 0.4)"
|
|
strokeWidth="0.5"
|
|
fill="none"
|
|
strokeDasharray="3,3"
|
|
vectorEffect="non-scaling-stroke"
|
|
>
|
|
<animate
|
|
attributeName="stroke-dashoffset"
|
|
from="0"
|
|
to="6"
|
|
dur="3s"
|
|
repeatCount="indefinite"
|
|
/>
|
|
</path>
|
|
</g>
|
|
|
|
<g className="animate-pulse" style={{ animationDuration: '7s', animationDelay: '0.5s' }}>
|
|
<path
|
|
d="M 0,50 Q 30,40 60,45 Q 80,50 100,55"
|
|
stroke="rgba(59, 130, 246, 0.35)"
|
|
strokeWidth="0.4"
|
|
fill="none"
|
|
strokeDasharray="2.5,2.5"
|
|
vectorEffect="non-scaling-stroke"
|
|
>
|
|
<animate
|
|
attributeName="stroke-dashoffset"
|
|
from="0"
|
|
to="5"
|
|
dur="4s"
|
|
repeatCount="indefinite"
|
|
/>
|
|
</path>
|
|
</g>
|
|
</svg>
|
|
|
|
{/* Floating gradient orbs */}
|
|
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl animate-pulse" style={{ animationDuration: '8s' }}></div>
|
|
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-purple-500/10 rounded-full blur-3xl animate-pulse" style={{ animationDuration: '10s', animationDelay: '2s' }}></div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default TradingBackground
|