diff options
| author | hrbrmstr <bob@rud.is> | 2025-12-31 11:32:05 -0500 |
|---|---|---|
| committer | hrbrmstr <bob@rud.is> | 2025-12-31 11:32:05 -0500 |
| commit | 7e628e7d5e1b7fb88b6e792d2052e55f259d5709 (patch) | |
| tree | 45ce76fddb923adeeedae94401f94c33530115f4 /2025/2025-12-25-dropped-animation.html | |
| parent | b70adecfaab54d3ac747a7aa2f96b1169babcdd4 (diff) | |
add: dropped
Diffstat (limited to '2025/2025-12-25-dropped-animation.html')
| -rw-r--r-- | 2025/2025-12-25-dropped-animation.html | 190 |
1 files changed, 0 insertions, 190 deletions
diff --git a/2025/2025-12-25-dropped-animation.html b/2025/2025-12-25-dropped-animation.html deleted file mode 100644 index 53a7f36..0000000 --- a/2025/2025-12-25-dropped-animation.html +++ /dev/null @@ -1,190 +0,0 @@ -<!doctype html> -<html lang="en"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>2025 — Dropped</title> - <link rel="preconnect" href="https://fonts.googleapis.com" /> - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> - <link href="https://fonts.googleapis.com/css2?family=Londrina+Outline&display=swap" rel="stylesheet" /> - <style> - * { - margin: 0; - padding: 0; - box-sizing: border-box; - } - - body { - background: #0a0a0a; - min-height: 100vh; - overflow: hidden; - font-family: "Londrina Outline", system-ui, sans-serif; - } - - .container { - position: relative; - width: 100%; - height: 100vh; - } - - .year { - position: absolute; - top: 10%; - left: 50%; - transform: translateX(-50%); - display: flex; - gap: 0.5vw; - } - - .digit { - font-size: 22vw; - font-weight: 400; - color: #fff; - line-height: 1; - position: relative; - } - - .year.dropping { - animation: drop 1.4s cubic-bezier(0.55, 0, 1, 0.45) forwards; - } - - @keyframes drop { - 0% { - top: 10%; - } - 100% { - top: calc(100vh - 24vw); - } - } - - .shard { - position: absolute; - font-size: 22vw; - font-weight: 400; - color: #fff; - line-height: 1; - font-family: "Londrina Outline", system-ui, sans-serif; - clip-path: polygon(var(--clip)); - animation: shard-fall var(--duration) cubic-bezier(0.25, 0, 0.5, 1) forwards; - animation-delay: var(--delay); - opacity: 1; - } - - @keyframes shard-fall { - 0% { - transform: translate(0, 0) rotate(0deg); - opacity: 1; - } - 100% { - transform: translate(var(--tx), var(--ty)) rotate(var(--rot)); - opacity: 0; - } - } - - .restart { - position: fixed; - bottom: 30px; - left: 50%; - transform: translateX(-50%); - background: transparent; - border: 1px solid #333; - color: #666; - padding: 10px 24px; - font-size: 14px; - cursor: pointer; - transition: all 0.2s; - opacity: 0; - z-index: 50; - } - - .restart.visible { - opacity: 1; - } - - .restart:hover { - border-color: #fff; - color: #fff; - } - </style> - </head> - <body> - <div class="container"> - <div class="year" id="year"> - <span class="digit" data-char="2">2</span> - <span class="digit" data-char="0">0</span> - <span class="digit" data-char="2">2</span> - <span class="digit" data-char="5">5</span> - </div> - </div> - <button class="restart" id="restart">drop again</button> - - <script> - const year = document.getElementById("year"); - const restartBtn = document.getElementById("restart"); - const container = document.querySelector(".container"); - - const shardConfigs = [ - { clip: "0% 0%, 50% 0%, 30% 50%, 0% 40%", tx: -120, ty: 180, rot: -25 }, - { clip: "50% 0%, 100% 0%, 100% 35%, 60% 50%", tx: 80, ty: 200, rot: 35 }, - { clip: "0% 40%, 30% 50%, 40% 100%, 0% 100%", tx: -90, ty: 250, rot: -40 }, - { clip: "30% 50%, 60% 50%, 70% 100%, 40% 100%", tx: 20, ty: 300, rot: 10 }, - { clip: "60% 50%, 100% 35%, 100% 100%, 70% 100%", tx: 100, ty: 220, rot: 45 }, - ]; - - function createShards(digit, index) { - const rect = digit.getBoundingClientRect(); - const char = digit.dataset.char; - - shardConfigs.forEach((config, i) => { - const shard = document.createElement("span"); - shard.className = "shard"; - shard.textContent = char; - shard.style.left = rect.left + "px"; - shard.style.top = rect.top + "px"; - shard.style.setProperty("--clip", config.clip); - shard.style.setProperty("--tx", config.tx + (Math.random() - 0.5) * 60 + "px"); - shard.style.setProperty("--ty", config.ty + Math.random() * 100 + "px"); - shard.style.setProperty("--rot", config.rot + (Math.random() - 0.5) * 30 + "deg"); - shard.style.setProperty("--duration", 1.2 + Math.random() * 0.6 + "s"); - shard.style.setProperty("--delay", i * 0.02 + index * 0.05 + "s"); - container.appendChild(shard); - }); - } - - function shatter() { - const digits = document.querySelectorAll(".digit"); - digits.forEach((digit, index) => { - createShards(digit, index); - }); - - year.style.opacity = "0"; - - setTimeout(() => { - restartBtn.classList.add("visible"); - }, 2000); - } - - function startAnimation() { - document.querySelectorAll(".shard").forEach((s) => s.remove()); - year.style.opacity = "1"; - year.classList.remove("dropping", "shattered"); - restartBtn.classList.remove("visible"); - - void year.offsetWidth; - - year.classList.add("dropping"); - - year.addEventListener("animationend", function handler(e) { - if (e.animationName === "drop") { - year.removeEventListener("animationend", handler); - shatter(); - } - }); - } - - restartBtn.addEventListener("click", startAnimation); - - setTimeout(startAnimation, 500); - </script> - </body> -</html> |
