Przejdź do treści
<code>pen.pl

Menu kontekstowe obiektu na planszy

Narzędzia

Podgląd

Ładowanie podglądu…

Menu planszy z opcjami zmiany koloru, duplikowania obiektu i resetowania widoku.

0,0 / 5 Brak ocen

Kod źródłowy

Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.

HTML
<main class="canvas-app"><header><h1>Plansza obiektów.</h1><button id="context-toggle" aria-expanded="false" aria-controls="context-actions">Akcje obiektu</button></header><p>Wybierz akcję przyciskiem, prawym kliknięciem lub Shift + F10 na obiekcie.</p><div class="canvas" id="object-target" tabindex="0" aria-label="Obiekt na planszy, Shift F10 otwiera akcje"><div id="object-shape" aria-hidden="true"><i></i><b></b><em></em></div><span class="canvas-caption">Wybrany obiekt.</span><div id="context-actions" hidden><button data-action="color">Zmień kolor</button><button data-action="duplicate">Duplikuj obiekt</button><button data-action="reset">Przywróć układ</button></div></div><p id="context-status" class="status" aria-live="polite">1 obiekt na planszy</p></main>
CSS
*{box-sizing:border-box}body{margin:0;min-height:100vh;font-family:Arial,sans-serif;color:var(--ink,#15202b);background:var(--paper,#fff);line-height:1.5}button,input,select{font:inherit}button{cursor:pointer;min-height:44px}button:disabled{cursor:not-allowed;opacity:.55}button,input,select,a{touch-action:manipulation}button:focus-visible,input:focus-visible,select:focus-visible,a:focus-visible,[tabindex]:focus-visible,summary:focus-visible{outline:3px solid var(--focus,#1368ce);outline-offset:4px}button{border-radius:0}h1,h2,p{margin-top:0}svg{display:block;max-width:100%}[hidden]{display:none!important}.status{min-height:24px;font-size:14px}@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
body{--paper:#d8e2ea;--ink:#284153;--focus:#aa642f}.canvas-app{max-width:820px;margin:auto;padding:30px}header{display:flex;justify-content:space-between;align-items:center;gap:20px}h1{font-family:'Trebuchet MS',sans-serif;font-size:37px;letter-spacing:-1px;margin:0}#context-toggle{background:#284153;color:#f3f7fa;border:0;padding:10px 16px;font-size:13px}.canvas-app>p{font-size:13px;color:#496274;margin:14px 0}.canvas{height:285px;position:relative;background-color:#eff4f6;background-image:radial-gradient(#a7bac7 1px,transparent 1px);background-size:18px 18px;border:1px solid #829faf;overflow:hidden}#object-shape,.duplicate-shape{position:absolute;left:30%;top:45px;width:180px;height:190px;--shape:#dd8c60}#object-shape i,.duplicate-shape i{display:block;position:absolute;width:135px;height:135px;border-radius:50%;background:var(--shape);left:22px;top:10px}#object-shape b,.duplicate-shape b{position:absolute;width:90px;height:90px;background:#365e7c;left:15px;top:95px;transform:rotate(-20deg)}#object-shape em,.duplicate-shape em{position:absolute;width:90px;height:90px;border:12px solid #e7d6b7;right:0;bottom:0;transform:rotate(15deg)}.canvas-caption{position:absolute;left:18px;bottom:12px;font:11px monospace;color:#496274}.duplicate-shape{transform:scale(.7) rotate(15deg);left:60%;top:80px;opacity:.75}#context-actions{position:absolute;right:20px;top:20px;background:#284153;min-width:185px;padding:8px;z-index:3}#context-actions button{display:block;width:100%;background:none;border:0;border-bottom:1px solid #668296;color:#eff4f6;text-align:left;padding:10px 12px;font-size:14px}#context-actions button:last-child{border-bottom:0}.status{font-size:13px}@media(max-width:480px){.canvas-app{padding:22px}header{align-items:flex-start;gap:12px}h1{font-size:30px;max-width:175px}#context-toggle{max-width:105px;font-size:12px;padding:9px}.canvas{height:320px}#object-shape{left:18%;top:58px}.duplicate-shape{left:43%;top:110px}#context-actions{right:12px;top:12px}}
JavaScript
(()=>{
const toggle=document.querySelector('#context-toggle'),menu=document.querySelector('#context-actions'),target=document.querySelector('#object-target');let colored=false;function open(){menu.hidden=false;toggle.setAttribute('aria-expanded','true');menu.querySelector('button').focus();}function close(focus=true){menu.hidden=true;toggle.setAttribute('aria-expanded','false');if(focus)toggle.focus();}toggle.addEventListener('click',()=>menu.hidden?open():close());target.addEventListener('contextmenu',e=>{e.preventDefault();open();});target.addEventListener('keydown',e=>{if(e.shiftKey&&e.key==='F10'){e.preventDefault();open();}});document.addEventListener('keydown',e=>{if(e.key==='Escape'&&!menu.hidden){e.preventDefault();close();}});menu.querySelectorAll('[data-action]').forEach(button=>button.addEventListener('click',()=>{if(button.dataset.action==='color'){colored=!colored;document.querySelector('#object-shape').style.setProperty('--shape',colored?'#799b70':'#dd8c60');document.querySelector('#context-status').textContent='Zmieniono kolor obiektu: '+(colored?'zielony':'pomarańczowy');}if(button.dataset.action==='duplicate'){let clone=target.querySelector('.duplicate-shape');if(!clone){clone=document.querySelector('#object-shape').cloneNode(true);clone.removeAttribute('id');clone.className='duplicate-shape';target.append(clone);}document.querySelector('#context-status').textContent='2 obiekty na planszy';}if(button.dataset.action==='reset'){target.querySelector('.duplicate-shape')?.remove();colored=false;document.querySelector('#object-shape').style.setProperty('--shape','#dd8c60');document.querySelector('#context-status').textContent='1 obiekt na planszy — przywrócono układ';}close();}));document.addEventListener('pointerdown',e=>{if(!menu.hidden&&!menu.contains(e.target)&&!toggle.contains(e.target))close(false);});
})();

Edytuj swój pen

Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.

Link jest ważny przez 30 minut.