feat: replace animated backgrounds with Aceternity UI system

- Add 16 animated background components (aurora, sparkles, vortex, shooting-stars,
  beams, beams-collision, gradient-animation, wavy, lines, boxes, meteors, grid,
  dots, spotlight, noise, ripple, gemini-effect)
- Add full admin BackgroundEditor with live preview, type gallery, per-type settings
- Add BackgroundRenderer with lazy loading, localStorage cache, mobile reduction
- Add input sanitization (sanitizeColor, clampNumber) across all components
- Add translations for en, ru, zh, fa locales
- Remove old Aurora (WebGL/OGL) and AnimatedBackground (CSS wave-blob)
- Remove ogl dependency, add simplex-noise
This commit is contained in:
Fringg
2026-02-25 07:12:59 +03:00
parent 78e70992f1
commit 1a702a68b9
35 changed files with 2919 additions and 653 deletions

View File

@@ -0,0 +1,56 @@
import { useMemo } from 'react';
import { motion } from 'framer-motion';
import { sanitizeColor, clampNumber } from './types';
interface Props {
settings: Record<string, unknown>;
}
export default function BackgroundBoxes({ settings }: Props) {
const rows = clampNumber(settings.rows, 2, 30, 12);
const cols = clampNumber(settings.cols, 2, 30, 12);
const boxColor = sanitizeColor(settings.boxColor, '#818cf8');
const boxes = useMemo(() => {
const result: { row: number; col: number; color: string }[] = [];
for (let r = 0; r < rows; r++) {
for (let c = 0; c < cols; c++) {
result.push({ row: r, col: c, color: boxColor });
}
}
return result;
}, [rows, cols, boxColor]);
return (
<div className="absolute inset-0 overflow-hidden">
<div
className="absolute inset-0"
style={{
display: 'grid',
gridTemplateRows: `repeat(${rows}, 1fr)`,
gridTemplateColumns: `repeat(${cols}, 1fr)`,
transform: 'skewX(-48deg) skewY(14deg) scale(0.675) translateX(10%)',
transformOrigin: 'center center',
}}
>
{boxes.map((box, i) => (
<motion.div
key={i}
className="border border-white/5"
initial={{ opacity: 0 }}
animate={{
opacity: [0, 0.08, 0],
}}
transition={{
duration: 3 + Math.random() * 4,
delay: Math.random() * 5,
repeat: Infinity,
ease: 'easeInOut',
}}
style={{ backgroundColor: box.color }}
/>
))}
</div>
</div>
);
}