Project demo
Introduction:
We created a fun interactive Ghost Mode experience webpage. It includes animated ghost emojis, a toggle-activated haunted house background, spooky sound effects, and floating ghosts that appear when enabled. The interface uses stylish glass-blur UI, glowing animations, and custom switches instead of normal checkboxes. Each toggle activates a different horror effect, making the page transform into a spooky ghost environment with sound, motion, and visual changes. This project combines HTML, CSS, and JavaScript to create an engaging Halloween-style interactive page.
HTML:
The HTML structure builds the main layout of the page. It includes a container with a title and three toggle switches.Ghost emojis and background elements are added in the markup. Floating ghost elements are positioned around the screen. It provides the skeleton for the interactive Ghost Mode interface.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ghost House Toggle</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Ghost House Background -->
<div class="ghost-house" id="ghostHouse"></div>
<!-- Floating Ghosts -->
<div class="floating-ghosts" id="floatingGhosts">
<div class="ghost" style="top: 20%; left: 10%;">👻</div>
<div class="ghost" style="top: 60%; left: 85%;">👻</div>
<div class="ghost" style="top: 80%; left: 15%;">👻</div>
<div class="ghost" style="top: 30%; left: 80%;">👻</div>
<div class="ghost" style="top: 10%; left: 50%;">👻</div>
</div>
<div class="container">
<h1>👻 Ghost House</h1>
<div class="toggle-container">
<label class="toggle-wrapper">
<input type="checkbox" id="ghostToggle">
<span class="custom-toggle">
<span class="toggle-handle">
<span class="ghost-emoji">👻</span>
</span>
</span>
<span class="toggle-text">Activate Ghost House</span>
</label>
<label class="toggle-wrapper">
<input type="checkbox" id="spookyToggle">
<span class="custom-toggle">
<span class="toggle-handle">
<span class="ghost-emoji">👻</span>
</span>
</span>
<span class="toggle-text">Enable Spooky Sounds</span>
</label>
<label class="toggle-wrapper">
<input type="checkbox" id="floatToggle">
<span class="custom-toggle">
<span class="toggle-handle">
<span class="ghost-emoji">👻</span>
</span>
</span>
<span class="toggle-text">Floating Ghosts</span>
</label>
</div>
<p class="instructions">Toggle the switches to reveal the ghost house and spooky effects!</p>
</div>
<script src="script.js"></script>
</body>
</html>
CSS:
The CSS styles the page with a spooky, glowing, glass-blur theme. It creates custom animated toggle switches with ghost icons. Floating ghosts are animated using keyframes to float around. A dark haunted-house background appears when enabled. Responsive rules ensure the design works on smaller screens.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
overflow: hidden;
position: relative;
}
.container {
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 40px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
max-width: 500px;
width: 100%;
z-index: 10;
position: relative;
}
h1 {
color: white;
text-align: center;
margin-bottom: 30px;
font-weight: 600;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.toggle-container {
display: flex;
flex-direction: column;
gap: 20px;
}
/* Hide the default checkbox */
.toggle-wrapper input {
display: none;
}
/* Custom toggle design */
.toggle-wrapper {
display: flex;
align-items: center;
cursor: pointer;
padding: 15px 20px;
background: rgba(255, 255, 255, 0.15);
border-radius: 15px;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.toggle-wrapper:hover {
background: rgba(255, 255, 255, 0.25);
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
.toggle-wrapper:active {
transform: translateY(1px);
}
.custom-toggle {
width: 60px;
height: 30px;
background: rgba(255, 255, 255, 0.2);
border-radius: 15px;
margin-right: 15px;
display: flex;
align-items: center;
padding: 0 5px;
transition: all 0.3s ease;
position: relative;
z-index: 2;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.toggle-handle {
width: 22px;
height: 22px;
background: white;
border-radius: 50%;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
transform: translateX(0);
}
.toggle-text {
color: white;
font-weight: 500;
font-size: 18px;
z-index: 2;
}
/* Ghost emoji effect */
.ghost-emoji {
font-size: 14px;
transition: all 0.3s ease;
}
/* Checked state styles */
.toggle-wrapper input:checked+.custom-toggle {
background: rgba(123, 97, 255, 0.7);
border-color: rgba(255, 255, 255, 0.5);
}
.toggle-wrapper input:checked+.custom-toggle .toggle-handle {
transform: translateX(30px);
background: rgba(255, 255, 255, 0.9);
}
.toggle-wrapper input:checked+.custom-toggle .ghost-emoji {
transform: rotate(15deg);
}
/* Ghost House Background */
.ghost-house {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 800" width="1200" height="800"><rect width="100%" height="100%" fill="%23051229"/><path d="M300,400 L450,300 L600,400 L600,550 L300,550 Z" fill="%233a2c5b" stroke="%235d43a0" stroke-width="5"/><rect x="400" y="450" width="100" height="100" fill="%235d43a0"/><path d="M425,450 L425,400 M475,450 L475,400" stroke="%23ffffff" stroke-width="8"/><circle cx="350" cy="350" r="20" fill="%23ffffff"/><circle cx="500" cy="350" r="20" fill="%23ffffff"/><path d="M100,200 L150,150 L200,200 L200,300 L100,300 Z" fill="%233a2c5b" stroke="%235d43a0" stroke-width="4"/><rect x="130" y="250" width="40" height="50" fill="%235d43a0"/><circle cx="125" cy="190" r="10" fill="%23ffffff"/><circle cx="165" cy="190" r="10" fill="%23ffffff"/><path d="M800,350 L900,250 L1000,350 L1000,500 L800,500 Z" fill="%233a2c5b" stroke="%235d43a0" stroke-width="5"/><rect x="870" y="400" width="60" height="100" fill="%235d43a0"/><circle cx="840" cy="300" r="15" fill="%23ffffff"/><circle cx="940" cy="300" r="15" fill="%23ffffff"/></svg>') no-repeat center center;
background-size: cover;
opacity: 0;
visibility: hidden;
transition: all 0.5s ease;
z-index: 1;
pointer-events: none;
}
.ghost-house.active {
opacity: 1;
visibility: visible;
}
/* Floating Ghosts */
.floating-ghosts {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 2;
}
.ghost {
position: absolute;
font-size: 40px;
opacity: 0;
transition: opacity 0.5s ease;
}
.ghost.show {
opacity: 0.8;
}
/* Instructions */
.instructions {
text-align: center;
color: rgba(255, 255, 255, 0.7);
margin-top: 30px;
font-size: 14px;
}
/* Ghost animation */
@keyframes float {
0%,
100% {
transform: translateY(0) translateX(0);
}
25% {
transform: translateY(-20px) translateX(10px);
}
50% {
transform: translateY(-10px) translateX(-10px);
}
75% {
transform: translateY(-15px) translateX(5px);
}
}
.ghost {
animation: float 5s ease-in-out infinite;
}
.ghost:nth-child(2) {
animation-delay: 1s;
font-size: 30px;
}
.ghost:nth-child(3) {
animation-delay: 2s;
font-size: 50px;
}
.ghost:nth-child(4) {
animation-delay: 3s;
font-size: 35px;
}
.ghost:nth-child(5) {
animation-delay: 4s;
font-size: 25px;
}
/* Toggle active state glow */
.toggle-wrapper input:checked~.toggle-text {
text-shadow: 0 0 10px rgba(255, 255, 255, 0.7);
}
/* Responsive design */
@media (max-width: 600px) {
.container {
margin: 20px;
padding: 30px 20px;
}
.custom-toggle {
width: 50px;
height: 26px;
}
.toggle-handle {
width: 18px;
height: 18px;
}
.toggle-wrapper input:checked+.custom-toggle .toggle-handle {
transform: translateX(24px);
}
}
JavaScript:
JavaScript controls the interactive ghost effects. Checkbox events trigger background, floating ghost, and sound actions. It uses classes to show/hide visuals and animate ghosts. The Web Audio API creates spooky sound when the sound toggle is activated. Click effects and ripple animations enhance user interaction.
// Get DOM elements
const ghostToggle = document.getElementById("ghostToggle");
const spookyToggle = document.getElementById("spookyToggle");
const floatToggle = document.getElementById("floatToggle");
const ghostHouse = document.getElementById("ghostHouse");
const floatingGhosts = document.querySelectorAll(".ghost");
// Toggle ghost house background
ghostToggle.addEventListener("change", function () {
if (this.checked) {
ghostHouse.classList.add("active");
} else {
ghostHouse.classList.remove("active");
}
});
// Toggle floating ghosts
floatToggle.addEventListener("change", function () {
if (this.checked) {
floatingGhosts.forEach((ghost) => {
ghost.classList.add("show");
});
} else {
floatingGhosts.forEach((ghost) => {
ghost.classList.remove("show");
});
}
});
// Spooky sounds effect
spookyToggle.addEventListener("change", function () {
if (this.checked) {
// Create a spooky sound using the Web Audio API
try {
const audioContext = new (window.AudioContext ||
window.webkitAudioContext)();
const oscillator = audioContext.createOscillator();
const gainNode = audioContext.createGain();
oscillator.connect(gainNode);
gainNode.connect(audioContext.destination);
oscillator.type = "sine";
oscillator.frequency.setValueAtTime(200, audioContext.currentTime);
oscillator.frequency.exponentialRampToValueAtTime(
50,
audioContext.currentTime + 1.5
);
gainNode.gain.setValueAtTime(0.1, audioContext.currentTime);
gainNode.gain.exponentialRampToValueAtTime(
0.01,
audioContext.currentTime + 1.5
);
oscillator.start(audioContext.currentTime);
oscillator.stop(audioContext.currentTime + 1.5);
} catch (e) {
console.log("Web Audio API not supported");
}
}
});
// Add click effects to all toggles
document.querySelectorAll(".toggle-wrapper").forEach((wrapper) => {
wrapper.addEventListener("click", function () {
// Add a subtle ripple effect
const ripple = document.createElement("span");
ripple.style.cssText = `
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.5);
transform: scale(0);
animation: ripple 0.6s linear;
z-index: 1;
`;
const size = Math.max(this.clientWidth, this.clientHeight);
const rect = this.getBoundingClientRect();
ripple.style.width = ripple.style.height = size + "px";
ripple.style.left = event.clientX - rect.left - size / 2 + "px";
ripple.style.top = event.clientY - rect.top - size / 2 + "px";
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
});
});
// Add CSS for ripple animation
const style = document.createElement("style");
style.textContent = `
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
`;
document.head.appendChild(style);
SOURCE CODE 👇
Download “Ghost-House.zip” Ghost-House.zip – Downloaded 45 times – 4.11 KB