/* hover effect: modern glow */ .desktop-icon:hover .icon-graphic background: rgba(50, 55, 70, 0.8); transform: scale(1.02); box-shadow: 0 10px 22px rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255,255,255,0.3); border-color: rgba(255,215,150,0.6);
const desktopEl = document.getElementById('desktopContainer');
// clamp all icon positions to visible area (on window resize) function clampIconPositions() const containerRect = desktopEl.getBoundingClientRect(); let changed = false; iconsState.forEach(icon => const maxX = Math.max(20, containerRect.width - 95); const maxY = Math.max(20, containerRect.height - 85); if (icon.x > maxX) icon.x = maxX; changed = true; if (icon.y > maxY) icon.y = maxY; changed = true; if (icon.x < 5) icon.x = 5; changed = true; if (icon.y < 5) icon.y = 5; changed = true; ); if (changed) persistPositions(); renderAllIcons(); // re-render with updated coords else // still re-render to keep consistent? we call after resize anyway renderAllIcons(); small icons on desktop
// ---- Drag & Drop logic (mouse) ---- function onMouseDown(e, icon) if (e.button !== 0) return; // left click only for dragging e.preventDefault(); dragTarget = icon; const iconDiv = e.currentTarget; activeIconElement = iconDiv; // bring to front iconDiv.style.zIndex = currentZIndex++; const startRect = iconDiv.getBoundingClientRect(); initialLeft = startRect.left; initialTop = startRect.top; dragStartX = e.clientX; dragStartY = e.clientY; const onMouseMove = (moveEvent) => if (!dragTarget) return; moveEvent.preventDefault(); const dx = moveEvent.clientX - dragStartX; const dy = moveEvent.clientY - dragStartY; let newX = initialLeft + dx; let newY = initialTop + dy; // boundary constraints relative to desktop container const containerRect = desktopEl.getBoundingClientRect(); const maxX = containerRect.width - 88; const maxY = containerRect.height - 78; newX = Math.min(maxX, Math.max(2, newX)); newY = Math.min(maxY, Math.max(2, newY)); if (activeIconElement) activeIconElement.style.left = `$newXpx`; activeIconElement.style.top = `$newYpx`; ; const onMouseUp = (upEvent) => if (dragTarget && activeIconElement) // commit final position from actual element style const leftVal = parseFloat(activeIconElement.style.left); const topVal = parseFloat(activeIconElement.style.top); if (!isNaN(leftVal) && !isNaN(topVal)) dragTarget.x = leftVal; dragTarget.y = topVal; persistPositions(); dragTarget = null; activeIconElement = null; document.removeEventListener('mousemove', onMouseMove); document.removeEventListener('mouseup', onMouseUp); removeContextMenu(); // also remove menu while dragging ; document.addEventListener('mousemove', onMouseMove); document.addEventListener('mouseup', onMouseUp); removeContextMenu(); // dismiss any open context menu when starting drag
/* desktop right-click hint (optional) */ .status-note position: fixed; bottom: 12px; right: 16px; background: rgba(0,0,0,0.4); padding: 4px 10px; border-radius: 30px; font-size: 10px; color: #ccc; font-family: monospace; pointer-events: none; z-index: 99; </style> </head> <body> /* hover effect: modern glow */
/* individual icon wrapper — draggable, positioned absolutely */ .desktop-icon position: absolute; width: 85px; display: flex; flex-direction: column; align-items: center; text-align: center; cursor: grab; transition: transform 0.05s ease, filter 0.1s; z-index: 10; will-change: left, top;
// reset positions to a nice grid (based on current desktop size) function resetToDefaultGrid() const containerRect = desktopEl.getBoundingClientRect(); const marginX = 35; const marginY = 35; const colSpacing = 110; const rowSpacing = 120; const columns = 3; iconsState.forEach((icon, idx) => const col = idx % columns; const row = Math.floor(idx / columns); let x = marginX + col * colSpacing; let y = marginY + row * rowSpacing; // ensure within viewport borders const maxX = Math.max(20, containerRect.width - 100); const maxY = Math.max(20, containerRect.height - 90); x = Math.min(maxX, Math.max(10, x)); y = Math.min(maxY, Math.max(10, y)); icon.x = x; icon.y = y; ); persistPositions(); renderAllIcons(); showToast("✨ Icons rearranged to default grid", 1200); box-shadow: 0 10px 22px rgba(0
// double-click handler: open action (simulate app launch) function onDoubleClickIcon(icon) // add bounce animation class const iconElement = document.querySelector(`.desktop-icon[data-id='$icon.id']`); if (iconElement) iconElement.classList.add('icon-bounce'); setTimeout(() => iconElement.classList.remove('icon-bounce'), 220); // custom action based on icon id let message = `📂 Opened "$icon.name"`; if (icon.id === 'app_music') message = `🎵 Now playing: lo-fi desktop waves · ♪`; else if (icon.id === 'app_terminal') message = `💻 $> welcome ~ Desktop ready.`; else if (icon.id === 'app_settings') message = `⚙️ Display preferences: icon drag enabled.`; else if (icon.id === 'trash_bin') message = `🗑️ Trash is empty · double-click to delete? (right-click to remove any icon)`; else if (icon.id === 'folder_docs') message = `📄 Documents · nothing here yet.`; else if (icon.id === 'folder_pics') message = `🌄 Gallery preview: beautiful canvas desktop.`; showToast(message, 1600); console.log(`[Launch] $icon.name double-clicked`);