зеркало из
https://github.com/kodackx/disinformation-quest.git
synced 2025-10-29 12:46:03 +02:00
Revamp Meme Animation
Updated the meme animation to better communicate the underlying idea of the stratagem. Adjustments made to enhance clarity and effectiveness in conveying the intended message. [skip gpt_engineer]
Этот коммит содержится в:
родитель
cf19dd256d
Коммит
0064ce4117
@ -6,67 +6,139 @@ interface MemeSymbol {
|
|||||||
symbol: string;
|
symbol: string;
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
rotation: number;
|
|
||||||
scale: number;
|
scale: number;
|
||||||
|
delay: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MemeAnimation = ({ className = '' }: { className?: string }) => {
|
export const MemeAnimation = ({ className = '' }: { className?: string }) => {
|
||||||
const createWave = (waveIndex: number) => {
|
// Create a grid of starting positions
|
||||||
return Array.from({ length: 6 }, (_, i) => {
|
const createMemeWave = () => {
|
||||||
const symbols = ['😂', '🤔', '💭', '🎯', '🔥', '💯', '👀', '🙌', '✨', '💪'];
|
const memes: MemeSymbol[] = [];
|
||||||
const x = 5 + (i * (90 / 5));
|
const symbols = ['💡', '🎯', '📱', '🔄', '🌐', '💫'];
|
||||||
return {
|
|
||||||
id: waveIndex * 6 + i,
|
// Create a 3x3 grid of meme symbols
|
||||||
symbol: symbols[Math.floor(Math.random() * symbols.length)],
|
for (let row = 0; row < 3; row++) {
|
||||||
x,
|
for (let col = 0; col < 3; col++) {
|
||||||
y: 120 + (waveIndex * 60),
|
const baseSymbol = symbols[Math.floor(Math.random() * symbols.length)];
|
||||||
rotation: -10 + Math.random() * 20,
|
memes.push({
|
||||||
scale: 0.8 + Math.random() * 0.4,
|
id: row * 3 + col,
|
||||||
};
|
symbol: baseSymbol,
|
||||||
});
|
x: 20 + (col * 30), // Spread across horizontally
|
||||||
|
y: 20 + (row * 30), // Spread across vertically
|
||||||
|
scale: 0.8 + Math.random() * 0.4,
|
||||||
|
delay: (row * 3 + col) * 0.15 // Stagger the animations
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return memes;
|
||||||
};
|
};
|
||||||
|
|
||||||
const memeSymbols: MemeSymbol[] = [
|
const memeSymbols = createMemeWave();
|
||||||
...createWave(0),
|
|
||||||
...createWave(1),
|
|
||||||
...createWave(2),
|
|
||||||
...createWave(3),
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`relative w-full h-40 overflow-hidden bg-black/20 rounded-lg ${className}`}>
|
<div className={`relative w-full h-40 overflow-hidden bg-black/20 rounded-lg ${className}`}>
|
||||||
|
{/* Background network effect */}
|
||||||
|
<div className="absolute inset-0 opacity-20">
|
||||||
|
{[...Array(20)].map((_, i) => (
|
||||||
|
<div
|
||||||
|
key={`line-${i}`}
|
||||||
|
className="absolute h-px bg-yellow-500"
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
top: `${Math.random() * 100}%`,
|
||||||
|
transform: `rotate(${Math.random() * 360}deg)`,
|
||||||
|
opacity: 0.3
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Meme symbols with viral spread effect */}
|
||||||
{memeSymbols.map((meme) => (
|
{memeSymbols.map((meme) => (
|
||||||
<motion.div
|
<motion.div
|
||||||
key={meme.id}
|
key={meme.id}
|
||||||
className="absolute text-2xl select-none"
|
className="absolute text-2xl select-none"
|
||||||
style={{
|
|
||||||
transform: 'translate(-50%, -50%)',
|
|
||||||
willChange: 'transform',
|
|
||||||
}}
|
|
||||||
initial={{
|
initial={{
|
||||||
x: `${meme.x}%`,
|
x: `${meme.x}%`,
|
||||||
y: `${meme.y}%`,
|
y: `${meme.y}%`,
|
||||||
rotate: meme.rotation,
|
scale: 0,
|
||||||
scale: meme.scale,
|
opacity: 0
|
||||||
opacity: 0,
|
|
||||||
}}
|
}}
|
||||||
animate={{
|
animate={[
|
||||||
y: [`${meme.y}%`, '-20%'],
|
// First appear and pulse
|
||||||
rotate: meme.rotation,
|
{
|
||||||
scale: meme.scale,
|
scale: meme.scale,
|
||||||
opacity: [0, 1, 1, 0],
|
opacity: 1,
|
||||||
}}
|
transition: {
|
||||||
transition={{
|
delay: meme.delay,
|
||||||
duration: 6,
|
duration: 0.3
|
||||||
repeat: Infinity,
|
}
|
||||||
ease: "easeInOut",
|
},
|
||||||
opacity: {
|
// Then spread out with copies
|
||||||
times: [0, 0.1, 0.9, 1],
|
{
|
||||||
duration: 6,
|
x: [
|
||||||
|
`${meme.x}%`,
|
||||||
|
`${meme.x + (Math.random() * 40 - 20)}%`,
|
||||||
|
`${meme.x + (Math.random() * 60 - 30)}%`
|
||||||
|
],
|
||||||
|
y: [
|
||||||
|
`${meme.y}%`,
|
||||||
|
`${meme.y + (Math.random() * 40 - 20)}%`,
|
||||||
|
`${meme.y + (Math.random() * 60 - 30)}%`
|
||||||
|
],
|
||||||
|
transition: {
|
||||||
|
delay: meme.delay + 0.3,
|
||||||
|
duration: 2,
|
||||||
|
repeat: Infinity,
|
||||||
|
repeatType: "reverse",
|
||||||
|
ease: "easeInOut"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
]}
|
||||||
>
|
>
|
||||||
{meme.symbol}
|
{meme.symbol}
|
||||||
|
|
||||||
|
{/* Echo effect for viral spread visualization */}
|
||||||
|
<motion.div
|
||||||
|
className="absolute inset-0 text-yellow-500"
|
||||||
|
initial={{ scale: 1, opacity: 0 }}
|
||||||
|
animate={{
|
||||||
|
scale: [1, 1.5, 2],
|
||||||
|
opacity: [0.5, 0.2, 0],
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration: 1.5,
|
||||||
|
repeat: Infinity,
|
||||||
|
delay: meme.delay + 0.5
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{meme.symbol}
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Floating engagement indicators */}
|
||||||
|
{[...Array(5)].map((_, i) => (
|
||||||
|
<motion.div
|
||||||
|
key={`indicator-${i}`}
|
||||||
|
className="absolute text-sm text-yellow-500/70"
|
||||||
|
initial={{
|
||||||
|
x: `${Math.random() * 100}%`,
|
||||||
|
y: '100%',
|
||||||
|
opacity: 0
|
||||||
|
}}
|
||||||
|
animate={{
|
||||||
|
y: '-20%',
|
||||||
|
opacity: [0, 1, 0],
|
||||||
|
}}
|
||||||
|
transition={{
|
||||||
|
duration: 2,
|
||||||
|
repeat: Infinity,
|
||||||
|
delay: i * 0.5,
|
||||||
|
ease: "linear"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{['🔁', '❤️', '⭐'][Math.floor(Math.random() * 3)]}
|
||||||
</motion.div>
|
</motion.div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Загрузка…
x
Ссылка в новой задаче
Block a user