Frontend Forever App
We have a mobile app for you to download and use. And you can unlock many features in the app.
Get it now
Intall Later
Run
HTML
CSS
Javascript
Output
Document
Reset Garden
@charset "UTF-8"; @import url(https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,600,700,800); *, :after, :before { box-sizing: border-box; padding: 0; margin: 0; } /* styles.css */ body { margin: 0; overflow: hidden; } #garden { width: 100vw; height: 100vh; background-color: #3a5f0b; /* Garden background color */ position: relative; cursor: crosshair; } .seed, .vine, .flower, .pumpkin { position: absolute; transform-origin: center center; } .seed { width: 5px; height: 10px; background-color: #fffac2; border-radius: 75%; transform: translate(-50%, -50%); } .vine { width: 2px; height: 20px; /* Height of each vine segment */ background-color: #a4f21c; transform-origin: bottom center; transform: rotate(0deg) scaleY(0); transform-style: preserve-3d; } .flower { width: 10px; height: 10px; background-color: #ffd700; border-radius: 50%; transform: translate(-50%, -50%); } .pumpkin { width: 20px; height: 20px; background-color: #ff8c00; border-radius: 50%; transform: translate(-50%, -50%); } /* Style for the reset button */ #reset-button { position: absolute; top: 10px; left: 10px; z-index: 1000; /* Ensure the button stays on top */ padding: 10px 20px; font-size: 16px; cursor: pointer; background-color: #ff6347; /* Tomato color */ color: white; border: none; border-radius: 5px; } #reset-button:hover { background-color: #ff4500; /* Darker shade on hover */ }
console.log("Event Fired") // script.js //browning and decaying vines //browning and decaying flowers //browning and decaying pumpkins // Constants const garden = document.getElementById("garden"); const maxSeeds = 10; // Global variables let seedCount = 0; let activeTimeouts = []; let activeIntervals = []; // Event listener for planting seeds garden.addEventListener("click", handleGardenClick); // Handles the garden click event and plants a seed function handleGardenClick(e) { if (seedCount >= maxSeeds) return; const rect = garden.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; plantSeed(x, y); } // Plants a seed and initializes the plant object function plantSeed(x, y) { seedCount++; const seed = createSeedElement(x, y); garden.appendChild(seed); const plant = initializePlant(seed); const timeoutId = setTimeout(() => { growVines(plant, x, y); seed.remove(); seedCount--; }, 1000); activeTimeouts.push(timeoutId); } // Initializes a plant object function initializePlant(seed) { return { seed: seed, vines: [], flowers: [], pumpkin: null }; } // Creates a seed DOM element function createSeedElement(x, y) { const seed = document.createElement("div"); seed.classList.add("seed"); seed.style.left = `${x}px`; seed.style.top = `${y}px`; return seed; } // Starts growing vines for the plant function growVines(plant, x, y) { let vineCount = Math.random() * 3 + 1; for (let i = 0; i < vineCount; i++) { const initialAngle = Math.random() * 360; const vineSegments = []; plant.vines.push(vineSegments); growVineSegments( plant, x, y, initialAngle, 0, Math.random() * 5 + 5, vineSegments ); } } // Grows vine segments recursively function growVineSegments( plant, x, y, angle, segmentIndex, totalSegments, vineSegments ) { if (segmentIndex >= totalSegments) { sproutFlower(plant, x, y); return; } const segment = createVineSegment(x, y, angle); garden.appendChild(segment); vineSegments.push(segment); animateVineSegment(segment, angle, () => { const { endX, endY } = calculateEndPosition(x, y, angle); const nextAngle = angle + (Math.random() * 40 - 20); growVineSegments( plant, endX, endY, nextAngle, segmentIndex + 1, totalSegments, vineSegments ); }); } // Creates a vine segment DOM element function createVineSegment(x, y, angle) { const segment = document.createElement("div"); segment.classList.add("vine"); segment.style.left = `${x}px`; segment.style.top = `${y}px`; segment.style.transformOrigin = "0% 100%"; segment.style.transform = `rotate(${angle}deg) scaleY(0)`; return segment; } // Animates a vine segment growing function animateVineSegment(segment, angle, callback) { let scaleY = 0; const maxScaleY = 1; const growthRate = 0.05; const intervalId = setInterval(() => { if (scaleY >= maxScaleY) { clearInterval(intervalId); callback(); return; } scaleY += growthRate; segment.style.transform = `rotate(${angle}deg) scaleY(${scaleY})`; }, 50); activeIntervals.push(intervalId); // Track interval ID } // Calculates the end position of a vine segment based on its angle function calculateEndPosition(x, y, angle) { const segmentLength = 20; // Length of the vine segment const endX = x + segmentLength * Math.cos(((angle - 90) * Math.PI) / 180); const endY = y + segmentLength * Math.sin(((angle - 90) * Math.PI) / 180); return { endX, endY }; } // Sprouts a flower at the end of the last vine segment function sproutFlower(plant, x, y) { const flower = createFlowerElement(x, y); // Use x, y from the last segment garden.appendChild(flower); plant.flowers.push(flower); const timeoutId = setTimeout(() => { flower.remove(); growPumpkin(plant, x, y); // Pass the final position to grow the pumpkin }, 2000); activeTimeouts.push(timeoutId); // Track timeout ID } // Creates a flower DOM element function createFlowerElement(x, y) { const flower = document.createElement("div"); flower.classList.add("flower"); flower.style.left = `${x}px`; flower.style.top = `${y + 15}px`; return flower; } // Grows a pumpkin at the position of the flower function growPumpkin(plant, x, y) { const pumpkin = createPumpkinElement(x, y); // Use x, y from the flower's position garden.appendChild(pumpkin); plant.pumpkin = pumpkin; animatePumpkinGrowth(pumpkin, () => { const timeoutId = setTimeout(() => { explodePumpkin(plant, x, y); // Pass the final position for explosion }, 3000); activeTimeouts.push(timeoutId); // Track timeout ID }); } // Creates a pumpkin DOM element function createPumpkinElement(x, y) { const pumpkin = document.createElement("div"); pumpkin.classList.add("pumpkin"); pumpkin.style.left = `${x - 10}px`; pumpkin.style.top = `${y}px`; pumpkin.style.transform = "scale(0)"; return pumpkin; } // Animates the growth of a pumpkin function animatePumpkinGrowth(pumpkin, callback) { let scale = 0; const maxScale = 1; const growthRate = 0.01; const intervalId = setInterval(() => { if (scale >= maxScale) { clearInterval(intervalId); callback(); return; } scale += growthRate; pumpkin.style.transform = `scale(${scale})`; }, 20); activeIntervals.push(intervalId); // Track interval ID } // Explodes the pumpkin and plants new seeds function explodePumpkin(plant, x, y) { plant.pumpkin?.remove(); plant.flowers.forEach((flower) => flower.remove()); let seedCountToPlant = Math.floor(Math.random() * 4); for (let i = 0; i < seedCountToPlant; i++) { if (seedCount >= maxSeeds) return; const { seedX, seedY } = calculateSeedPosition(x, y); plantSeed(seedX, seedY); } } // Calculates the position for planting new seeds after explosion function calculateSeedPosition(x, y) { const angle = Math.random() * 360; const seedDistance = 5; const seedX = x + seedDistance * Math.cos((angle * Math.PI) / 180); const seedY = y + seedDistance * Math.sin((angle * Math.PI) / 180); return { seedX, seedY }; } // Reset button event listener and functionality const resetButton = document.getElementById("reset-button"); resetButton.addEventListener("click", resetGarden); // Resets the garden and global variables function resetGarden() { // Clear all active timeouts and intervals activeTimeouts.forEach((timeoutId) => clearTimeout(timeoutId)); activeIntervals.forEach((intervalId) => clearInterval(intervalId)); // Empty the arrays tracking the timers activeTimeouts = []; activeIntervals = []; // Remove all child elements from the garden while (garden.firstChild) { garden.removeChild(garden.firstChild); } // Reset the seed count seedCount = 0; }