Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ASCII Wave Animation</title> | |
| <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet"> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| background-color: #000; | |
| min-height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| font-family: 'JetBrains Mono', monospace; | |
| overflow: hidden; | |
| } | |
| header { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| padding: 1rem; | |
| text-align: center; | |
| z-index: 100; | |
| } | |
| header a { | |
| color: #444; | |
| text-decoration: none; | |
| font-size: 0.8rem; | |
| letter-spacing: 2px; | |
| transition: color 0.3s ease; | |
| } | |
| header a:hover { | |
| color: #888; | |
| } | |
| #ascii-container { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 0; | |
| line-height: 1.2; | |
| } | |
| .ascii-row { | |
| display: flex; | |
| gap: 0; | |
| } | |
| .ascii-char { | |
| width: clamp(8px, 2vw, 16px); | |
| height: clamp(12px, 2.5vw, 20px); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: clamp(8px, 2vw, 16px); | |
| color: #fff; | |
| transition: transform 0.1s ease-out; | |
| } | |
| @media (max-width: 768px) { | |
| .ascii-char { | |
| width: 6px; | |
| height: 10px; | |
| font-size: 6px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .ascii-char { | |
| width: 5px; | |
| height: 8px; | |
| font-size: 5px; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a> | |
| </header> | |
| <div id="ascii-container"></div> | |
| <script> | |
| const container = document.getElementById('ascii-container'); | |
| const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@#$%&*!?<>[]{}|/\\~^'; | |
| let cols, rows; | |
| let grid = []; | |
| let time = 0; | |
| function calculateGridSize() { | |
| const charWidth = Math.max(8, Math.min(16, window.innerWidth * 0.02)); | |
| const charHeight = Math.max(12, Math.min(20, window.innerWidth * 0.025)); | |
| cols = Math.floor(window.innerWidth / charWidth); | |
| rows = Math.floor(window.innerHeight / charHeight); | |
| // Ensure minimum grid size | |
| cols = Math.max(40, Math.min(cols, 120)); | |
| rows = Math.max(20, Math.min(rows, 60)); | |
| } | |
| function getRandomChar() { | |
| return characters[Math.floor(Math.random() * characters.length)]; | |
| } | |
| function createGrid() { | |
| container.innerHTML = ''; | |
| grid = []; | |
| for (let y = 0; y < rows; y++) { | |
| const row = document.createElement('div'); | |
| row.className = 'ascii-row'; | |
| const rowData = []; | |
| for (let x = 0; x < cols; x++) { | |
| const charSpan = document.createElement('span'); | |
| charSpan.className = 'ascii-char'; | |
| charSpan.textContent = getRandomChar(); | |
| row.appendChild(charSpan); | |
| rowData.push({ | |
| element: charSpan, | |
| baseChar: getRandomChar(), | |
| changeTimer: Math.random() * 100 | |
| }); | |
| } | |
| container.appendChild(row); | |
| grid.push(rowData); | |
| } | |
| } | |
| function animate() { | |
| // Increased time increment for faster animation (was 0.03) | |
| time += 0.08; | |
| for (let y = 0; y < rows; y++) { | |
| for (let x = 0; x < cols; x++) { | |
| const cell = grid[y][x]; | |
| // Multiple wave patterns combined with faster multipliers | |
| const wave1 = Math.sin(x * 0.1 + time * 2.5) * 0.5; | |
| const wave2 = Math.sin(y * 0.08 + time * 3.2) * 0.3; | |
| const wave3 = Math.sin((x + y) * 0.05 + time * 1.8) * 0.4; | |
| const wave4 = Math.cos(x * 0.15 - time * 1.5) * Math.sin(y * 0.12 + time * 2) * 0.3; | |
| // Radial wave from center - faster | |
| const centerX = cols / 2; | |
| const centerY = rows / 2; | |
| const distFromCenter = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2); | |
| const radialWave = Math.sin(distFromCenter * 0.15 - time * 5) * 0.4; | |
| // Additional fast diagonal wave | |
| const diagonalWave = Math.sin((x - y) * 0.08 + time * 4) * 0.25; | |
| let combinedWave = wave1 + wave2 + wave3 + wave4 + radialWave + diagonalWave; | |
| // Calculate brightness based on wave | |
| const baseBrightness = 0.2 + (combinedWave + 1) * 0.3; | |
| const brightness = Math.min(1, baseBrightness); | |
| // Apply transformations | |
| const scale = 0.7 + (combinedWave + 1) * 0.25; | |
| const translateY = combinedWave * 5; | |
| // White color with varying opacity | |
| const alpha = Math.max(0.15, Math.min(1, brightness)); | |
| cell.element.style.color = `rgba(255, 255, 255, ${alpha})`; | |
| cell.element.style.transform = `translateY(${translateY}px) scale(${scale})`; | |
| // Randomly change characters - faster rate | |
| cell.changeTimer += 0.15; | |
| if (cell.changeTimer > 40 + Math.random() * 80) { | |
| cell.element.textContent = getRandomChar(); | |
| cell.changeTimer = 0; | |
| } | |
| // More frequent changes at wave peaks | |
| if (combinedWave > 0.7 && Math.random() < 0.2) { | |
| cell.element.textContent = getRandomChar(); | |
| } | |
| } | |
| } | |
| requestAnimationFrame(animate); | |
| } | |
| function init() { | |
| calculateGridSize(); | |
| createGrid(); | |
| animate(); | |
| } | |
| // Handle window resize | |
| let resizeTimeout; | |
| window.addEventListener('resize', () => { | |
| clearTimeout(resizeTimeout); | |
| resizeTimeout = setTimeout(() => { | |
| calculateGridSize(); | |
| createGrid(); | |
| }, 250); | |
| }); | |
| // Initialize | |
| init(); | |
| </script> | |
| </body> | |
| </html> |