<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Arc-en-ciel Magique</title>
<style>
body { margin: 0; overflow: hidden; background-color: #000; display: flex; justify-content: center; align-items: flex-end; height: 100vh; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Configuration de l'arc-en-ciel (Couleurs du Do Ré Mi Fa Sol La Si)
// Note: L'ordre est inversé ici car on dessine du plus grand au plus petit ou inversement selon le souhait.
// Ici on va du Rouge (extérieur) au Violet (intérieur) ou l'inverse.
// Dans ta vidéo c'est Rouge en haut.
const colors = [
'#FF0000', // Rouge (Do)
'#FF7F00', // Orange (Ré)
'#FFFF00', // Jaune (Mi)
'#00FF00', // Vert (Fa)
'#0000FF', // Bleu (Sol)
'#4B0082', // Indigo (La)
'#9400D3' // Violet (Si) - Ajoutons un 2eme Do rose si besoin
];
// Paramètres
const centerX = canvas.width / 2;
const centerY = canvas.height + 100; // Un peu plus bas que l'écran
const baseRadius = 200; // Rayon du plus petit arc
const stripWidth = 40; // Largeur des bandes
const speed = 0.02; // Vitesse de l'animation
let currentLayer = 0; // Quelle bande on dessine (0 = Rouge)
let progress = Math.PI; // On part de PI (gauche) vers 0 (droite) ou 2PI
// Système de particules
let particles = [];
function spawnParticles(x, y, color) {
for(let i=0; i<5; i++) {
particles.push({
x: x,
y: y,
vx: (Math.random() - 0.5) * 4,
vy: (Math.random() - 0.5) * 4,
life: 1.0,
color: '#FFFFFF' // Étoiles blanches/brillantes
});
}
}
function drawParticles() {
for (let i = particles.length - 1; i >= 0; i--) {
let p = particles[i];
p.x += p.vx;
p.y += p.vy;
p.life -= 0.03;
ctx.globalAlpha = p.life;
ctx.fillStyle = p.color;
ctx.beginPath();
ctx.arc(p.x, p.y, 2 + Math.random()*2, 0, Math.PI * 2);
ctx.fill();
// Effet étoile (croix)
if (p.life > 0.5) {
ctx.fillRect(p.x - 4, p.y - 0.5, 9, 1);
ctx.fillRect(p.x - 0.5, p.y - 4, 1, 9);
}
if (p.life <= 0) particles.splice(i, 1);
}
ctx.globalAlpha = 1;
}
// On stocke l'état final des arcs déjà dessinés
let completedArcs = [];
function animate() {
// Fond noir avec léger "trail" pour effet de flou si on veut, sinon clearRect
ctx.fillStyle = 'rgba(0, 0, 0, 1)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Dessiner les arcs terminés
completedArcs.forEach(arc => {
ctx.beginPath();
ctx.arc(centerX, centerY, arc.radius, Math.PI, 0);
ctx.lineWidth = stripWidth;
ctx.strokeStyle = arc.color;
ctx.stroke();
});
// Dessiner l'arc en cours
if (currentLayer < colors.length) {
let radius = baseRadius + (colors.length - 1 - currentLayer) * stripWidth;
// Dessin de la ligne
ctx.beginPath();
ctx.arc(centerX, centerY, radius, Math.PI, progress, true); // true pour sens anti-horaire? non, on va de PI à 0
// Correction sens: On part de PI (gauche) et on diminue vers 0 (droite)
// Donc startAngle: Math.PI, EndAngle: progress
ctx.lineWidth = stripWidth;
ctx.strokeStyle = colors[currentLayer];
ctx.stroke();
// Calcul position de la tête (là où sont les étoiles)
let headX = centerX + Math.cos(progress) * radius;
let headY = centerY + Math.sin(progress) * radius;
// Faire briller la tête
spawnParticles(headX, headY, colors[currentLayer]);
// Halo lumineux au bout
ctx.shadowBlur = 20;
ctx.shadowColor = "white";
ctx.fillStyle = "white";
ctx.beginPath();
ctx.arc(headX, headY, 10, 0, Math.PI*2);
ctx.fill();
ctx.shadowBlur = 0;
// Avancer
progress -= speed;
// Si on a fini l'arc (atteint 0)
if (progress <= 0) {
completedArcs.push({
color: colors[currentLayer],
radius: radius
});
currentLayer++;
progress = Math.PI; // Reset pour le prochain
}
}
drawParticles();
requestAnimationFrame(animate);
}
// Lancer au clic pour synchroniser si besoin
document.body.addEventListener('click', () => {
currentLayer = 0;
completedArcs = [];
progress = Math.PI;
animate();
});
animate();
</script>
</body>
</html>