a
This commit is contained in:
parent
899b5f57c2
commit
199317d0c6
BIN
golden-ticket.png
Normal file
BIN
golden-ticket.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 614 KiB |
BIN
result-remade.png
Normal file
BIN
result-remade.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 319 KiB |
BIN
result.png
Normal file
BIN
result.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 MiB |
11
src/App.jsx
11
src/App.jsx
@ -3,6 +3,7 @@ import { useLuckyDraw } from './hooks/useLuckyDraw';
|
|||||||
import { SlotMachine } from './components/SlotMachine';
|
import { SlotMachine } from './components/SlotMachine';
|
||||||
import { HistoryPanel } from './components/HistoryPanel';
|
import { HistoryPanel } from './components/HistoryPanel';
|
||||||
import { WinnerModal } from './components/WinnerModal';
|
import { WinnerModal } from './components/WinnerModal';
|
||||||
|
import { SparkleEffect } from './components/SparkleEffect';
|
||||||
import { Sparkles } from 'lucide-react';
|
import { Sparkles } from 'lucide-react';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@ -109,6 +110,16 @@ function App() {
|
|||||||
onDraw={handleDraw}
|
onDraw={handleDraw}
|
||||||
poolLength={pool.length}
|
poolLength={pool.length}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Left Sparkles - Absolute positioned next to slot machine */}
|
||||||
|
<div className="absolute left-0 top-1/2 -translate-y-1/2 -translate-x-[calc(100%+20px)] w-[350px] h-[600px] pointer-events-none overflow-visible">
|
||||||
|
<SparkleEffect />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Right Sparkles - Absolute positioned next to slot machine */}
|
||||||
|
<div className="absolute right-0 top-1/2 -translate-y-1/2 translate-x-[calc(100%+20px)] w-[350px] h-[600px] pointer-events-none overflow-visible">
|
||||||
|
<SparkleEffect />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
132
src/components/SparkleEffect.jsx
Normal file
132
src/components/SparkleEffect.jsx
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to generate random number within a range
|
||||||
|
*/
|
||||||
|
const random = (min, max) => Math.random() * (max - min) + min;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component: Star
|
||||||
|
* Renders a 4-pointed glowing star (lens flare style)
|
||||||
|
*/
|
||||||
|
const Star = ({ style }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="absolute flex items-center justify-center mix-blend-screen pointer-events-none"
|
||||||
|
style={{
|
||||||
|
...style,
|
||||||
|
animationName: 'twinkle',
|
||||||
|
animationTimingFunction: 'ease-in-out',
|
||||||
|
animationIterationCount: 'infinite',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* The Glow Center - Bright Core */}
|
||||||
|
<div className="absolute w-[10%] h-[10%] bg-white rounded-full shadow-[0_0_20px_5px_rgba(255,255,255,1),0_0_50px_20px_rgba(253,224,71,0.8)] z-20" />
|
||||||
|
|
||||||
|
{/* Vertical Ray - Sharp White Core */}
|
||||||
|
<div className="absolute w-[2px] h-full bg-gradient-to-b from-transparent via-white to-transparent opacity-100 z-10" />
|
||||||
|
{/* Vertical Ray - Gold Glow */}
|
||||||
|
<div className="absolute w-[6px] h-full bg-gradient-to-b from-transparent via-yellow-200 to-transparent opacity-60 blur-[2px]" />
|
||||||
|
|
||||||
|
{/* Horizontal Ray - Sharp White Core */}
|
||||||
|
<div className="absolute h-[2px] w-full bg-gradient-to-r from-transparent via-white to-transparent opacity-100 z-10" />
|
||||||
|
{/* Horizontal Ray - Gold Glow */}
|
||||||
|
<div className="absolute h-[6px] w-full bg-gradient-to-r from-transparent via-yellow-200 to-transparent opacity-60 blur-[2px]" />
|
||||||
|
|
||||||
|
{/* Diffuse Halo */}
|
||||||
|
<div className="absolute w-[70%] h-[70%] bg-amber-500/40 rounded-full blur-2xl" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component: Particle
|
||||||
|
* Renders tiny background dust/bokeh circles
|
||||||
|
*/
|
||||||
|
const Particle = ({ style }) => (
|
||||||
|
<div
|
||||||
|
className="absolute rounded-full bg-yellow-50 mix-blend-screen"
|
||||||
|
style={{
|
||||||
|
...style,
|
||||||
|
animationName: 'pulse',
|
||||||
|
animationTimingFunction: 'ease-in-out',
|
||||||
|
animationIterationCount: 'infinite',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
export function SparkleEffect() {
|
||||||
|
const [stars, setStars] = useState([]);
|
||||||
|
const [particles, setParticles] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Generate Stars (The big cross flares) - spread across entire area
|
||||||
|
const starCount = 40; // Increased from 25
|
||||||
|
const newStars = Array.from({ length: starCount }).map((_, i) => {
|
||||||
|
return {
|
||||||
|
id: i,
|
||||||
|
style: {
|
||||||
|
left: `${random(0, 100)}%`,
|
||||||
|
top: `${random(0, 100)}%`,
|
||||||
|
width: `${random(50, 150)}px`,
|
||||||
|
height: `${random(50, 150)}px`,
|
||||||
|
animationDuration: `${random(1.5, 4)}s`,
|
||||||
|
animationDelay: `${random(0, 4)}s`,
|
||||||
|
opacity: random(0.6, 1),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Generate Particles (The small bokeh dots) - spread across entire area
|
||||||
|
const particleCount = 100; // Increased from 60
|
||||||
|
const newParticles = Array.from({ length: particleCount }).map((_, i) => {
|
||||||
|
return {
|
||||||
|
id: i,
|
||||||
|
style: {
|
||||||
|
left: `${random(0, 100)}%`,
|
||||||
|
top: `${random(0, 100)}%`,
|
||||||
|
width: `${random(2, 5)}px`,
|
||||||
|
height: `${random(2, 5)}px`,
|
||||||
|
opacity: random(0.3, 0.8),
|
||||||
|
boxShadow: `0 0 ${random(3, 6)}px rgba(255, 255, 220, 0.8)`,
|
||||||
|
animationDuration: `${random(1, 3)}s`,
|
||||||
|
animationDelay: `${random(0, 5)}s`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
setStars(newStars);
|
||||||
|
setParticles(newParticles);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="absolute inset-0 pointer-events-none">
|
||||||
|
{/* Custom Keyframes */}
|
||||||
|
<style>{`
|
||||||
|
@keyframes twinkle {
|
||||||
|
0% { transform: scale(0.3) rotate(0deg); opacity: 0; }
|
||||||
|
50% { transform: scale(1.2) rotate(15deg); opacity: 1; filter: brightness(2.5); }
|
||||||
|
100% { transform: scale(0.3) rotate(0deg); opacity: 0; }
|
||||||
|
}
|
||||||
|
@keyframes pulse {
|
||||||
|
0%, 100% { opacity: 0.2; transform: scale(0.5); }
|
||||||
|
50% { opacity: 1; transform: scale(1.3); filter: brightness(1.5); }
|
||||||
|
}
|
||||||
|
`}</style>
|
||||||
|
|
||||||
|
{/* Render Stars (Big cross flares) */}
|
||||||
|
<div className="absolute inset-0 z-10">
|
||||||
|
{stars.map((s) => (
|
||||||
|
<Star key={s.id} style={s.style} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Render Particles (Small dots) */}
|
||||||
|
<div className="absolute inset-0 z-0">
|
||||||
|
{particles.map((p) => (
|
||||||
|
<Particle key={p.id} style={p.style} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user