341 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			341 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <!DOCTYPE html>
 | |
| <html lang="en">
 | |
| <head>
 | |
|     <meta charset="UTF-8">
 | |
|     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | |
|     <title>Project Mycelium</title>
 | |
|     <style>
 | |
|         * {
 | |
|             margin: 0;
 | |
|             padding: 0;
 | |
|             box-sizing: border-box;
 | |
|         }
 | |
| 
 | |
|         body {
 | |
|             background-color: #222222;
 | |
|             color: #e2e8f0;
 | |
|             font-family: system-ui, -apple-system, sans-serif;
 | |
|             line-height: 1.6;
 | |
|             overflow: hidden;
 | |
|         }
 | |
| 
 | |
|         .content-container {
 | |
|             height: 100vh;
 | |
|             overflow: hidden;
 | |
|             position: relative;
 | |
|         }
 | |
| 
 | |
|         .scroll-content {
 | |
|             position: relative;
 | |
|             transition: transform 1s cubic-bezier(0.4, 0, 0.2, 1);
 | |
|         }
 | |
| 
 | |
|         .landing-section {
 | |
|             height: 100vh;
 | |
|             width: 100vw;
 | |
|             display: flex;
 | |
|             flex-direction: column;
 | |
|             position: relative;
 | |
|         }
 | |
| 
 | |
|         .header-container {
 | |
|             width: 100%;
 | |
|         }
 | |
| 
 | |
|         .header-image {
 | |
|             width: 100%;
 | |
|             display: block;
 | |
|         }
 | |
| 
 | |
|         .gif-container {
 | |
|             flex: 1;
 | |
|             display: flex;
 | |
|             align-items: center;
 | |
|             justify-content: center;
 | |
|             overflow: hidden;
 | |
|         }
 | |
| 
 | |
|         .gif-image {
 | |
|             max-width: 100%;
 | |
|             max-height: 100%;
 | |
|             object-fit: contain;
 | |
|         }
 | |
| 
 | |
|         .image-section {
 | |
|             position: relative;
 | |
|             height: 100vh;
 | |
|             width: 100vw;
 | |
|             display: flex;
 | |
|             align-items: center;
 | |
|             justify-content: center;
 | |
|             opacity: 0;
 | |
|             transform: translateY(40px);
 | |
|             transition: all 1.5s cubic-bezier(0.4, 0, 0.2, 1);
 | |
|         }
 | |
| 
 | |
|         /* Special handling for footer section */
 | |
|         .image-section:last-child {
 | |
|             align-items: flex-end;
 | |
|             justify-content: flex-end;
 | |
|         }
 | |
| 
 | |
|         .image-section:last-child .image-container {
 | |
|             height: auto;
 | |
|         }
 | |
| 
 | |
|         .image-section.visible {
 | |
|             opacity: 1;
 | |
|             transform: translateY(0);
 | |
|         }
 | |
| 
 | |
|         .image-section.entering-up {
 | |
|             opacity: 0;
 | |
|             transform: translateY(-40px);
 | |
|         }
 | |
| 
 | |
|         .image-section.entering-down {
 | |
|             opacity: 0;
 | |
|             transform: translateY(40px);
 | |
|         }
 | |
| 
 | |
|         .image-section.leaving-up {
 | |
|             opacity: 0;
 | |
|             transform: translateY(-40px);
 | |
|         }
 | |
| 
 | |
|         .image-section.leaving-down {
 | |
|             opacity: 0;
 | |
|             transform: translateY(40px);
 | |
|         }
 | |
| 
 | |
|         .image-container {
 | |
|             width: 100%;
 | |
|             height: 100%;
 | |
|             display: flex;
 | |
|             align-items: center;
 | |
|             justify-content: center;
 | |
|         }
 | |
| 
 | |
|         .scroll-image {
 | |
|             width: 100%;
 | |
|             height: 100%;
 | |
|             object-fit: contain;
 | |
|         }
 | |
| 
 | |
|         .image-section:last-child .scroll-image {
 | |
|             object-fit: cover;
 | |
|             width: 100%;
 | |
|         }
 | |
| 
 | |
