| |
| let highestZ = 100; |
| let activeWindow = null; |
| let dragOffset = { x: 0, y: 0 }; |
| let isDragging = false; |
| let currentDragWindow = null; |
|
|
| |
| document.addEventListener('DOMContentLoaded', () => { |
| initializeWindows(); |
| startClock(); |
| addMatrixEffect(); |
| }); |
|
|
| |
| function startClock() { |
| const clock = document.getElementById('clock'); |
| setInterval(() => { |
| const now = new Date(); |
| clock.textContent = now.toLocaleTimeString('en-US', { |
| hour12: false, |
| hour: '2-digit', |
| minute: '2-digit', |
| second: '2-digit' |
| }); |
| }, 1000); |
| } |
|
|
| |
| function initializeWindows() { |
| const windows = document.querySelectorAll('.window'); |
| |
| windows.forEach(window => { |
| const header = window.querySelector('.window-header'); |
| |
| header.addEventListener('mousedown', (e) => startDrag(e, window)); |
| header.addEventListener('touchstart', (e) => startDrag(e, window), { passive: false }); |
| |
| |
| window.addEventListener('mousedown', () => bringToFront(window)); |
| }); |
|
|
| document.addEventListener('mousemove', drag); |
| document.addEventListener('touchmove', drag, { passive: false }); |
| document.addEventListener('mouseup', stopDrag); |
| document.addEventListener('touchend', stopDrag); |
| } |
|
|
| function startDrag(e, window) { |
| if (window.classList.contains('minimized')) return; |
| |
| isDragging = true; |
| currentDragWindow = window; |
| window.classList.add('dragging'); |
| bringToFront(window); |
| |
| const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX; |
| const clientY = e.type.includes('touch') ? e.touches[0].clientY : e.clientY; |
| const rect = window.getBoundingClientRect(); |
| |
| dragOffset.x = clientX - rect.left; |
| dragOffset.y = clientY - rect.top; |
| |
| e.preventDefault(); |
| } |
|
|
| function drag(e) { |
| if (!isDragging || !currentDragWindow) return; |
| |
| const clientX = e.type.includes('touch') ? e.touches[0].clientX : e.clientX; |
| const clientY = e.type.includes('touch') ? e.touches[0].clientY : e.clientY; |
| |
| let newX = clientX - dragOffset.x; |
| let newY = clientY - dragOffset.y; |
| |
| |
| const maxX = window.innerWidth - currentDragWindow.offsetWidth; |
| const maxY = window.innerHeight - currentDragWindow.offsetHeight - 48; |
| |
| newX = Math.max(0, Math.min(newX, maxX)); |
| newY = Math.max(48, Math.min(newY, maxY)); |
| |
| currentDragWindow.style.left = newX + 'px'; |
| currentDragWindow.style.top = newY + 'px'; |
| |
| e.preventDefault(); |
| } |
|
|
| function stopDrag() { |
| if (currentDragWindow) { |
| currentDragWindow.classList.remove('dragging'); |
| } |
| isDragging = false; |
| currentDragWindow = null; |
| } |
|
|
| function bringToFront(window) { |
| highestZ++; |
| window.style.zIndex = highestZ; |
| |
| |
| document.querySelectorAll('.window').forEach(w => w.classList.remove('active')); |
| window.classList.add('active'); |
| } |
|
|
| |
| function minimizeWindow(windowId) { |
| const window = document.querySelector(`[data-window="${windowId}"]`); |
| if (window) { |
| window.classList.add('minimized'); |
| updateTaskbarButton(windowId, false); |
| } |
| } |
|
|
| function closeWindow(windowId) { |
| const window = document.querySelector(`[data-window="${windowId}"]`); |
| if (window) { |
| window.style.display = 'none'; |
| updateTaskbarButton(windowId, false); |
| |
| |
| window.style.animation = 'none'; |
| setTimeout(() => { |
| window.style.animation = ''; |
| }, 10); |
| } |
| } |
|
|
| function openWindow(windowId) { |
| const window = document.querySelector(`[data-window="${windowId}"]`); |
| if (window) { |
| window.classList.remove('minimized'); |
| window.style.display = 'block'; |
| bringToFront(window); |
| updateTaskbarButton(windowId, true); |
| |
| |
| window.style.animation = 'windowOpen 0.3s ease-out'; |
| } |
| } |
|
|
| function updateTaskbarButton(windowId, isActive) { |
| const buttons = document.querySelectorAll('.taskbar-btn'); |
| buttons.forEach(btn => { |
| if (btn.getAttribute('onclick').includes(windowId)) { |
| if (isActive) { |
| btn.classList.add('active'); |
| } else { |
| btn.classList.remove('active'); |
| } |
| } |
| }); |
| } |
|
|
| |
| function addMatrixEffect() { |
| const chars = "0123456789ABCDEF"; |
| const desktop = document.getElementById('desktop'); |
| |
| |
| setInterval(() => { |
| if (Math.random() > 0.9) { |
| createFallingChar(); |
| } |
| }, 500); |
| } |
|
|
| function createFallingChar() { |
| const char = document.createElement('div'); |
| char.textContent = Math.random() > 0.5 ? '0' : '1'; |
| char.style.position = 'absolute'; |
| char.style.left = Math.random() * 100 + '%'; |
| char.style.top = '-20px'; |
| char.style.color = 'rgba(245, 158, 11, 0.2)'; |
| char.style.fontFamily = 'JetBrains Mono, monospace'; |
| char.style.fontSize = '14px'; |
| char.style.pointerEvents = 'none'; |
| char.style.zIndex = '1'; |
| char.style.animation = 'fall 3s linear forwards'; |
| |
| document.getElementById('desktop').appendChild(char); |
| |
| setTimeout(() => char.remove(), 3000); |
| } |
|
|
| |
| const style = document.createElement('style'); |
| style.textContent = ` |
| @keyframes fall { |
| to { |
| transform: translateY(100vh); |
| opacity: 0; |
| } |
| } |
| `; |
| document.head.appendChild(style); |
|
|
| |
| document.addEventListener('keydown', (e) => { |
| |
| if (e.altKey && e.key === 'w') { |
| const active = document.querySelector('.window.active'); |
| if (active) { |
| const windowId = active.getAttribute('data-window'); |
| closeWindow(windowId); |
| } |
| } |
| |
| |
| if (e.key === 'Escape') { |
| const active = document.querySelector('.window.active'); |
| if (active) { |
| const windowId = active.getAttribute('data-window'); |
| minimizeWindow(windowId); |
| } |
| } |
| }); |
|
|
| |
| document.addEventListener('selectstart', (e) => { |
| if (isDragging) { |
| e.preventDefault(); |
| } |
| }); |
|
|
| |
| document.querySelectorAll('.window-header').forEach(header => { |
| header.addEventListener('dblclick', (e) => { |
| const window = header.closest('.window'); |
| if (window.style.width === '90%') { |
| |
| window.style.width = ''; |
| window.style.height = ''; |
| window.style.left = '10%'; |
| window.style.top = '10%'; |
| } else { |
| |
| window.style.width = '90%'; |
| window.style.height = '80%'; |
| window.style.left = '5%'; |
| window.style.top = '5%'; |
| } |
| }); |
| }); |