This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,159 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useTheme } from '../hooks/useTheme';
|
||||||
|
|
||||||
|
export const AnimatedSvgBackground: React.FC = () => {
|
||||||
|
const { isDark } = useTheme();
|
||||||
|
const [scrollY, setScrollY] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let ticking = false;
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
if (!ticking) {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
setScrollY(window.scrollY);
|
||||||
|
ticking = false;
|
||||||
|
});
|
||||||
|
ticking = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||||
|
return () => window.removeEventListener('scroll', handleScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Couleurs réactives selon le mode clair/sombre
|
||||||
|
const strokePrimary = isDark ? "rgba(59, 130, 246, 0.25)" : "rgba(37, 99, 235, 0.18)"; // Bleu Google
|
||||||
|
const strokeSuccess = isDark ? "rgba(16, 185, 129, 0.3)" : "rgba(16, 185, 129, 0.22)"; // Vert Émeraude
|
||||||
|
const strokeSubtle = isDark ? "rgba(148, 163, 184, 0.1)" : "rgba(100, 116, 139, 0.08)";
|
||||||
|
const fillGlow = isDark ? "rgba(59, 130, 246, 0.03)" : "rgba(37, 99, 235, 0.02)";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed inset-0 pointer-events-none z-0 overflow-hidden bg-[#f8f9fa] dark:bg-[#0f172a] transition-colors duration-500">
|
||||||
|
|
||||||
|
{/* ------------------------------------------------------------- */}
|
||||||
|
{/* COUCHE 1 : GRILLE TECHNIQUE & FLUX LENTS (Vitesse: -0.1x) */}
|
||||||
|
{/* ------------------------------------------------------------- */}
|
||||||
|
<svg
|
||||||
|
className="absolute inset-0 w-full h-[200vh] transition-transform duration-75 ease-out"
|
||||||
|
style={{ transform: `translateY(${scrollY * -0.1}px)` }}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<defs>
|
||||||
|
<pattern id="gise-grid" width="80" height="80" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M 80 0 L 0 0 0 80" fill="none" stroke={strokeSubtle} strokeWidth="1" />
|
||||||
|
<circle cx="80" cy="0" r="1.5" fill={strokePrimary} />
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<rect width="100%" height="100%" fill="url(#gise-grid)" />
|
||||||
|
|
||||||
|
{/* Lignes de flux de données sinusoïdales */}
|
||||||
|
<path
|
||||||
|
d="M -100 200 C 300 100, 600 500, 1200 300 T 2000 600"
|
||||||
|
fill="none"
|
||||||
|
stroke={strokePrimary}
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeDasharray="8 6"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M -100 800 C 400 600, 800 1100, 1500 900 T 2200 1200"
|
||||||
|
fill="none"
|
||||||
|
stroke={strokeSuccess}
|
||||||
|
strokeWidth="1.5"
|
||||||
|
strokeDasharray="12 8"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{/* ------------------------------------------------------------- */}
|
||||||
|
{/* COUCHE 2 : SYMBOLES CLÉS GISE (BOUCLIER, SERVEUR, CADENAS) */}
|
||||||
|
{/* Vitesse intermédiaire: -0.28x */}
|
||||||
|
{/* ------------------------------------------------------------- */}
|
||||||
|
<svg
|
||||||
|
className="absolute inset-0 w-full h-[250vh] transition-transform duration-75 ease-out"
|
||||||
|
style={{ transform: `translateY(${scrollY * -0.28}px)` }}
|
||||||
|
viewBox="0 0 1200 1800"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
|
||||||
|
{/* --- DESSIN 1 : LE BOUCLIER SOUVERAIN (AEGIS) en haut à droite --- */}
|
||||||
|
<g transform="translate(850, 120) scale(1.2)">
|
||||||
|
{/* Contour externe du Bouclier */}
|
||||||
|
<path
|
||||||
|
d="M100 20 L180 50 V120 C180 170 100 210 100 210 C100 210 20 170 20 120 V50 L100 20 Z"
|
||||||
|
stroke={strokePrimary}
|
||||||
|
strokeWidth="2.5"
|
||||||
|
fill={fillGlow}
|
||||||
|
/>
|
||||||
|
{/* Maillage interne Zero-Trust */}
|
||||||
|
<path d="M100 20 V210 M20 50 L180 120 M180 50 L20 120" stroke={strokePrimary} strokeWidth="1" />
|
||||||
|
<circle cx="100" cy="115" r="25" stroke={strokeSuccess} strokeWidth="2" fill="none" />
|
||||||
|
<circle cx="100" cy="115" r="6" fill={isDark ? "#10b981" : "#059669"} />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
{/* --- DESSIN 2 : BAIE DE SERVEURS (CLOUD BELGE) au milieu à gauche --- */}
|
||||||
|
<g transform="translate(80, 650) scale(0.9)">
|
||||||
|
{/* Armoire Serveur */}
|
||||||
|
<rect x="0" y="0" width="160" height="240" rx="16" stroke={strokePrimary} strokeWidth="2" fill={fillGlow} />
|
||||||
|
{/* Serveur Lame 1 */}
|
||||||
|
<rect x="15" y="20" width="130" height="35" rx="6" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
<circle cx="35" cy="37.5" r="3" fill={isDark ? "#10b981" : "#059669"} />
|
||||||
|
<line x1="55" y1="37.5" x2="125" y2="37.5" stroke={strokePrimary} strokeWidth="2" strokeDasharray="4 4" />
|
||||||
|
|
||||||
|
{/* Serveur Lame 2 */}
|
||||||
|
<rect x="15" y="70" width="130" height="35" rx="6" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
<circle cx="35" cy="87.5" r="3" fill={isDark ? "#3b82f6" : "#2563eb"} />
|
||||||
|
<line x1="55" y1="87.5" x2="125" y2="87.5" stroke={strokePrimary} strokeWidth="2" strokeDasharray="6 3" />
|
||||||
|
|
||||||
|
{/* Serveur Lame 3 */}
|
||||||
|
<rect x="15" y="120" width="130" height="35" rx="6" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
<circle cx="35" cy="137.5" r="3" fill={isDark ? "#10b981" : "#059669"} />
|
||||||
|
<line x1="55" y1="137.5" x2="125" y2="137.5" stroke={strokePrimary} strokeWidth="2" strokeDasharray="4 4" />
|
||||||
|
|
||||||
|
{/* Base & Connexion terre */}
|
||||||
|
<path d="M80 160 V220 M40 220 H120" stroke={strokeSuccess} strokeWidth="2" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
{/* --- DESSIN 3 : CADENAS DE SÉCURITÉ / VAULT en bas à droite --- */}
|
||||||
|
<g transform="translate(900, 1250) scale(1.1)">
|
||||||
|
{/* Anse du cadenas */}
|
||||||
|
<path d="M30 60 V35 C30 18 43 5 60 5 C77 5 90 18 90 35 V60" stroke={strokeSuccess} strokeWidth="3" fill="none" />
|
||||||
|
{/* Corps du cadenas */}
|
||||||
|
<rect x="10" y="60" width="100" height="80" rx="16" stroke={strokeSuccess} strokeWidth="2.5" fill={fillGlow} />
|
||||||
|
{/* Serrure */}
|
||||||
|
<circle cx="60" cy="92" r="8" fill={isDark ? "#10b981" : "#059669"} />
|
||||||
|
<path d="M60 100 V115" stroke={isDark ? "#10b981" : "#059669"} strokeWidth="3" strokeLinecap="round" />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
{/* --- DESSIN 4 : NŒUDS DE RÉSEAU INTERCONNECTÉS (Réseau Zero-Trust) --- */}
|
||||||
|
<g transform="translate(450, 950)">
|
||||||
|
<line x1="0" y1="0" x2="120" y2="-60" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
<line x1="120" y1="-60" x2="240" y2="20" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
<line x1="0" y1="0" x2="100" y2="80" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
<line x1="100" y1="80" x2="240" y2="20" stroke={strokePrimary} strokeWidth="1.5" />
|
||||||
|
|
||||||
|
<circle cx="0" cy="0" r="8" fill={isDark ? "#3b82f6" : "#2563eb"} />
|
||||||
|
<circle cx="120" cy="-60" r="6" fill={isDark ? "#10b981" : "#059669"} />
|
||||||
|
<circle cx="240" cy="20" r="10" stroke={strokePrimary} strokeWidth="2" fill={isDark ? "#0f172a" : "#ffffff"} />
|
||||||
|
<circle cx="100" cy="80" r="7" fill={isDark ? "#6366f1" : "#4f46e5"} />
|
||||||
|
</g>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
{/* ------------------------------------------------------------- */}
|
||||||
|
{/* COUCHE 3 : HALOS LUMINEUX EN ACCENTUATION (Vitesse: -0.4x) */}
|
||||||
|
{/* ------------------------------------------------------------- */}
|
||||||
|
<div
|
||||||
|
className="absolute top-20 left-1/2 -translate-x-1/2 w-175 h-87.5 bg-blue-500/10 dark:bg-blue-600/15 blur-[140px] rounded-full transition-transform duration-75 ease-out"
|
||||||
|
style={{ transform: `translate(-50%, ${scrollY * -0.4}px)` }}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="absolute top-200 -left-20 w-125 h-125 bg-emerald-500/10 dark:bg-emerald-500/15 blur-[150px] rounded-full transition-transform duration-75 ease-out"
|
||||||
|
style={{ transform: `translateY(${scrollY * -0.2}px)` }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AnimatedSvgBackground;
|
||||||
+541
-535
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user