|         .progress-bar {
 | |
|             position: fixed;
 | |
|             top: 0;
 | |
|             left: 0;
 | |
|             width: 100%;
 | |
|             height: 4px;
 | |
|             background: #1e293b;
 | |
|             z-index: 1000;
 | |
|         }
 | |
| 
 | |
|         .progress {
 | |
|             height: 100%;
 | |
|             width: 0%;
 | |
|             background: linear-gradient(90deg, #60a5fa, #93c5fd);
 | |
|             transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
 | |
|         }
 | |
|     </style>
 | |
| </head>
 | |
| <body>
 | |
|     <div class="progress-bar">
 | |
|         <div class="progress"></div>
 | |
|     </div>
 | |
| 
 | |
|     <div class="content-container">
 | |
|         <div class="scroll-content">
 | |
|             <!-- Landing section with header and GIF -->
 | |
|             <div class="landing-section">
 | |
|                 <div class="header-container">
 | |
|                     <img src="./img/1.png" alt="Header" class="header-image">
 | |
|                 </div>
 | |
|                 <div class="gif-container">
 | |
|                     <img src="./img/myceliumdate_blackbg.gif" alt="GIF" class="gif-image">
 | |
|                 </div>
 | |
|             </div>
 | |
|             
 | |
|             <!-- Images 3-17 will be inserted here via JavaScript -->
 | |
|         </div>
 | |
|     </div>
 | |
| 
 | |
|     <script>
 | |
|         const content = document.querySelector('.scroll-content');
 | |
|         const landingSection = document.querySelector('.landing-section');
 | |
|         
 | |
|         // Create image sections starting from image 3
 | |
|         for (let i = 3; i <= 17; i++) {
 | |
|             const section = document.createElement('div');
 | |
|             section.className = 'image-section';
 | |
|             
 | |
|             const imageContainer = document.createElement('div');
 | |
|             imageContainer.className = 'image-container';
 | |
|             
 | |
|             const img = document.createElement('img');
 | |
|             img.src = `./img/${i}.png`;
 | |
|             img.alt = `Image ${i}`;
 | |
|             img.className = 'scroll-image';
 | |
|             
 | |
|             imageContainer.appendChild(img);
 | |
|             section.appendChild(imageContainer);
 | |
|             content.appendChild(section);
 | |
|         }
 | |
| 
 | |
|         const sections = document.querySelectorAll('.image-section');
 | |
|         const progressBar = document.querySelector('.progress');
 | |
|         
 | |
|         let currentSection = 0;
 | |
|         let isScrolling = false;
 | |
|         let lastScrollTime = Date.now();
 | |
|         const scrollCooldown = 1000;
 | |
| 
 | |
|         function updateProgress() {
 | |
|             const progress = (currentSection / sections.length) * 100;
 | |
|             progressBar.style.width = `${progress}%`;
 | |
|         }
 | |
| 
 | |
|         function showSection(index, direction) {
 | |
|             // For index 0, show the landing section
 | |
|             if (index === 0) {
 | |
|                 content.style.transform = 'translateY(0)';
 | |
|             } else {
 | |
|                 // For other indices, offset by the height of one section
 | |
|                 // and subtract 1 from index since we're counting from the sections after landing
 | |
|                 content.style.transform = `translateY(-${index * 100}vh)`;
 | |
|             }
 | |
|             
 | |
|             // Reset all sections
 | |
|             sections.forEach(section => {
 | |
|                 section.classList.remove('visible', 'entering-up', 'entering-down', 'leaving-up', 'leaving-down');
 | |
|             });
 | |
| 
 | |
|             if (index > 0) {
 | |
|                 // Current section (subtract 1 since sections array starts after landing)
 | |
|                 const currentSection = sections[index - 1];
 | |
|                 currentSection.classList.remove(direction === 'up' ? 'entering-up' : 'entering-down');
 | |
|                 currentSection.classList.add('visible');
 | |
| 
 | |
|                 // Previous section
 | |
|                 if (index > 1 && direction === 'down') {
 | |
|                     sections[index - 2].classList.add('leaving-up');
 | |
|                 }
 | |
| 
 | |
|                 // Next section
 | |
|                 if (index < sections.length && direction === 'up') {
 | |
|                     sections[index].classList.add('leaving-down');
 | |
|                 }
 | |
| 
 | |
|                 // Prepare next section for entry
 | |
|                 if (index < sections.length) {
 | |
|                     if (sections[index]) sections[index].classList.add('entering-down');
 | |
|                 }
 | |
| 
 | |
|                 // Prepare previous section for entry
 | |
|                 if (index > 1) {
 | |
|                     sections[index - 2].classList.add('entering-up');
 | |
|                 }
 | |
|             }
 | |
|             
 | |
|             updateProgress();
 | |
|         }
 | |
| 
 | |
|         function handleScroll(event) {
 | |
|             event.preventDefault();
 | |
|             
 | |
|             const now = Date.now();
 | |
|             if (isScrolling || now - lastScrollTime < scrollCooldown) return;
 | |
|             
 | |
|             const delta = event.deltaY;
 | |
|             
 | |
|             if (delta > 0 && currentSection < sections.length) {
 | |
|                 isScrolling = true;
 | |
|                 currentSection++;
 | |
|                 showSection(currentSection, 'down');
 | |
|             } else if (delta < 0 && currentSection > 0) {
 | |
|                 isScrolling = true;
 | |
|                 currentSection--;
 | |
|                 showSection(currentSection, 'up');
 | |
|             }
 | |
|             
 | |
|             lastScrollTime = now;
 | |
|             setTimeout(() => {
 | |
|                 isScrolling = false;
 | |
|             }, scrollCooldown);
 | |
|         }
 | |
| 
 | |
|         function handleKeydown(event) {
 | |
|             const now = Date.now();
 | |
|             if (isScrolling || now - lastScrollTime < scrollCooldown) return;
 | |
|             
 | |
|             if (event.key === 'ArrowDown' && currentSection < sections.length) {
 | |
|                 event.preventDefault();
 | |
|                 isScrolling = true;
 | |
|                 currentSection++;
 | |
|                 showSection(currentSection, 'down');
 | |
|             } else if (event.key === 'ArrowUp' && currentSection > 0) {
 | |
|                 event.preventDefault();
 | |
|                 isScrolling = true;
 | |
|                 currentSection--;
 | |
|                 showSection(currentSection, 'up');
 | |
|             }
 | |
|             
 | |
|             lastScrollTime = now;
 | |
|             setTimeout(() => {
 | |
|                 isScrolling = false;
 | |
|             }, scrollCooldown);
 | |
|         }
 | |
| 
 | |
|         // Initialize
 | |
|         showSection(0, 'down');
 | |
| 
 | |
|         // Event listeners
 | |
|         window.addEventListener('wheel', handleScroll, { passive: false });
 | |
|         window.addEventListener('keydown', handleKeydown);
 | |
| 
 | |
|         // Touch events for mobile
 | |
|         let touchStartY = 0;
 | |
|         let touchEndY = 0;
 | |
| 
 | |
|         window.addEventListener('touchstart', (e) => {
 | |
|             touchStartY = e.touches[0].clientY;
 | |
|         }, { passive: false });
 | |
| 
 | |
|         window.addEventListener('touchmove', (e) => {
 | |
|             e.preventDefault();
 | |
|         }, { passive: false });
 | |
| 
 | |
|         window.addEventListener('touchend', (e) => {
 | |
|             touchEndY = e.changedTouches[0].clientY;
 | |
|             const now = Date.now();
 | |
|             
 | |
|             if (isScrolling || now - lastScrollTime < scrollCooldown) return;
 | |
|             
 | |
|             const delta = touchStartY - touchEndY;
 | |
|             
 | |
|             if (Math.abs(delta) > 50) {
 | |
|                 if (delta > 0 && currentSection < sections.length) {
 | |
|                     isScrolling = true;
 | |
|                     currentSection++;
 | |
|                     showSection(currentSection, 'down');
 | |
|                 } else if (delta < 0 && currentSection > 0) {
 | |
|                     isScrolling = true;
 | |
|                     currentSection--;
 | |
|                     showSection(currentSection, 'up');
 | |
|                 }
 | |
|                 
 | |
|                 lastScrollTime = now;
 | |
|                 setTimeout(() => {
 | |
|                     isScrolling = false;
 | |
|                 }, scrollCooldown);
 | |
|             }
 | |
|         }, { passive: false });
 | |
|     </script>
 | |
| </body>
 | |
| </html> |