Se rendre au contenu

Welcome .


Sign u

Cette question a été signalée
39 Vues

Ce code HTML/CSS/JS affiche un texte centré sur la page, survolé par 7 ballons colorés animés qui montent et oscillent doucement, créant un effet visuel léger et festif.



<div id="balloons-hero">
  <div class="hero-text">Bienvenue à notre événement</div>
  <div class="sky" aria-hidden="true"></div>
</div>

<style>
  #balloons-hero {
    position: relative;
    height: 70vh;
    min-height: 380px;
    overflow: hidden;
    background: #fff;
  }
  #balloons-hero .hero-text {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    text-align: center;
    font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial;
    font-weight: 700;
    font-size: clamp(28px, 5vw, 64px);
    line-height: 1.1;
    color: #111827;
    z-index: 1;
  }
  #balloons-hero .sky {
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
  }

  .balloon {
    position: absolute;
    will-change: transform, opacity;
    transform: translate(-50%, 0);
    width: var(--size, 72px);
    height: calc(var(--size, 72px) * 1.25);
    border-radius: 50% 50% 48% 48%;
    /* Plus opaque qu'avant */
    --alpha: 0.85;
    background:
      radial-gradient(circle at 28% 28%, rgba(255, 255, 255, .75) 0 18%, transparent 22%),
      rgba(var(--rgb, 239, 68, 68), var(--alpha));
    box-shadow: 0 8px 18px rgba(0, 0, 0, .12);
  }

  /* Ficelle courbée en SVG */
  .balloon svg {
    position: absolute;
    top: 95%;
    left: 50%;
    transform-origin: top center;
    transform: translateX(-50%) rotate(var(--tilt, 0deg));
  }
  .balloon path {
    fill: none;
    stroke: #9ca3af;
    stroke-width: 2;
    opacity: 0.9;
  }

  .balloon::before {
    content: "";
    position: absolute;
    bottom: -10%;
    left: 50%;
    width: 60%;
    height: 8%;
    transform: translateX(-50%);
    filter: blur(4px);
    background: rgba(0, 0, 0, .08);
    border-radius: 50%;
  }

  @media (prefers-reduced-motion: reduce) {
    .balloon { transition: none; }
  }
</style>

<script>
(function () {
  const sky = document.querySelector("#balloons-hero .sky");
  const W = () => sky.clientWidth;
  const H = () => sky.clientHeight;

  const colors = [
    [239, 68, 68],   // rouge
    [37, 99, 235],   // bleu
    [250, 204, 21],  // jaune
    [34, 197, 94],   // vert
    [239, 68, 68],
    [37, 99, 235],
    [34, 197, 94]
  ];
  const COUNT = 7;

  function rand(min, max) { return Math.random() * (max - min) + min; }
  function clamp(x, a, b) { return Math.min(b, Math.max(a, x)); }

  const balloons = [];

  for (let i = 0; i < COUNT; i++) {
    const el = document.createElement("div");
    el.className = "balloon";

    const size = Math.round(rand(58, 86));
    const rgb = colors[i % colors.length];
    el.style.setProperty("--size", size + "px");
    el.style.setProperty("--rgb", rgb.join(","));

    // Ajout ficelle courbée via SVG
    const svgNS = "http://www.w3.org/2000/svg";
    const svg = document.createElementNS(svgNS, "svg");
    svg.setAttribute("width", "2");
    svg.setAttribute("height", size * 0.9);
    svg.setAttribute("viewBox", "0 0 2 " + (size * 0.9));
    const path = document.createElementNS(svgNS, "path");
    path.setAttribute("d", `M1 0 Q ${rand(-4,4)} ${size*0.3} , 1 ${size*0.6} T 1 ${size*0.9}`);
    svg.appendChild(path);
    el.appendChild(svg);

    sky.appendChild(el);

    const b = {
      el,
      path,
      size,
      baseX: rand(0.08, 0.92),
      amp: rand(0.04, 0.09),
      omega: rand(0.4, 0.85),
      vy: rand(18, 32),
      phase: rand(0, Math.PI * 2),
      y: rand(H() * 0.15, H() * 0.95),
      t0: performance.now() / 1000 - rand(0, 10)
    };
    balloons.push(b);
  }

  function tick(nowMs) {
    const t = nowMs / 1000;
    const w = W(), h = H();

    for (const b of balloons) {
      const x = (b.baseX + b.amp * Math.sin(b.omega * (t - b.t0) + b.phase)) * w;
      b.y -= b.vy * (1 / 60);
      if (b.y < -b.size * 1.6) {
        b.y = h + rand(10, 120);
        b.baseX = rand(0.08, 0.92);
        b.amp = rand(0.04, 0.09);
        b.omega = rand(0.4, 0.85);
        b.vy = rand(18, 32);
        b.phase = rand(0, Math.PI * 2);
      }
      const vx = b.amp * b.omega * Math.cos(b.omega * (t - b.t0) + b.phase) * w;
      const tilt = clamp(vx * 0.06, -14, 14);
      b.el.style.setProperty("--tilt", tilt.toFixed(2) + "deg");

      const alpha = 0.75 + (1 - b.y / h) * 0.15;
      b.el.style.setProperty("--alpha", clamp(alpha, 0.75, 0.9).toFixed(2));

      // Mise à jour dynamique de la courbure de la ficelle
      b.path.setAttribute("d", `M1 0 Q ${clamp(vx*0.08,-6,6)} ${b.size*0.3} , 1 ${b.size*0.6} T 1 ${b.size*0.9}`);

      b.el.style.transform = `translate(${x}px, ${b.y}px)`;
    }
    requestAnimationFrame(tick);
  }

  (function initStartPositions() {
    const w = W();
    for (const b of balloons) {
      const x = (b.baseX + b.amp * Math.sin(b.phase)) * w;
      b.el.style.transform = `translate(${x}px, ${b.y}px)`;
    }
  })();

  requestAnimationFrame(tick);
})();
</script>

Ignorer
Publications associées Réponses Vues Activité
1
août 25
79
0
août 25
1
0
août 25
42
0
août 25
29
0
août 25
3