mirror of
https://github.com/p0yoy01dev/njz_is_five
synced 2026-06-01 21:45:28 +02:00
225 lines
14 KiB
HTML
225 lines
14 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||
<title>Windows 7 Apps Demo</title>
|
||
<style>
|
||
:root{--taskbar:56px;--text:#eaf2ff;--muted:#bed3f1;--bg1:#081626;--bg2:#0d2f50;--glass:rgba(255,255,255,.08)}
|
||
*{box-sizing:border-box}
|
||
html,body{height:100%;margin:0;font-family:"Segoe UI",Arial,sans-serif;color:var(--text);overflow:hidden;background:linear-gradient(135deg,var(--bg1),var(--bg2))}
|
||
.wallpaper{position:fixed;inset:0;display:grid;place-items:center;pointer-events:none}
|
||
.glow{width:700px;height:340px;opacity:.08;filter:blur(20px);transform:rotate(-8deg);border-radius:20px;background:linear-gradient(90deg,#0bb1ff,#2fbf54,#ffcb40,#ff4f4f)}
|
||
|
||
.desktop{position:fixed;inset:0 0 var(--taskbar) 0;padding:18px}
|
||
.desktop-icons{display:flex;gap:16px;flex-wrap:wrap;align-content:flex-start;width:360px}
|
||
.icon{width:92px;padding:10px;border-radius:10px;text-align:center;cursor:pointer;background:rgba(0,0,0,.15);border:1px solid rgba(255,255,255,.1)}
|
||
.icon:hover{background:rgba(255,255,255,.12)}
|
||
.icon .emoji{font-size:30px;display:block;margin-bottom:8px}
|
||
.icon .label{font-size:12px}
|
||
|
||
.window{position:absolute;width:min(960px,calc(100vw - 60px));height:min(620px,calc(100vh - 120px));top:50px;left:60px;border-radius:10px;overflow:hidden;background:rgba(7,15,30,.78);border:1px solid rgba(255,255,255,.16);box-shadow:0 20px 60px rgba(0,0,0,.55);display:none}
|
||
.window.visible{display:flex;flex-direction:column}
|
||
.titlebar{height:42px;display:flex;align-items:center;gap:10px;padding:8px 10px;background:linear-gradient(180deg,rgba(255,255,255,.11),rgba(255,255,255,.03));border-bottom:1px solid rgba(255,255,255,.13);cursor:move}
|
||
.title{font-size:14px;font-weight:700}
|
||
.controls{margin-left:auto;display:flex;gap:7px}
|
||
.controls button{width:42px;height:28px;border:0;border-radius:6px;cursor:pointer;font-weight:700}
|
||
.min{background:#dcecff}.max{background:#2a88d8;color:#fff}.close{background:#d55353;color:#fff}
|
||
|
||
.explorer-shell{display:grid;grid-template-columns:220px 1fr;height:100%}
|
||
.sidebar{border-right:1px solid rgba(255,255,255,.12);padding:10px;background:rgba(255,255,255,.03)}
|
||
.node{padding:7px;border-radius:6px;cursor:pointer;font-size:13px}.node:hover{background:rgba(255,255,255,.1)}
|
||
.explorer-main{display:flex;flex-direction:column}
|
||
.toolbar,.pathbar{padding:8px 10px;border-bottom:1px solid rgba(255,255,255,.12);display:flex;gap:8px;align-items:center}
|
||
.toolbar button,.pathbar button{padding:6px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.08);color:var(--text);cursor:pointer}
|
||
.crumb{background:none;border:none;color:#d8ebff;cursor:pointer}
|
||
.list{padding:10px;display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;overflow:auto}
|
||
.item{padding:10px;border-radius:8px;border:1px solid rgba(255,255,255,.15);background:rgba(7,18,33,.66);cursor:pointer}
|
||
.item.sel{outline:2px solid #8ec4ff}
|
||
.meta{font-size:12px;color:var(--muted);margin-top:4px}
|
||
.status{padding:7px 10px;font-size:12px;color:var(--muted);border-top:1px solid rgba(255,255,255,.12)}
|
||
|
||
.browser-toolbar{display:flex;gap:8px;padding:10px;border-bottom:1px solid rgba(255,255,255,.12)}
|
||
.browser-toolbar input{flex:1;padding:8px;border-radius:6px;border:1px solid rgba(255,255,255,.2);background:rgba(0,0,0,.25);color:#fff}
|
||
.browser-toolbar button{padding:8px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.08);color:#fff;cursor:pointer}
|
||
iframe{width:100%;height:100%;border:0;background:#fff}
|
||
|
||
.editor-toolbar{display:flex;gap:8px;padding:10px;border-bottom:1px solid rgba(255,255,255,.12)}
|
||
.editor-toolbar input,.editor-toolbar button{padding:7px 10px;border-radius:6px;border:1px solid rgba(255,255,255,.2);background:rgba(255,255,255,.08);color:#fff}
|
||
#editor{flex:1;background:#071423;color:#d7ebff;border:0;padding:12px;font-family:Consolas,monospace;resize:none}
|
||
|
||
.taskbar{position:fixed;left:8px;right:8px;bottom:8px;height:calc(var(--taskbar) - 10px);border-radius:12px;display:flex;align-items:center;justify-content:space-between;padding:8px;background:linear-gradient(180deg,rgba(6,13,25,.65),rgba(3,7,14,.85));box-shadow:0 10px 30px rgba(0,0,0,.55)}
|
||
.task-left{display:flex;gap:8px;align-items:center}
|
||
.start{padding:8px 12px;border-radius:8px;background:rgba(255,255,255,.1);font-weight:700}
|
||
.task-app{width:44px;height:36px;border-radius:8px;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.08);color:#fff;cursor:pointer}
|
||
#clock{font-size:13px;color:#d8ebff}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="wallpaper"><div class="glow"></div></div>
|
||
|
||
<main class="desktop">
|
||
<section class="desktop-icons">
|
||
<div class="icon" data-open="explorer"><span class="emoji">📁</span><span class="label">Explorer</span></div>
|
||
<div class="icon" data-open="browser"><span class="emoji">🌐</span><span class="label">Browser</span></div>
|
||
<div class="icon" data-open="editor"><span class="emoji">📝</span><span class="label">Text Editor</span></div>
|
||
</section>
|
||
|
||
<section class="window visible" id="explorer-window" style="z-index:5">
|
||
<div class="titlebar"><span>📁</span><span class="title">Windows Explorer</span>
|
||
<div class="controls"><button class="min" data-min="explorer-window">−</button><button class="max" data-max="explorer-window">▢</button><button class="close" data-close="explorer-window">✕</button></div>
|
||
</div>
|
||
<div class="explorer-shell">
|
||
<aside class="sidebar">
|
||
<div class="node" data-path="/">🖥️ Computer</div>
|
||
<div class="node" data-path="/Music">🎵 Music</div>
|
||
<div class="node" data-path="/Music/NewJeans">💿 NewJeans</div>
|
||
<div class="node" data-path="/Music/Blackpink">💿 Blackpink</div>
|
||
</aside>
|
||
<div class="explorer-main">
|
||
<div class="toolbar">
|
||
<button id="up-btn">Up</button>
|
||
<button id="new-folder-btn">New Folder</button>
|
||
<button id="new-file-btn">New Text File</button>
|
||
<button id="rename-btn">Rename</button>
|
||
<button id="delete-btn">Delete</button>
|
||
</div>
|
||
<div class="pathbar" id="pathbar"></div>
|
||
<div class="list" id="file-list"></div>
|
||
<div class="status" id="status">Ready</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="window" id="browser-window" style="top:85px;left:110px;z-index:4">
|
||
<div class="titlebar"><span>🌐</span><span class="title">Browser</span>
|
||
<div class="controls"><button class="min" data-min="browser-window">−</button><button class="max" data-max="browser-window">▢</button><button class="close" data-close="browser-window">✕</button></div>
|
||
</div>
|
||
<div class="browser-toolbar">
|
||
<input id="address" value="https://example.com" />
|
||
<button id="go-btn">Go</button>
|
||
</div>
|
||
<iframe id="browser-frame" src="https://example.com"></iframe>
|
||
</section>
|
||
|
||
<section class="window" id="editor-window" style="top:120px;left:160px;z-index:3;height:min(560px,calc(100vh - 150px))">
|
||
<div class="titlebar"><span>📝</span><span class="title">Text Editor</span>
|
||
<div class="controls"><button class="min" data-min="editor-window">−</button><button class="max" data-max="editor-window">▢</button><button class="close" data-close="editor-window">✕</button></div>
|
||
</div>
|
||
<div class="editor-toolbar">
|
||
<input id="note-name" value="note.txt" />
|
||
<button id="save-note">Save</button>
|
||
<button id="load-note">Load</button>
|
||
</div>
|
||
<textarea id="editor">Write something here...</textarea>
|
||
</section>
|
||
</main>
|
||
|
||
<footer class="taskbar">
|
||
<div class="task-left">
|
||
<div class="start">Start</div>
|
||
<button class="task-app" data-open="explorer" title="Explorer">📁</button>
|
||
<button class="task-app" data-open="browser" title="Browser">🌐</button>
|
||
<button class="task-app" data-open="editor" title="Text Editor">📝</button>
|
||
</div>
|
||
<div id="clock"></div>
|
||
</footer>
|
||
|
||
<script>
|
||
const fs = { type:'folder', children:{ Music:{ type:'folder', children:{
|
||
NewJeans:{ type:'folder', children:{
|
||
'Attention.mp3':{type:'file',size:'7.0 MB'}, 'Hype Boy.mp3':{type:'file',size:'6.8 MB'}, 'Ditto.mp3':{type:'file',size:'7.2 MB'}, 'OMG.mp3':{type:'file',size:'6.5 MB'}, 'Super Shy.mp3':{type:'file',size:'6.2 MB'}
|
||
}},
|
||
Blackpink:{ type:'folder', children:{
|
||
'DDU-DU DDU-DU.mp3':{type:'file',size:'7.3 MB'}, 'How You Like That.mp3':{type:'file',size:'7.1 MB'}, 'Kill This Love.mp3':{type:'file',size:'7.0 MB'}, 'Pink Venom.mp3':{type:'file',size:'6.9 MB'}, 'Shut Down.mp3':{type:'file',size:'6.7 MB'}
|
||
}}
|
||
}}} };
|
||
|
||
const windows = {
|
||
explorer: document.getElementById('explorer-window'),
|
||
browser: document.getElementById('browser-window'),
|
||
editor: document.getElementById('editor-window')
|
||
};
|
||
let z = 10;
|
||
const bringFront = (el) => { el.style.zIndex = ++z; };
|
||
const showWindow = (name) => { const el = windows[name]; el.classList.add('visible'); bringFront(el); };
|
||
|
||
document.querySelectorAll('[data-open]').forEach(el => el.onclick = () => showWindow(el.dataset.open));
|
||
document.querySelectorAll('[data-close]').forEach(el => el.onclick = () => el.closest('.window').classList.remove('visible'));
|
||
document.querySelectorAll('[data-min]').forEach(el => el.onclick = () => el.closest('.window').classList.remove('visible'));
|
||
document.querySelectorAll('[data-max]').forEach(el => el.onclick = () => {
|
||
const w = el.closest('.window');
|
||
if (!w.dataset.maxed) { w.dataset.maxed='1'; w.dataset.prev=w.style.cssText; w.style.top='8px'; w.style.left='8px'; w.style.width='calc(100vw - 16px)'; w.style.height='calc(100vh - 74px)'; }
|
||
else { delete w.dataset.maxed; w.style.cssText = w.dataset.prev; w.classList.add('visible'); }
|
||
bringFront(w);
|
||
});
|
||
document.querySelectorAll('.window').forEach(w => w.addEventListener('mousedown', () => bringFront(w)));
|
||
|
||
// Browser app
|
||
const frame = document.getElementById('browser-frame');
|
||
const address = document.getElementById('address');
|
||
document.getElementById('go-btn').onclick = () => {
|
||
let url = address.value.trim();
|
||
if (!/^https?:\/\//i.test(url)) url = `https://${url}`;
|
||
address.value = url;
|
||
frame.src = url;
|
||
};
|
||
|
||
// Text editor app
|
||
const editor = document.getElementById('editor');
|
||
const noteName = document.getElementById('note-name');
|
||
document.getElementById('save-note').onclick = () => {
|
||
localStorage.setItem(`note:${noteName.value}`, editor.value);
|
||
alert('Saved.');
|
||
};
|
||
document.getElementById('load-note').onclick = () => {
|
||
const content = localStorage.getItem(`note:${noteName.value}`);
|
||
editor.value = content ?? '';
|
||
};
|
||
|
||
// Explorer app
|
||
const fileList = document.getElementById('file-list');
|
||
const pathBar = document.getElementById('pathbar');
|
||
const status = document.getElementById('status');
|
||
let currentPath=['/']; let selected=null;
|
||
const normalize = (path) => path === '/' ? ['/'] : ['/', ...path.split('/').filter(Boolean)];
|
||
function getNode(pathArr){ let node=fs; for(const part of pathArr.slice(1)){ if(!node.children?.[part]) return null; node=node.children[part]; } return node; }
|
||
function openPath(path){ const target=normalize(path); if(getNode(target)?.type!=='folder') return; currentPath=target; selected=null; render(); }
|
||
|
||
function renderPath(){ pathBar.innerHTML=''; let built=''; currentPath.forEach((part,i)=>{
|
||
built = i===0 ? '/' : `${built==='/'?'':built}/${part}`;
|
||
const b=document.createElement('button'); b.className='crumb'; b.textContent=i===0?'Computer':part; b.onclick=()=>openPath(built); pathBar.appendChild(b);
|
||
if(i<currentPath.length-1) pathBar.append('›');
|
||
}); }
|
||
|
||
function renderList(){
|
||
const folder=getNode(currentPath); const entries=Object.entries(folder.children||{}).sort((a,b)=>a[0].localeCompare(b[0]));
|
||
fileList.innerHTML='';
|
||
for(const [name,node] of entries){
|
||
const el=document.createElement('article');
|
||
el.className=`item${selected===name?' sel':''}`;
|
||
el.innerHTML=`<div>${node.type==='folder'?'📁':'🎵'} ${name}</div><div class="meta">${node.type==='folder'?'File Folder':node.size}</div>`;
|
||
el.onclick=()=>{selected=name; renderList(); status.textContent=`${name} selected`;};
|
||
el.ondblclick=()=>{ if(node.type==='folder') openPath(`${currentPath.join('/').replace('//','/')}/${name}`); else status.textContent=`Now playing: ${name}`; };
|
||
fileList.appendChild(el);
|
||
}
|
||
status.textContent=`${entries.length} item(s)`;
|
||
}
|
||
|
||
document.getElementById('up-btn').onclick=()=>{ if(currentPath.length>1){ currentPath=currentPath.slice(0,-1); selected=null; render(); } };
|
||
document.getElementById('new-folder-btn').onclick=()=>{ const name=prompt('Folder name?'); if(!name) return; const n=getNode(currentPath); if(n.children[name]) return alert('Name already exists.'); n.children[name]={type:'folder',children:{}}; render(); };
|
||
document.getElementById('new-file-btn').onclick=()=>{ const name=prompt('File name?','New File.txt'); if(!name) return; const n=getNode(currentPath); if(n.children[name]) return alert('Name already exists.'); n.children[name]={type:'file',size:'1 KB'}; render(); };
|
||
document.getElementById('rename-btn').onclick=()=>{ if(!selected) return alert('Select an item first.'); const n=getNode(currentPath); const next=prompt('Rename to?',selected); if(!next||next===selected) return; if(n.children[next]) return alert('Name already exists.'); n.children[next]=n.children[selected]; delete n.children[selected]; selected=next; render(); };
|
||
document.getElementById('delete-btn').onclick=()=>{ if(!selected) return alert('Select an item first.'); const n=getNode(currentPath); delete n.children[selected]; selected=null; render(); };
|
||
document.querySelectorAll('.node').forEach(n=>n.onclick=()=>openPath(n.dataset.path));
|
||
|
||
function render(){ renderPath(); renderList(); }
|
||
render();
|
||
|
||
// clock
|
||
const clock = document.getElementById('clock');
|
||
const tick = () => clock.textContent = new Date().toLocaleString();
|
||
tick(); setInterval(tick, 1000);
|
||
</script>
|
||
</body>
|
||
</html>
|