Created
March 17, 2026 13:36
-
-
Save tilaktilak/ebf6a94527726500fdf7673e3d2d2123 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>🍼 Bébé Surprise</title> | |
| <style> | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| min-height: 100vh; | |
| display: flex; flex-direction: column; align-items: center; justify-content: center; | |
| background: #e8f5e0; | |
| font-family: 'Georgia', serif; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| /* Décor SVG nature en fond */ | |
| #bg { position: fixed; inset: 0; z-index: 0; pointer-events: none; } | |
| .content { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; } | |
| h1 { font-size: 1.7em; color: #5a7a3a; margin-bottom: 6px; text-shadow: 1px 1px 0 #fff; } | |
| .subtitle { color: #7a9a5a; margin-bottom: 24px; font-size: 0.9em; } | |
| /* Personnage Miyazaki flottant au dessus */ | |
| #character { font-size: 5em; margin-bottom: -10px; animation: float 3s ease-in-out infinite; filter: drop-shadow(2px 4px 6px rgba(0,0,0,0.15)); } | |
| @keyframes float { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-12px)} } | |
| .card { | |
| position: relative; | |
| width: 320px; height: 220px; | |
| border-radius: 20px; | |
| overflow: hidden; | |
| box-shadow: 0 8px 30px rgba(0,0,0,0.2); | |
| cursor: crosshair; | |
| } | |
| #reveal { | |
| position: absolute; inset: 0; | |
| display: flex; flex-direction: column; align-items: center; justify-content: center; | |
| font-size: 2.2em; font-weight: bold; letter-spacing: 2px; | |
| } | |
| #reveal .big { font-size: 1.6em; } | |
| #reveal .lbl { font-size: 0.32em; margin-top: 8px; letter-spacing: 4px; text-transform: uppercase; } | |
| /* Petites feuilles animées dans la carte révélée */ | |
| .leaf { position: absolute; font-size: 1.2em; animation: spin 4s linear infinite; opacity: 0.5; } | |
| @keyframes spin { from{transform:rotate(0)} to{transform:rotate(360deg)} } | |
| canvas { position: absolute; inset: 0; } | |
| #hint { margin-top: 14px; color: #8aab6a; font-size: 0.85em; } | |
| #confetti-canvas { position: fixed; inset: 0; pointer-events: none; z-index: 10; } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Fond nature SVG style Miyazaki --> | |
| <svg id="bg" viewBox="0 0 800 600" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg"> | |
| <!-- Ciel doux --> | |
| <defs> | |
| <linearGradient id="sky" x1="0" y1="0" x2="0" y2="1"> | |
| <stop offset="0%" stop-color="#c8e6c9"/> | |
| <stop offset="100%" stop-color="#e8f5e0"/> | |
| </linearGradient> | |
| </defs> | |
| <rect width="800" height="600" fill="url(#sky)"/> | |
| <!-- Nuages ronds style Miyazaki --> | |
| <g fill="white" opacity="0.75"> | |
| <ellipse cx="120" cy="80" rx="70" ry="35"/> | |
| <ellipse cx="160" cy="70" rx="50" ry="28"/> | |
| <ellipse cx="80" cy="75" rx="45" ry="22"/> | |
| <ellipse cx="580" cy="100" rx="80" ry="38"/> | |
| <ellipse cx="630" cy="88" rx="55" ry="30"/> | |
| <ellipse cx="540" cy="96" rx="48" ry="24"/> | |
| <ellipse cx="350" cy="50" rx="60" ry="28"/> | |
| <ellipse cx="390" cy="40" rx="40" ry="20"/> | |
| </g> | |
| <!-- Collines --> | |
| <ellipse cx="0" cy="580" rx="250" ry="180" fill="#a5d6a7" opacity="0.7"/> | |
| <ellipse cx="800" cy="590" rx="280" ry="170" fill="#81c784" opacity="0.6"/> | |
| <ellipse cx="400" cy="620" rx="400" ry="160" fill="#c8e6c9" opacity="0.5"/> | |
| <!-- Grand arbre gauche style Totoro --> | |
| <rect x="60" y="300" width="18" height="200" fill="#5d4037" rx="5"/> | |
| <ellipse cx="69" cy="280" rx="60" ry="70" fill="#2e7d32" opacity="0.85"/> | |
| <ellipse cx="50" cy="310" rx="40" ry="50" fill="#388e3c" opacity="0.7"/> | |
| <ellipse cx="95" cy="305" rx="38" ry="48" fill="#43a047" opacity="0.65"/> | |
| <!-- Petit arbre droite --> | |
| <rect x="710" y="360" width="12" height="140" fill="#6d4c41" rx="4"/> | |
| <ellipse cx="716" cy="345" rx="42" ry="50" fill="#388e3c" opacity="0.8"/> | |
| <ellipse cx="700" cy="368" rx="28" ry="36" fill="#2e7d32" opacity="0.6"/> | |
| <!-- Herbe / fleurs au sol --> | |
| <g fill="#66bb6a" opacity="0.6"> | |
| <ellipse cx="200" cy="570" rx="120" ry="25"/> | |
| <ellipse cx="600" cy="575" rx="100" ry="22"/> | |
| </g> | |
| <!-- Petites fleurs --> | |
| <g font-size="18"> | |
| <text x="160" y="565">🌸</text><text x="200" y="572">🌼</text> | |
| <text x="240" y="560">🌿</text><text x="560" y="568">🌸</text> | |
| <text x="600" y="575">🌿</text><text x="640" y="562">🍀</text> | |
| <text x="350" y="578">🌱</text><text x="420" y="570">🦋</text> | |
| </g> | |
| <!-- Particules lumineuses façon kodama --> | |
| <g fill="white" opacity="0.5"> | |
| <circle cx="300" cy="200" r="3"><animate attributeName="opacity" values="0.5;1;0.5" dur="2s" repeatCount="indefinite"/></circle> | |
| <circle cx="500" cy="160" r="2"><animate attributeName="opacity" values="0.3;0.9;0.3" dur="2.5s" repeatCount="indefinite"/></circle> | |
| <circle cx="200" cy="250" r="2.5"><animate attributeName="opacity" values="0.4;1;0.4" dur="1.8s" repeatCount="indefinite"/></circle> | |
| <circle cx="620" cy="230" r="3"><animate attributeName="opacity" values="0.5;1;0.5" dur="3s" repeatCount="indefinite"/></circle> | |
| <circle cx="150" cy="180" r="2"><animate attributeName="opacity" values="0.3;0.8;0.3" dur="2.2s" repeatCount="indefinite"/></circle> | |
| </g> | |
| </svg> | |
| <div class="content"> | |
| <div id="character">🌿</div> | |
| <h1>🍼 Bébé Surprise !</h1> | |
| <p class="subtitle">Grattez pour découvrir le sexe du bébé</p> | |
| <div class="card"> | |
| <div id="reveal"> | |
| <div class="leaf" style="top:10%;left:8%;animation-duration:5s">🍃</div> | |
| <div class="leaf" style="top:15%;right:10%;animation-duration:7s">🌸</div> | |
| <div class="leaf" style="bottom:12%;left:12%;animation-duration:6s">🌿</div> | |
| <div class="leaf" style="bottom:10%;right:8%;animation-duration:4s">🍀</div> | |
| </div> | |
| <canvas id="scratch"></canvas> | |
| </div> | |
| <p id="hint">✨ Grattez avec le doigt ou la souris</p> | |
| </div> | |
| <canvas id="confetti-canvas"></canvas> | |
| <script> | |
| const GENDER = "fille"; // "fille" ou "garçon" | |
| const isBoy = GENDER === "garçon"; | |
| const color = isBoy ? "#4fc3f7" : "#f48fb1"; | |
| const label = isBoy ? "C'est un garçon !" : "C'est une fille !"; | |
| // Personnage Miyazaki selon sexe | |
| const charEl = document.getElementById("character"); | |
| charEl.textContent = isBoy ? "🐉" : "🌺"; // dragon / fleur de cerisier avant révélation | |
| const reveal = document.getElementById("reveal"); | |
| reveal.style.background = `linear-gradient(135deg, ${color}44, ${color}99)`; | |
| reveal.style.color = color; | |
| // Contenu révélé avec bébé style Miyazaki | |
| const babyEmoji = isBoy ? "🐉👶🌊" : "🌸👶🍃"; | |
| reveal.innerHTML = ` | |
| <div class="leaf" style="top:10%;left:8%;animation-duration:5s">🍃</div> | |
| <div class="leaf" style="top:15%;right:10%;animation-duration:7s">🌸</div> | |
| <div class="leaf" style="bottom:12%;left:12%;animation-duration:6s">🌿</div> | |
| <div class="leaf" style="bottom:10%;right:8%;animation-duration:4s">🍀</div> | |
| <div class="big">${babyEmoji}</div> | |
| <div class="lbl">${label}</div> | |
| `; | |
| // Canvas | |
| const card = document.querySelector(".card"); | |
| const canvas = document.getElementById("scratch"); | |
| canvas.width = card.offsetWidth; | |
| canvas.height = card.offsetHeight; | |
| const ctx = canvas.getContext("2d"); | |
| // Layer à gratter : style ardoise verte nature | |
| const g = ctx.createLinearGradient(0,0,canvas.width,canvas.height); | |
| g.addColorStop(0,"#6a9a5a"); g.addColorStop(1,"#3d6b3a"); | |
| ctx.fillStyle = g; | |
| ctx.fillRect(0,0,canvas.width,canvas.height); | |
| // Texture motif feuilles sur le layer | |
| ctx.font = "22px serif"; | |
| ctx.globalAlpha = 0.18; | |
| for(let x=20;x<canvas.width;x+=45) | |
| for(let y=20;y<canvas.height;y+=40) | |
| ctx.fillText(["🍃","🌿","🍀"][(x+y)%3], x, y); | |
| ctx.globalAlpha = 1; | |
| ctx.fillStyle = "#c8e6b0"; | |
| ctx.font = "bold 18px Georgia"; | |
| ctx.textAlign = "center"; | |
| ctx.fillText("🌿 GRATTEZ ICI 🌿", canvas.width/2, canvas.height/2-10); | |
| ctx.font = "13px Georgia"; | |
| ctx.fillStyle = "#a8c890"; | |
| ctx.fillText("Votre surprise vous attend...", canvas.width/2, canvas.height/2+18); | |
| ctx.globalCompositeOperation = "destination-out"; | |
| let scratching = false, revealed = false; | |
| function getPos(e,el) { | |
| const r = el.getBoundingClientRect(), s = e.touches?e.touches[0]:e; | |
| return [s.clientX-r.left, s.clientY-r.top]; | |
| } | |
| function scratch(x,y) { | |
| ctx.beginPath(); ctx.arc(x,y,30,0,Math.PI*2); ctx.fill(); | |
| checkRevealed(); | |
| } | |
| function checkRevealed() { | |
| if(revealed) return; | |
| const d = ctx.getImageData(0,0,canvas.width,canvas.height).data; | |
| let t=0; | |
| for(let i=3;i<d.length;i+=4) if(d[i]<128) t++; | |
| if(t/(canvas.width*canvas.height)>0.55) { | |
| revealed = true; | |
| canvas.style.transition = "opacity 1s"; | |
| canvas.style.opacity = "0"; | |
| document.getElementById("hint").textContent = label + " 🎉"; | |
| document.getElementById("hint").style.color = color; | |
| charEl.textContent = isBoy ? "🐉✨" : "🌸✨"; | |
| launchConfetti(); | |
| } | |
| } | |
| canvas.addEventListener("mousedown", e=>{scratching=true; scratch(...getPos(e,canvas));}); | |
| canvas.addEventListener("mousemove", e=>{if(scratching)scratch(...getPos(e,canvas));}); | |
| canvas.addEventListener("mouseup", ()=>scratching=false); | |
| canvas.addEventListener("touchstart", e=>{e.preventDefault();scratching=true;scratch(...getPos(e,canvas));},{passive:false}); | |
| canvas.addEventListener("touchmove", e=>{e.preventDefault();if(scratching)scratch(...getPos(e,canvas));},{passive:false}); | |
| canvas.addEventListener("touchend", ()=>scratching=false); | |
| function launchConfetti() { | |
| const cc = document.getElementById("confetti-canvas"); | |
| cc.width = window.innerWidth; cc.height = window.innerHeight; | |
| const cx = cc.getContext("2d"); | |
| // Confettis style pétales / feuilles | |
| const shapes = isBoy ? ["🌊","💙","🌿","⭐"] : ["🌸","💗","🍃","✨"]; | |
| const pieces = Array.from({length:80}, ()=>({ | |
| x: Math.random()*cc.width, y:-20, | |
| s: 14+Math.random()*16, | |
| c: shapes[Math.random()*shapes.length|0], | |
| vx:(Math.random()-.5)*3, vy:2+Math.random()*3, | |
| rot:Math.random()*360, rv:(Math.random()-.5)*5 | |
| })); | |
| (function draw(){ | |
| cx.clearRect(0,0,cc.width,cc.height); | |
| let alive=false; | |
| for(const p of pieces){ | |
| p.x+=p.vx; p.y+=p.vy; p.rot+=p.rv; | |
| if(p.y<cc.height+30) alive=true; | |
| cx.save(); cx.translate(p.x,p.y); cx.rotate(p.rot*Math.PI/180); | |
| cx.font = p.s+"px serif"; cx.textAlign="center"; | |
| cx.fillText(p.c,0,0); | |
| cx.restore(); | |
| } | |
| if(alive) requestAnimationFrame(draw); | |
| })(); | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment