Skip to content

Instantly share code, notes, and snippets.

@tilaktilak
Created March 17, 2026 13:36
Show Gist options
  • Select an option

  • Save tilaktilak/ebf6a94527726500fdf7673e3d2d2123 to your computer and use it in GitHub Desktop.

Select an option

Save tilaktilak/ebf6a94527726500fdf7673e3d2d2123 to your computer and use it in GitHub Desktop.
<!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