feat: Add initial mess
This commit is contained in:
		
							parent
							
								
									1988edaafe
								
							
						
					
					
						commit
						59fa42e6c0
					
				
							
								
								
									
										
											BIN
										
									
								
								icons/folder.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icons/folder.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										
											BIN
										
									
								
								icons/notepad.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icons/notepad.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 843 B | 
							
								
								
									
										
											BIN
										
									
								
								icons/trash.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icons/trash.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 671 B | 
							
								
								
									
										15
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
| 	<meta charset="UTF-8" /> | ||||
| 	<meta name="viewport" content="width=device-width, initial-scale=1" /> | ||||
| 	<link rel="stylesheet" href="styles.css" /> | ||||
| 	<title>My Desktop Page</title> | ||||
| </head> | ||||
| <body> | ||||
| 	<div class="desktop"> | ||||
| 	</div> | ||||
| 	<script src="script.js"></script> | ||||
| </body> | ||||
| </html> | ||||
| 
 | ||||
							
								
								
									
										259
									
								
								script.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								script.js
									
									
									
									
									
										Normal file
									
								
							| @ -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", | ||||
| 				`<iframe src="https://98.js.org"></iframe>`, | ||||
| 				true, | ||||
| 				500, | ||||
| 				400 | ||||
| 			) | ||||
| 		}, | ||||
| 		{ | ||||
| 			label: "Notes", | ||||
| 			icon: "icons/notepad.png", | ||||
| 			width: 400, | ||||
| 			height: 300, | ||||
| 			action: () => | ||||
| 			openNewWindow( | ||||
| 				"Notes", | ||||
| 				`<textarea>hello...</textarea>`, | ||||
| 				true, | ||||
| 				400, | ||||
| 				300 | ||||
| 			) | ||||
| 		}, | ||||
| 		{ | ||||
| 			label: "Recycle Bin", | ||||
| 			icon: "icons/trash.png", | ||||
| 			width: 300, | ||||
| 			height: 200, | ||||
| 			action: () => | ||||
| 			openNewWindow( | ||||
| 				"Recycle Bin", | ||||
| 				`<p>Your trash goes here.</p>`, | ||||
| 				false, | ||||
| 				300, | ||||
| 				200 | ||||
| 			) | ||||
| 		}, | ||||
| 		{ | ||||
| 			label: "CSS Art", | ||||
| 			icon: "icons/folder.png", | ||||
| 			width: 600, | ||||
| 			height: 500, | ||||
| 			action: () => | ||||
| 			openNewWindow( | ||||
| 				"CSS Art", | ||||
| 				`<iframe src="https://tilde.town/~dozens/cssart/quarters.html"></iframe>`, | ||||
| 				true, | ||||
| 				600, | ||||
| 				600 | ||||
| 			) | ||||
| 		} | ||||
| 	]; | ||||
| 
 | ||||
| 	shortcutData.forEach(({ label, icon, action }) => { | ||||
| 		const shortcut = document.createElement("div"); | ||||
| 		shortcut.className = "shortcut"; | ||||
| 
 | ||||
| 		shortcut.innerHTML = ` | ||||
| 			<img src="${icon}" alt="${label}" /> | ||||
| 			<span>${label}</span> | ||||
| 		`;
 | ||||
| 
 | ||||
| 		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 = ` | ||||
| 	  <div class="titlebar"> | ||||
| 		<div class="title">${title}</div> | ||||
| 		<button class="close-btn" aria-label="Close window">×</button> | ||||
| 	  </div> | ||||
| 	  <div class="content">${contentHTML}</div> | ||||
| 	`;
 | ||||
| 
 | ||||
| 	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; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										156
									
								
								styles.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								styles.css
									
									
									
									
									
										Normal file
									
								
							| @ -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; } | ||||
| 
 | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user