t-t / index.html
joung's picture
Add 3 files
99eb336 verified
raw
history blame
13.5 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cherry Blossoms & Snowfall</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
font-family: 'Arial', sans-serif;
}
#info {
position: absolute;
bottom: 20px;
width: 100%;
text-align: center;
color: white;
text-shadow: 0 0 5px rgba(0,0,0,0.5);
z-index: 100;
pointer-events: none;
}
#title {
position: absolute;
top: 20px;
width: 100%;
text-align: center;
color: white;
font-size: 2.5rem;
text-shadow: 0 0 10px rgba(0,0,0,0.7);
z-index: 100;
font-weight: 300;
letter-spacing: 2px;
pointer-events: none;
}
.petal {
position: absolute;
width: 15px;
height: 15px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill="%23ffb6c1" d="M50 0 Q75 25 100 50 Q75 75 50 100 Q25 75 0 50 Q25 25 50 0"/></svg>') no-repeat;
background-size: contain;
opacity: 0.8;
animation: petal-fall linear infinite;
filter: drop-shadow(0 0 2px rgba(255,182,193,0.7));
}
@keyframes petal-fall {
0% {
transform: translate(0, -10px) rotate(0deg);
}
100% {
transform: translate(calc(var(--sway) * 100px), calc(100vh + 10px)) rotate(360deg);
}
}
</style>
</head>
<body class="bg-gradient-to-b from-blue-900 to-purple-900">
<div id="title">春の舞 (Spring Dance)</div>
<div id="info">Cherry blossoms and snowflakes dancing together</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x0a1128);
// Camera setup
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 5, 30);
camera.lookAt(0, 0, 0);
// Renderer setup
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
// Create cherry blossom tree
createCherryTree(scene);
// Create snowflakes
const snowflakes = createSnowflakes(scene);
// Create cherry blossom petals
const petals = createPetals(scene);
// Add stars in the background
const stars = createStars(scene);
// Lighting
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.7);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
// Moon
const moonGeometry = new THREE.SphereGeometry(3, 32, 32);
const moonMaterial = new THREE.MeshBasicMaterial({
color: 0xffffcc,
transparent: true,
opacity: 0.9
});
const moon = new THREE.Mesh(moonGeometry, moonMaterial);
moon.position.set(-20, 20, -30);
scene.add(moon);
// Animation loop
function animate() {
requestAnimationFrame(animate);
// Update snowflakes
snowflakes.forEach(flake => {
flake.position.y -= flake.speed;
flake.position.x += Math.sin(Date.now() * 0.001 + flake.id) * 0.05;
if (flake.position.y < -20) {
flake.position.y = 20;
flake.position.x = Math.random() * 40 - 20;
flake.position.z = Math.random() * 40 - 20;
}
});
// Update petals
petals.forEach(petal => {
petal.position.y -= petal.speed;
petal.position.x += Math.sin(Date.now() * 0.001 + petal.id) * 0.03;
petal.rotation.y += 0.01;
if (petal.position.y < -5) {
petal.position.y = 15;
petal.position.x = Math.random() * 10 - 5;
petal.position.z = Math.random() * 10 - 5;
}
});
// Rotate stars slightly
stars.rotation.x += 0.0001;
stars.rotation.y += 0.0001;
renderer.render(scene, camera);
}
// Handle window resize
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
// Start animation
animate();
// Add CSS petals for variety
for (let i = 0; i < 20; i++) {
const petal = document.createElement('div');
petal.className = 'petal';
// Random properties
const size = Math.random() * 15 + 10;
petal.style.width = `${size}px`;
petal.style.height = `${size}px`;
petal.style.left = `${Math.random() * 100}vw`;
petal.style.top = `${Math.random() * 20 - 10}vh`;
petal.style.setProperty('--sway', Math.random() * 2 - 1);
// Random animation duration (5-15 seconds)
const duration = Math.random() * 10 + 5;
petal.style.animationDuration = `${duration}s`;
// Random opacity
petal.style.opacity = Math.random() * 0.5 + 0.3;
document.body.appendChild(petal);
}
});
function createCherryTree(scene) {
// Trunk
const trunkGeometry = new THREE.CylinderGeometry(0.5, 1, 10, 8);
const trunkMaterial = new THREE.MeshPhongMaterial({
color: 0x8B4513,
flatShading: true
});
const trunk = new THREE.Mesh(trunkGeometry, trunkMaterial);
trunk.position.y = 5;
trunk.rotation.z = Math.PI / 20;
scene.add(trunk);
// Branches
const branchMaterial = new THREE.MeshPhongMaterial({
color: 0x8B4513,
flatShading: true
});
for (let i = 0; i < 5; i++) {
const length = 5 + Math.random() * 3;
const angle = Math.PI * 0.2 + Math.random() * Math.PI * 0.3;
const branchGeometry = new THREE.CylinderGeometry(0.2, 0.4, length, 6);
const branch = new THREE.Mesh(branchGeometry, branchMaterial);
branch.position.y = 8 + i * 0.5;
branch.position.x = (Math.random() - 0.5) * 3;
branch.rotation.z = angle * (Math.random() > 0.5 ? 1 : -1);
scene.add(branch);
}
// Blossom clusters
const blossomGeometry = new THREE.SphereGeometry(0.1, 8, 8);
const blossomMaterial = new THREE.MeshPhongMaterial({
color: 0xffb6c1,
transparent: true,
opacity: 0.9
});
for (let i = 0; i < 100; i++) {
const blossom = new THREE.Mesh(blossomGeometry, blossomMaterial);
// Position around branches
const angle = Math.random() * Math.PI * 2;
const radius = 1 + Math.random() * 4;
const height = 5 + Math.random() * 8;
blossom.position.x = Math.cos(angle) * radius;
blossom.position.y = height;
blossom.position.z = Math.sin(angle) * radius;
scene.add(blossom);
}
}
function createSnowflakes(scene) {
const snowflakes = [];
const snowflakeGeometry = new THREE.BufferGeometry();
const snowflakeMaterial = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.15,
transparent: true,
opacity: 0.8,
blending: THREE.AdditiveBlending
});
const snowflakeCount = 1500;
const positions = new Float32Array(snowflakeCount * 3);
for (let i = 0; i < snowflakeCount; i++) {
positions[i * 3] = Math.random() * 40 - 20;
positions[i * 3 + 1] = Math.random() * 40 - 10;
positions[i * 3 + 2] = Math.random() * 40 - 20;
}
snowflakeGeometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
const snowflakeSystem = new THREE.Points(snowflakeGeometry, snowflakeMaterial);
scene.add(snowflakeSystem);
// Add individual properties to each snowflake
for (let i = 0; i < snowflakeCount; i++) {
snowflakes.push({
position: snowflakeSystem.geometry.attributes.position,
index: i,
speed: 0.05 + Math.random() * 0.1,
id: i
});
}
return snowflakes;
}
function createPetals(scene) {
const petals = [];
const petalGeometry = new THREE.PlaneGeometry(0.3, 0.3);
const petalMaterial = new THREE.MeshPhongMaterial({
color: 0xffb6c1,
transparent: true,
opacity: 0.7,
side: THREE.DoubleSide
});
const petalCount = 100;
for (let i = 0; i < petalCount; i++) {
const petal = new THREE.Mesh(petalGeometry, petalMaterial);
petal.position.x = Math.random() * 10 - 5;
petal.position.y = 5 + Math.random() * 10;
petal.position.z = Math.random() * 10 - 5;
petal.rotation.x = Math.random() * Math.PI;
petal.rotation.y = Math.random() * Math.PI;
petal.rotation.z = Math.random() * Math.PI;
petal.speed = 0.02 + Math.random() * 0.03;
petal.id = i;
scene.add(petal);
petals.push(petal);
}
return petals;
}
function createStars(scene) {
const starGeometry = new THREE.BufferGeometry();
const starMaterial = new THREE.PointsMaterial({
color: 0xffffff,
size: 0.1,
transparent: true,
opacity: 0.7
});
const starCount = 1000;
const starPositions = new Float32Array(starCount * 3);
for (let i = 0; i < starCount; i++) {
starPositions[i * 3] = (Math.random() - 0.5) * 2000;
starPositions[i * 3 + 1] = (Math.random() - 0.5) * 2000;
starPositions[i * 3 + 2] = (Math.random() - 0.5) * 2000;
}
starGeometry.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
const stars = new THREE.Points(starGeometry, starMaterial);
scene.add(stars);
return stars;
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=joung/t-t" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>