Animazione con interazione in javascript stile cartoon
See the Pen
Digital Pet – with Notifications! by Sofiya (@sheepsheep)
on CodePen.
<div class="pet-pen"> <img class="pet-image" src="https://assets.codepen.io/2345403/pixil-egg.png" alt="" /> <div class="curtain hidden" /> <div class="overlay hidden">💖</div> </div> <div class="button-bar"> <button id="love-button">Send Love</button> <button id="curtain-button">💡Toggle Lights 💡</button> <div class="notification-center"> <button>Notifications</button> <div class="notifications hidden"> <div id="no-notifications" class="notification"> <p>Nothing has happened...</p> </div> </div> </div> </div>
.html { height: 100vh; width: 100vw; margin: 0; padding: 0; } body { font-family: monospace; background-color: hsl(80deg 50% 70%); /* background-image: linear-gradient( 0deg, hsl(45deg 62% 100%) 0%, hsl(80deg 100% 83%) 39%, hsl(90deg 59% 74%) 61%, hsl(45deg 62% 100%) 100% ); */ } .button-bar { position: fixed; top: 20px; left: 20px; width: 300px; > button { background-color: #fbfbfb; width: 100%; border: 0; font: inherit; padding: 0.5rem 1rem; border-bottom: 1px solid black; } } .notification-center { width: 300px; background-color: #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); > button { width: 100%; border: 0; font: inherit; background: none; padding: 0.5rem 1rem; } } .hidden { display: none; } .notification { padding: 0.5rem; border-bottom: 1px dotted #e0e0e0; } .notification:last-child { border-bottom: none; } .heart { top: 0; left: 0; position: absolute; font-size: 1em; animation: burst 1000ms ease-in 0s 1 normal forwards; } .glow { animation: glowEffect 200ms ease-in 0s 1 normal forwards; } .pet-pen { background-color: white; margin: auto; margin-top: 50px; width: 300px; border: 20px dashed black; position: relative; } .curtain { position: absolute; width: 300px; height: 300px; background-color: black; top: 0; left: 0; } .pet-image { width: 300px; margin: auto; animation: petPulse 5s linear 2s infinite alternate; } .changing { animation: changeStage 3s ease-in-out 0s 2 alternate forwards !important; } @keyframes changeStage { 0% { opacity: 1; } 100% { opacity: 0; } } @keyframes showCurtain { 0% { opacity: 1; } 100% { opacity: 0; } } @keyframes petPulse { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } @keyframes glowEffect { 0% { box-shadow: inset 0 0 0 lime; } 100% { box-shadow: inset 0 0 10px lime; } } @keyframes burst { 0% { transform: scale(1); opacity: 0; } 50% { transform: scale(10); opacity: 1; } 100% { transform: scale(20); opacity: 0; } }
// Buttonns //--TODO: Rename button const button = document.querySelector(".notification-center > button"); const curtainToggler = document.getElementById("curtain-button"); const loveButton = document.getElementById("love-button"); // Other elements const notifications = document.querySelector(".notifications"); const petPen = document.querySelector(".pet-pen"); const petImage = document.querySelector(".pet-image"); const curtain = document.querySelector(".curtain"); const petOverlay = document.querySelector(".overlay"); // Images const firstStageImage = "https://assets.codepen.io/2345403/pixil-little-guy.png"; const firstStageAngryImage = "https://assets.codepen.io/2345403/pixii-little-mad.png"; // Messages //🥚 🐣 🐥 🐤 🐓 // 💢 🤬 😡 const hatchEventMessage = "🐣 The Egg Hatched!"; const firstGrowthSpurtMessage = "🐥The little guy got bigger!"; const checkBackMessage = "✨ Check back later!"; const stopMessage = "😡 Stop Clicking!"; const brokenLightMessage = "🌒 Good job, you broke the light"; //utility values let clickCount = 0; // Replace with loveLevel let annoyanceLevel = 0; let lightClickCount = 0; let hatching = false; let isTurningAngry = false; let isLightBroken = false; // Utility for delaying events async function getPromise(delay) { return await new Promise((resolve) => setTimeout(resolve, delay)); } // Unsorted Functions function onNotifcationClick() { button.classList.remove("glow"); if (button.getAttribute("aria-expanded") === "true") { button.setAttribute("aria-expanded", "false"); } else { button.setAttribute("aria-expanded", "true"); } notifications.classList.toggle("hidden"); } function addNotification(message) { if (notifications.firstElementChild.id === "no-notifications") { notifications.removeChild(notifications.firstElementChild); } const newNotification = document.createElement("div"); newNotification.classList.add("notification"); const details = document.createElement("p"); details.innerText = message; newNotification.append(details); notifications.appendChild(newNotification); button.classList.add("glow"); } // TODO - Factor out durations async function changeImage(url) { petImage.classList.add("changing"); await getPromise(3000); petImage.src = url; await getPromise(3000); petImage.classList.remove("changing"); return getPromise(0); } async function hatch() { if (!hatching) { hatching = true; changeImage(firstStageImage).then(() => { addNotification(hatchEventMessage); }); } } async function showAngry() { if (!isTurningAngry) { isTurningAngry = true; changeImage(firstStageAngryImage).then(() => { addNotification(stopMessage); }); } } async function notifyViewerOfMore() { setTimeout(() => { addNotification(checkBackMessage); }, 10000); } function sendLove() { if (clickCount < 10) { clickCount++; const newHeart = document.createElement("div"); newHeart.classList.add("heart"); newHeart.innerText = "💖"; petPen.append(newHeart); } else if (!hatching) { hatch(); } } function toggleCurtain() { console.log(annoyanceLevel); if (isLightBroken) { // Broken Light return; } else if (annoyanceLevel === 10) { // Gets angry showAngry(); } else if (isTurningAngry && annoyanceLevel >= 20) { // Break light isLightBroken = true; curtain.classList.remove("hidden"); addNotification(brokenLightMessage); notifyViewerOfMore(); return; } if (hatching) { // If hatched - Increase Annoyance annoyanceLevel++; } curtain.classList.toggle("hidden"); } // Listeners button.addEventListener("click", () => { onNotifcationClick(); }); curtainToggler.addEventListener("click", () => toggleCurtain()); loveButton.addEventListener("click", () => sendLove());