476 lines
17 KiB
HTML
476 lines
17 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>DAS</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
overflow: hidden;
|
|
cursor: crosshair;
|
|
}
|
|
|
|
#sky {
|
|
position: fixed;
|
|
inset: 0;
|
|
background: linear-gradient(
|
|
180deg,
|
|
#1a1a2e 0%,
|
|
#16213e 15%,
|
|
#4a3f6b 30%,
|
|
#845ec2 45%,
|
|
#d65db1 55%,
|
|
#ff6f91 65%,
|
|
#ff9671 75%,
|
|
#ffc75f 85%,
|
|
#f9f871 100%
|
|
);
|
|
transition: background 0.5s ease;
|
|
}
|
|
|
|
/* Stars layer */
|
|
#stars {
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.star {
|
|
position: absolute;
|
|
background: white;
|
|
border-radius: 50%;
|
|
animation: twinkle 3s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes twinkle {
|
|
0%, 100% { opacity: 0.3; transform: scale(1); }
|
|
50% { opacity: 1; transform: scale(1.2); }
|
|
}
|
|
|
|
/* Cloud container */
|
|
#clouds {
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.cloud {
|
|
position: absolute;
|
|
filter: blur(1px);
|
|
opacity: 0.9;
|
|
transition: transform 0.3s ease-out;
|
|
pointer-events: auto;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.cloud:hover {
|
|
transform: scale(1.1);
|
|
filter: blur(0px);
|
|
}
|
|
|
|
.cloud-body {
|
|
position: relative;
|
|
}
|
|
|
|
.cloud-puff {
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
background: linear-gradient(180deg, #ffffff 0%, #f0e6ff 50%, #e0d4f7 100%);
|
|
box-shadow:
|
|
inset -10px -10px 30px rgba(180, 150, 220, 0.3),
|
|
inset 5px 5px 20px rgba(255, 255, 255, 0.8),
|
|
0 10px 40px rgba(180, 150, 220, 0.2);
|
|
}
|
|
|
|
/* Pink-tinted clouds */
|
|
.cloud.pink .cloud-puff {
|
|
background: linear-gradient(180deg, #fff0f5 0%, #ffb6c1 50%, #ff91a4 100%);
|
|
box-shadow:
|
|
inset -10px -10px 30px rgba(255, 150, 180, 0.4),
|
|
inset 5px 5px 20px rgba(255, 255, 255, 0.9),
|
|
0 10px 40px rgba(255, 150, 180, 0.3);
|
|
}
|
|
|
|
/* Blue-tinted clouds */
|
|
.cloud.blue .cloud-puff {
|
|
background: linear-gradient(180deg, #f0f8ff 0%, #b0e0ff 50%, #89CFF0 100%);
|
|
box-shadow:
|
|
inset -10px -10px 30px rgba(137, 207, 240, 0.4),
|
|
inset 5px 5px 20px rgba(255, 255, 255, 0.9),
|
|
0 10px 40px rgba(137, 207, 240, 0.3);
|
|
}
|
|
|
|
/* Lavender clouds */
|
|
.cloud.lavender .cloud-puff {
|
|
background: linear-gradient(180deg, #f8f0ff 0%, #dda0dd 50%, #c890d0 100%);
|
|
box-shadow:
|
|
inset -10px -10px 30px rgba(221, 160, 221, 0.4),
|
|
inset 5px 5px 20px rgba(255, 255, 255, 0.9),
|
|
0 10px 40px rgba(221, 160, 221, 0.3);
|
|
}
|
|
|
|
/* Interactive particles on click */
|
|
.particle {
|
|
position: fixed;
|
|
pointer-events: none;
|
|
border-radius: 50%;
|
|
animation: particle-float 3s ease-out forwards;
|
|
}
|
|
|
|
@keyframes particle-float {
|
|
0% {
|
|
opacity: 1;
|
|
transform: translate(0, 0) scale(1);
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: translate(var(--dx), var(--dy)) scale(0);
|
|
}
|
|
}
|
|
|
|
/* Floating animation for clouds */
|
|
@keyframes float {
|
|
0%, 100% { transform: translateY(0) translateX(0); }
|
|
25% { transform: translateY(-15px) translateX(5px); }
|
|
50% { transform: translateY(-5px) translateX(-5px); }
|
|
75% { transform: translateY(-20px) translateX(3px); }
|
|
}
|
|
|
|
/* Drift animation */
|
|
@keyframes drift {
|
|
from { transform: translateX(-100%); }
|
|
to { transform: translateX(calc(100vw + 100%)); }
|
|
}
|
|
|
|
/* DAS text - subtle */
|
|
#title {
|
|
position: fixed;
|
|
bottom: 40px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
font-family: 'Georgia', serif;
|
|
font-size: 1.5rem;
|
|
letter-spacing: 0.5em;
|
|
color: rgba(255, 255, 255, 0.3);
|
|
text-shadow: 0 0 30px rgba(255, 255, 255, 0.2);
|
|
z-index: 100;
|
|
user-select: none;
|
|
transition: all 0.5s ease;
|
|
}
|
|
|
|
#title:hover {
|
|
color: rgba(255, 255, 255, 0.6);
|
|
text-shadow: 0 0 50px rgba(255, 255, 255, 0.4);
|
|
}
|
|
|
|
/* Hint text */
|
|
#hint {
|
|
position: fixed;
|
|
top: 30px;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
font-family: 'Georgia', serif;
|
|
font-size: 0.75rem;
|
|
letter-spacing: 0.2em;
|
|
color: rgba(255, 255, 255, 0.15);
|
|
z-index: 100;
|
|
user-select: none;
|
|
animation: fade-hint 5s ease-in-out forwards;
|
|
}
|
|
|
|
@keyframes fade-hint {
|
|
0%, 70% { opacity: 1; }
|
|
100% { opacity: 0; }
|
|
}
|
|
|
|
/* Time of day overlay */
|
|
#time-overlay {
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
transition: background 2s ease;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="sky"></div>
|
|
<div id="time-overlay"></div>
|
|
<div id="stars"></div>
|
|
<div id="clouds"></div>
|
|
<div id="title">DAS</div>
|
|
<div id="hint">click anywhere · drag to explore</div>
|
|
|
|
<script>
|
|
const sky = document.getElementById('sky');
|
|
const clouds = document.getElementById('clouds');
|
|
const stars = document.getElementById('stars');
|
|
const timeOverlay = document.getElementById('time-overlay');
|
|
|
|
// Sky gradients for different times
|
|
const skyGradients = {
|
|
dawn: `linear-gradient(180deg,
|
|
#1a1a2e 0%, #2d1b4e 10%, #5c3d6e 25%,
|
|
#9d5a8f 40%, #d4789c 55%, #f4a5b0 70%,
|
|
#ffc1a0 85%, #ffe4a0 100%)`,
|
|
day: `linear-gradient(180deg,
|
|
#4facfe 0%, #6fb3f2 20%, #87ceeb 40%,
|
|
#a8daef 60%, #c9e9f6 80%, #e8f4fc 100%)`,
|
|
sunset: `linear-gradient(180deg,
|
|
#1a1a2e 0%, #16213e 15%, #4a3f6b 30%,
|
|
#845ec2 45%, #d65db1 55%, #ff6f91 65%,
|
|
#ff9671 75%, #ffc75f 85%, #f9f871 100%)`,
|
|
night: `linear-gradient(180deg,
|
|
#0a0a15 0%, #0d0d20 20%, #151530 40%,
|
|
#1a1a40 60%, #202050 80%, #252560 100%)`
|
|
};
|
|
|
|
let currentTime = 'sunset';
|
|
let mouseX = window.innerWidth / 2;
|
|
let mouseY = window.innerHeight / 2;
|
|
|
|
// Create stars
|
|
function createStars() {
|
|
stars.innerHTML = '';
|
|
for (let i = 0; i < 100; i++) {
|
|
const star = document.createElement('div');
|
|
star.className = 'star';
|
|
star.style.left = Math.random() * 100 + '%';
|
|
star.style.top = Math.random() * 60 + '%';
|
|
const size = Math.random() * 3 + 1;
|
|
star.style.width = size + 'px';
|
|
star.style.height = size + 'px';
|
|
star.style.animationDelay = Math.random() * 3 + 's';
|
|
star.style.animationDuration = (2 + Math.random() * 3) + 's';
|
|
stars.appendChild(star);
|
|
}
|
|
}
|
|
|
|
// Create a fluffy cloud
|
|
function createCloud(x, y, scale = 1, type = 'white') {
|
|
const cloud = document.createElement('div');
|
|
cloud.className = `cloud ${type}`;
|
|
cloud.style.left = x + 'px';
|
|
cloud.style.top = y + 'px';
|
|
cloud.style.transform = `scale(${scale})`;
|
|
|
|
const body = document.createElement('div');
|
|
body.className = 'cloud-body';
|
|
|
|
// Create puffy cloud shape with multiple circles
|
|
const puffs = [
|
|
{ x: 0, y: 20, w: 60, h: 50 },
|
|
{ x: 40, y: 10, w: 70, h: 60 },
|
|
{ x: 90, y: 15, w: 55, h: 45 },
|
|
{ x: 25, y: 35, w: 80, h: 40 },
|
|
{ x: 70, y: 30, w: 60, h: 45 },
|
|
{ x: 10, y: 40, w: 50, h: 35 },
|
|
{ x: 100, y: 35, w: 45, h: 35 }
|
|
];
|
|
|
|
puffs.forEach((puff, i) => {
|
|
const p = document.createElement('div');
|
|
p.className = 'cloud-puff';
|
|
p.style.left = puff.x + 'px';
|
|
p.style.top = puff.y + 'px';
|
|
p.style.width = puff.w + 'px';
|
|
p.style.height = puff.h + 'px';
|
|
body.appendChild(p);
|
|
});
|
|
|
|
cloud.appendChild(body);
|
|
|
|
// Floating animation
|
|
cloud.style.animation = `float ${8 + Math.random() * 4}s ease-in-out infinite`;
|
|
cloud.style.animationDelay = Math.random() * 5 + 's';
|
|
|
|
// Click to burst
|
|
cloud.addEventListener('click', (e) => {
|
|
e.stopPropagation();
|
|
burstCloud(cloud, e.clientX, e.clientY, type);
|
|
});
|
|
|
|
clouds.appendChild(cloud);
|
|
return cloud;
|
|
}
|
|
|
|
// Burst cloud into particles
|
|
function burstCloud(cloud, x, y, type) {
|
|
const colors = {
|
|
white: ['#ffffff', '#f0e6ff', '#e0d4f7'],
|
|
pink: ['#ffb6c1', '#ff91a4', '#ffc0cb'],
|
|
blue: ['#b0e0ff', '#89CFF0', '#add8e6'],
|
|
lavender: ['#dda0dd', '#c890d0', '#e6b0e6']
|
|
};
|
|
|
|
for (let i = 0; i < 20; i++) {
|
|
const particle = document.createElement('div');
|
|
particle.className = 'particle';
|
|
const size = Math.random() * 15 + 5;
|
|
particle.style.width = size + 'px';
|
|
particle.style.height = size + 'px';
|
|
particle.style.left = x + 'px';
|
|
particle.style.top = y + 'px';
|
|
particle.style.background = colors[type][Math.floor(Math.random() * colors[type].length)];
|
|
particle.style.setProperty('--dx', (Math.random() - 0.5) * 200 + 'px');
|
|
particle.style.setProperty('--dy', (Math.random() - 0.5) * 200 - 100 + 'px');
|
|
document.body.appendChild(particle);
|
|
setTimeout(() => particle.remove(), 3000);
|
|
}
|
|
|
|
cloud.style.transition = 'opacity 0.3s, transform 0.3s';
|
|
cloud.style.opacity = '0';
|
|
cloud.style.transform += ' scale(1.5)';
|
|
setTimeout(() => {
|
|
cloud.remove();
|
|
// Respawn cloud somewhere else after a delay
|
|
setTimeout(() => {
|
|
const types = ['white', 'pink', 'blue', 'lavender'];
|
|
createCloud(
|
|
Math.random() * (window.innerWidth - 200),
|
|
Math.random() * (window.innerHeight * 0.6),
|
|
0.5 + Math.random() * 0.8,
|
|
types[Math.floor(Math.random() * types.length)]
|
|
);
|
|
}, 2000);
|
|
}, 300);
|
|
}
|
|
|
|
// Create particles on click
|
|
function createClickParticles(x, y) {
|
|
const colors = ['#ffb6c1', '#89CFF0', '#dda0dd', '#ffffff', '#ffc0cb', '#add8e6'];
|
|
for (let i = 0; i < 12; i++) {
|
|
const particle = document.createElement('div');
|
|
particle.className = 'particle';
|
|
const size = Math.random() * 10 + 3;
|
|
particle.style.width = size + 'px';
|
|
particle.style.height = size + 'px';
|
|
particle.style.left = x + 'px';
|
|
particle.style.top = y + 'px';
|
|
particle.style.background = colors[Math.floor(Math.random() * colors.length)];
|
|
particle.style.setProperty('--dx', (Math.random() - 0.5) * 150 + 'px');
|
|
particle.style.setProperty('--dy', -Math.random() * 150 - 50 + 'px');
|
|
document.body.appendChild(particle);
|
|
setTimeout(() => particle.remove(), 3000);
|
|
}
|
|
}
|
|
|
|
// Initialize clouds
|
|
function initClouds() {
|
|
const types = ['white', 'pink', 'blue', 'lavender'];
|
|
for (let i = 0; i < 12; i++) {
|
|
createCloud(
|
|
Math.random() * (window.innerWidth - 200),
|
|
Math.random() * (window.innerHeight * 0.7),
|
|
0.4 + Math.random() * 0.9,
|
|
types[Math.floor(Math.random() * types.length)]
|
|
);
|
|
}
|
|
}
|
|
|
|
// Parallax effect on mouse move
|
|
document.addEventListener('mousemove', (e) => {
|
|
mouseX = e.clientX;
|
|
mouseY = e.clientY;
|
|
|
|
const cloudEls = document.querySelectorAll('.cloud');
|
|
cloudEls.forEach((cloud, i) => {
|
|
const speed = 0.02 + (i % 3) * 0.01;
|
|
const x = (window.innerWidth / 2 - mouseX) * speed;
|
|
const y = (window.innerHeight / 2 - mouseY) * speed;
|
|
cloud.style.marginLeft = x + 'px';
|
|
cloud.style.marginTop = y + 'px';
|
|
});
|
|
|
|
// Subtle star parallax
|
|
const starEls = document.querySelectorAll('.star');
|
|
starEls.forEach((star, i) => {
|
|
const speed = 0.01;
|
|
const x = (window.innerWidth / 2 - mouseX) * speed;
|
|
const y = (window.innerHeight / 2 - mouseY) * speed;
|
|
star.style.marginLeft = x + 'px';
|
|
star.style.marginTop = y + 'px';
|
|
});
|
|
});
|
|
|
|
// Click to create particles and spawn cloud
|
|
document.addEventListener('click', (e) => {
|
|
createClickParticles(e.clientX, e.clientY);
|
|
});
|
|
|
|
// Keyboard controls for time of day
|
|
document.addEventListener('keydown', (e) => {
|
|
const times = ['dawn', 'day', 'sunset', 'night'];
|
|
const key = e.key.toLowerCase();
|
|
|
|
if (key === '1') setTime('dawn');
|
|
if (key === '2') setTime('day');
|
|
if (key === '3') setTime('sunset');
|
|
if (key === '4') setTime('night');
|
|
if (key === ' ') {
|
|
// Cycle through times
|
|
const idx = times.indexOf(currentTime);
|
|
setTime(times[(idx + 1) % times.length]);
|
|
}
|
|
});
|
|
|
|
function setTime(time) {
|
|
currentTime = time;
|
|
sky.style.background = skyGradients[time];
|
|
|
|
// Adjust star visibility
|
|
const starEls = document.querySelectorAll('.star');
|
|
const starOpacity = time === 'night' ? 1 : time === 'dawn' || time === 'sunset' ? 0.5 : 0.1;
|
|
starEls.forEach(star => {
|
|
star.style.opacity = starOpacity;
|
|
});
|
|
|
|
// Add/remove overlay for different moods
|
|
if (time === 'night') {
|
|
timeOverlay.style.background = 'radial-gradient(ellipse at 30% 20%, rgba(100,100,200,0.1) 0%, transparent 50%)';
|
|
} else if (time === 'day') {
|
|
timeOverlay.style.background = 'radial-gradient(ellipse at 80% 20%, rgba(255,255,200,0.2) 0%, transparent 40%)';
|
|
} else {
|
|
timeOverlay.style.background = 'none';
|
|
}
|
|
}
|
|
|
|
// Double click to spawn a new cloud
|
|
document.addEventListener('dblclick', (e) => {
|
|
const types = ['white', 'pink', 'blue', 'lavender'];
|
|
createCloud(
|
|
e.clientX - 75,
|
|
e.clientY - 40,
|
|
0.5 + Math.random() * 0.5,
|
|
types[Math.floor(Math.random() * types.length)]
|
|
);
|
|
});
|
|
|
|
// Initialize
|
|
createStars();
|
|
initClouds();
|
|
|
|
// Slowly drift clouds
|
|
setInterval(() => {
|
|
const cloudEls = document.querySelectorAll('.cloud');
|
|
cloudEls.forEach(cloud => {
|
|
const currentLeft = parseFloat(cloud.style.left) || 0;
|
|
cloud.style.left = (currentLeft + 0.1) + 'px';
|
|
|
|
// Wrap around
|
|
if (currentLeft > window.innerWidth + 200) {
|
|
cloud.style.left = '-200px';
|
|
}
|
|
});
|
|
}, 50);
|
|
|
|
console.log('☁️ DAS — click clouds to burst them, double-click to spawn, 1-4 or space to change time');
|
|
</script>
|
|
</body>
|
|
</html>
|