From 59fa42e6c00c5cb11497c6bb826d55f4b1b92abb Mon Sep 17 00:00:00 2001 From: cymen Date: Tue, 26 Aug 2025 21:00:00 +0200 Subject: [PATCH] feat: Add initial mess --- icons/folder.png | Bin 0 -> 1205 bytes icons/notepad.png | Bin 0 -> 843 bytes icons/trash.png | Bin 0 -> 671 bytes index.html | 15 +++ script.js | 259 ++++++++++++++++++++++++++++++++++++++++++++++ styles.css | 156 ++++++++++++++++++++++++++++ 6 files changed, 430 insertions(+) create mode 100644 icons/folder.png create mode 100644 icons/notepad.png create mode 100644 icons/trash.png create mode 100644 index.html create mode 100644 script.js create mode 100644 styles.css diff --git a/icons/folder.png b/icons/folder.png new file mode 100644 index 0000000000000000000000000000000000000000..6cd990824a87a16e8ce870fd5432485b416afd6a GIT binary patch literal 1205 zcmV;m1WNmfP);|{r&&^|Nj2}{{Q_11Oz81 zCnhH+CnYEA>+Ami{x>%_*Vfk#4-X$7A2l^M*4Nh$4-WtS{n66UJwHE2Mn*wFL)F#P zH#Iln;^I3yJ55bZeSCcm4G;10@mX10Nl8gPKRv9htaWvDWo2YDF*D@mGBZCvKPDz7*x1;6dwYwEi~aro z9UmR>@bVNC7T4F;#>U3_`uapfM8LqnlarGlA07Pv|HHw-v$3&EOiXKOYqYeq2nq;( zetd9naP#x=YinwId3utQll}kw($Lf0-QC{a-ZeEfLPJA&czG2S6;@VOHa0e+qoaFz zdy|rr|Nr~|0095~0RQ~}{r>>}{{a8~0sZ~{{r~>|{{sI100062|NQ~~{{jE}0R8_0 z00092{Q~~}0RI00{r>#{000000sZ~}0ssK~|NZ^`{{Q^_hG_s(00080NklitD6vD4v@+E6WeI^NIIxfCWz+F<8^+aSx}fX zLF(ZOYQe(ZMT^yv?xlUpmao9dRjb#mHS5-I*eFsIfUHrQHrp-zwyS&VHf$fjj-9)9 z@7cR=e}eizd;7sdgG0dKBkJg};p6tiNt`-eES@<#GO9~d=v=3=g~6dT&R;;+#o{G( zc|csbs_9lE*PtzM9ky)IcLO(XQNZm{+_|gn-N%E6=|_(hL+vpYV&%zjfA3QYc=r6o z%U9U_y7=a;e)rzXP)0tvBWyy96Mhh=vB#YQMe!#ImujT8@XD8p}8-7LV3({5>VN%Rp$reabY8h z0`ZOge3hwS`g=g!5937afa8BKi_{0ye1z0HRRBE7`Km&Skj zZiEgK7lS0MAw_6 T)}O#Z00000NkvXXu0mjf0wQ9) literal 0 HcmV?d00001 diff --git a/icons/notepad.png b/icons/notepad.png new file mode 100644 index 0000000000000000000000000000000000000000..0426663464c104c990455c5088a691c4eae64e87 GIT binary patch literal 843 zcmV-R1GM~!P)A%0f|Nj3aCnYE-DERpJ|Ns84udjc9 ze?C4wb#--xg@x|!?om-uMMXtAIy$bdt|KEOo12@~*49TyM@dOZLqkK<)YOiSjyX9w zQc_a(_VznFJM!}K<>lpgczA$;f$Z$;8X6k)_4SXBk32j)*x1;{#>PTILKYSlt*x!$ z;o+T~on2jB#l^)nH8j%F(vFXh{r&t12natvKQJ&dZ*OllHa3Weh~VJh{{8+nH8r}r zy2Ql9Gcz;({Qe3G3jF;1+uPfYj*K86AkEFqdwY9lu*=KK zkdTmmet!P`{%~+`Sy@@QxVXv5$r%|LhlhtiKtMr3LC((3PEJnn@bCct008~~0RI62 z{{R5}009320{;L4{{a9200001000640051)kI(=B0kBC#K~#90eUoWd(?A%7=O)8Q zAwW#o7ok#C*-=qcl(j|nMG+K~ZCa=b{Qob^noLB!=QO7??=$yZG9d(39uoQTLE?v1 zYVn^v>bOXtiai3VGbUD3>!5)K>gpQ=5E8kjkD~`EsJALHcvkFL|R{&O_WpI%)4eNaZBJ4yea7)iaO1vOag`waigEfc>x4AuKg{f_B`$2#HGsOcP#g0TRZI$+ zq)5eomAUj68JrqS(K4s6vd3LWfX1U{fhB*d8l5%~*b~}bncT>!lVtQBZs8D2@>E_J zrwI2gNyJM={Q$6)#&J&{y1UW-w@hym^|k2Y3Dq5?E`;oYrmtO)T8R|CTjn346!(1O VR68RIal8Nk002ovPDHLkV1oJ-oIn5o literal 0 HcmV?d00001 diff --git a/icons/trash.png b/icons/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..3cbf73d6a690255b394083dd33f9c8474b0ae336 GIT binary patch literal 671 zcmV;Q0$}}#P)ySqq8 zNLN=^F)=az{{H>{{~8(^^z`(`#>TR;ve3}b78Vxx`1q}?t>NL}8yg$)^71b)FV)r6 zOG`^$TwYaGRVODWZ*OllHa3Weh~VJh#Kgq^|NTEdK2uXuR#sM)mX_Mu+S}XPj*pHY zARx`n%~MfR|Nj5GySci$x`Ts*etv#%aB!QOo3OC3EG#TVMMZUWbwEHsPEJnn@bLcs z|NZ^{|Ns8Lz`+0g|G>b(!N9=4!N9=6z`(%5{r~>_|NsC0{Qv#^ifgu70004ANkl`Eyy1i5GV7I%s z53dXa2dd9Xha5Npj!$sf0nW~Q7v5!vpkzB-aiDh1`n}do6SsGQw*g-|+&?^4+Wn{Q z^UJFXfFXiTEGjgMh3N8g@lCF=K}^g1H*!oss0P^21w!^ZGUZ22hz2+b2PxhDfn#`~i>&K9C|58fO3i002ovPDHLk FV1ma1R5t(s literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..10ff36d --- /dev/null +++ b/index.html @@ -0,0 +1,15 @@ + + + + + + + My Desktop Page + + +
+
+ + + + diff --git a/script.js b/script.js new file mode 100644 index 0000000..b917427 --- /dev/null +++ b/script.js @@ -0,0 +1,259 @@ +let highestZIndex = 100; + +function init() { + const desktop = document.querySelector(".desktop"); + + const shortcutData = [ + { + label: "My Files", + icon: "icons/folder.png", + width: 500, + height: 400, + action: () => + openNewWindow( + "My Files", + ``, + true, + 500, + 400 + ) + }, + { + label: "Notes", + icon: "icons/notepad.png", + width: 400, + height: 300, + action: () => + openNewWindow( + "Notes", + ``, + true, + 400, + 300 + ) + }, + { + label: "Recycle Bin", + icon: "icons/trash.png", + width: 300, + height: 200, + action: () => + openNewWindow( + "Recycle Bin", + `

Your trash goes here.

`, + false, + 300, + 200 + ) + }, + { + label: "CSS Art", + icon: "icons/folder.png", + width: 600, + height: 500, + action: () => + openNewWindow( + "CSS Art", + ``, + true, + 600, + 600 + ) + } + ]; + + shortcutData.forEach(({ label, icon, action }) => { + const shortcut = document.createElement("div"); + shortcut.className = "shortcut"; + + shortcut.innerHTML = ` + ${label} + ${label} + `; + + shortcut.addEventListener("dblclick", action); + document.querySelector(".desktop").appendChild(shortcut); + }); +} + +init(); + +function openNewWindow(title, contentHTML, fullSizeContent = false, width = 300, height = 200) { + const newWin = document.createElement("div"); + newWin.className = "window"; + + const viewportWidth = window.innerWidth; + const viewportHeight = window.innerHeight; + const randomLeft = Math.floor(Math.random() * (viewportWidth - 320)); + const randomTop = Math.floor(Math.random() * (viewportHeight - 200)); + newWin.style.left = `${randomLeft}px`; + newWin.style.top = `${randomTop}px`; + + newWin.innerHTML = ` +
+
${title}
+ +
+
${contentHTML}
+ `; + + const resizers = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w']; + resizers.forEach(pos => { + const resizer = document.createElement("div"); + resizer.className = `resizer ${pos}`; + newWin.appendChild(resizer); + }); + + document.body.appendChild(newWin); + + bringToFront(newWin); + + const content = newWin.querySelector(".content"); + content.style.width = `${width}px`; + content.style.height = `${height}px`; + + if (fullSizeContent) { + content.style.padding = "0"; + } + + // Bring window to front when clicked + newWin.addEventListener("mousedown", () => { + bringToFront(newWin); + }); + + // Dragging logic + const titlebar = newWin.querySelector(".titlebar"); + let isDragging = false; + let offsetX = 0; + let offsetY = 0; + + titlebar.addEventListener("mousedown", (e) => { + if (e.target.classList.contains("close-btn")) return; + isDragging = true; + const rect = newWin.getBoundingClientRect(); + offsetX = e.clientX - rect.left; + offsetY = e.clientY - rect.top; + document.body.style.userSelect = 'none'; + }); + + document.addEventListener("mousemove", (e) => { + if (!isDragging) return; + newWin.style.left = `${e.clientX - offsetX}px`; + newWin.style.top = `${e.clientY - offsetY}px`; + }); + + document.addEventListener("mouseup", () => { + if (isDragging) { + isDragging = false; + document.body.style.userSelect = ''; + } + }); + + // Close button logic + const closeBtn = newWin.querySelector(".close-btn"); + closeBtn.addEventListener("click", () => { + newWin.remove(); + }); + + let isResizing = false; + let currentResizer = null; + + const minWidth = 200; + const minHeight = 150; + + const startResize = (e, resizer) => { + e.preventDefault(); + isResizing = true; + currentResizer = resizer; + + const rect = newWin.getBoundingClientRect(); + newWin.dataset.startX = e.clientX; + newWin.dataset.startY = e.clientY; + newWin.dataset.startWidth = rect.width; + newWin.dataset.startHeight = rect.height; + newWin.dataset.startLeft = rect.left; + newWin.dataset.startTop = rect.top; + + document.body.style.userSelect = "none"; + }; + + const onMouseMove = (e) => { + if (!isResizing || !currentResizer) return; + + const dx = e.clientX - newWin.dataset.startX; + const dy = e.clientY - newWin.dataset.startY; + + let newWidth = parseFloat(newWin.dataset.startWidth); + let newHeight = parseFloat(newWin.dataset.startHeight); + let newLeft = parseFloat(newWin.dataset.startLeft); + let newTop = parseFloat(newWin.dataset.startTop); + + switch (currentResizer) { + case 'e': + newWidth += dx; + break; + case 's': + newHeight += dy; + break; + case 'se': + newWidth += dx; + newHeight += dy; + break; + case 'w': + newWidth -= dx; + newLeft += dx; + break; + case 'n': + newHeight -= dy; + newTop += dy; + break; + case 'nw': + newWidth -= dx; + newLeft += dx; + newHeight -= dy; + newTop += dy; + break; + case 'ne': + newWidth += dx; + newHeight -= dy; + newTop += dy; + break; + case 'sw': + newWidth -= dx; + newLeft += dx; + newHeight += dy; + break; + } + + if (newWidth >= minWidth) { + newWin.style.width = `${newWidth}px`; + newWin.style.left = `${newLeft}px`; + content.style.width = `${newWidth}px`; + } + if (newHeight >= minHeight) { + newWin.style.height = `${newHeight}px`; + newWin.style.top = `${newTop}px`; + content.style.height = `${newHeight - titlebar.offsetHeight}px`; + } + }; + + const stopResize = () => { + isResizing = false; + currentResizer = null; + document.body.style.userSelect = ""; + }; + + resizers.forEach(pos => { + const el = newWin.querySelector(`.resizer.${pos}`); + el.addEventListener("mousedown", (e) => startResize(e, pos)); + }); + + document.addEventListener("mousemove", onMouseMove); + document.addEventListener("mouseup", stopResize); + + function bringToFront(win) { + highestZIndex++; + win.style.zIndex = highestZIndex; + } +} + diff --git a/styles.css b/styles.css new file mode 100644 index 0000000..774ac19 --- /dev/null +++ b/styles.css @@ -0,0 +1,156 @@ +body { + font-family: Tahoma, sans-serif; + margin: 2rem; + background-color: #e0b0ff; +} + +.window { + position: absolute; + border: 1px solid #555; + border-radius: 10px; + box-shadow: + 0 4px 8px rgba(0, 0, 0, 0.3), /* Soft outer shadow */ + inset 0 0 5px rgba(255, 255, 255, 0.1); /* Inner highlight for 3D */ + overflow: hidden; + background-color: #f0f0f0; + font-family: sans-serif; + cursor: default; + display: flex; + flex-direction: column; + height: auto; /* allow flexible height */ + box-sizing: border-box; +} + +.titlebar .title { + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.titlebar { + width: 100%; + height: 30px; + background: linear-gradient(to bottom, #8a2be2, #6a1dbf); + color: white; + display: flex; + justify-content: space-between; + align-items: center; + padding-left: 10px; + box-sizing: border-box; + cursor: move; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3); +} + +.content { + padding: 10px; + background: #C0C0C0; + overflow: auto; + box-sizing: border-box; +} + +.close-btn { + background: transparent; + border: none; + color: white; + font-size: 20px; + margin-right: 8px; + cursor: pointer; + transition: color 0.2s ease; +} + +.close-btn:hover { + color: #ffaaaa; +} + +.desktop { + display: grid; + grid-template-columns: repeat(auto-fill, 80px); + grid-auto-rows: 100px; + gap: 20px; + padding: 20px; + position: absolute; + top: 0; + left: 0; + z-index: 0; +} + +.shortcut { + width: 80px; + text-align: center; + color: black; + font-size: 12px; + font-family: sans-serif; + margin: 10px; + cursor: pointer; + user-select: none; +} + +.shortcut img { + width: 32px; + height: 32px; + display: block; + margin: 0 auto 5px; +} + +.shortcut span { + display: block; + text-shadow: 1px 1px 2px white; +} + +.content textarea { + font-family: monospace; + padding: 8px; + resize: none; + outline: none; +} + +.content iframe, +.content textarea { + width: 100%; + height: 100%; + border-radius: 6px; + border: none; +} + +.window .resizer { + position: absolute; + background: transparent; + z-index: 10; +} + +/* Corners */ +.window .resizer.nw, .window .resizer.ne, +.window .resizer.sw, .window .resizer.se { + width: 10px; + height: 10px; +} + +.window .resizer.nw { top: 0; left: 0; cursor: nw-resize; } +.window .resizer.ne { top: 0; right: 0; cursor: ne-resize; } +.window .resizer.sw { bottom: 0; left: 0; cursor: sw-resize; } +.window .resizer.se { bottom: 0; right: 0; cursor: se-resize; } + +/* Sides */ +.window .resizer.n, .window .resizer.s { + height: 6px; + left: 0; + right: 0; + cursor: ns-resize; +} + +.window .resizer.n { top: 0; } +.window .resizer.s { bottom: 0; } + +.window .resizer.e, .window .resizer.w { + width: 6px; + top: 0; + bottom: 0; + cursor: ew-resize; +} + +.window .resizer.e { right: 0; } +.window .resizer.w { left: 0; } +