Verbeter anatomie en plaatsing van avataraccessoires (v0.4.46-beta) #1
4 changed files with 44 additions and 11 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
0.3.62-beta
|
0.3.63-beta
|
||||||
|
|
|
||||||
|
|
@ -460,6 +460,16 @@
|
||||||
}
|
}
|
||||||
.dock-item:hover{background:var(--surface-2); transform:translateY(-2px);}
|
.dock-item:hover{background:var(--surface-2); transform:translateY(-2px);}
|
||||||
.dock-item .di{font-size:16px; line-height:1;}
|
.dock-item .di{font-size:16px; line-height:1;}
|
||||||
|
/* sluitknop op de dock-pil: geminimaliseerde widgets zijn direct te sluiten */
|
||||||
|
.dock-item .dock-close{
|
||||||
|
display:flex; align-items:center; justify-content:center;
|
||||||
|
width:20px; height:20px; margin:-2px -6px -2px 0; border-radius:7px;
|
||||||
|
font-size:11px; color:var(--muted); line-height:1;
|
||||||
|
}
|
||||||
|
.dock-item .dock-close:hover{background:var(--red-soft); color:var(--red);}
|
||||||
|
@media (pointer:coarse){
|
||||||
|
.dock-item .dock-close{width:28px; height:28px;}
|
||||||
|
}
|
||||||
.widget-head{
|
.widget-head{
|
||||||
display:flex; align-items:center; gap:10px; padding:10px 14px;
|
display:flex; align-items:center; gap:10px; padding:10px 14px;
|
||||||
background:rgba(255,255,255,.4); border-bottom:1px solid rgba(150,170,200,.28);
|
background:rgba(255,255,255,.4); border-bottom:1px solid rgba(150,170,200,.28);
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,24 @@ const REGISTRY = [
|
||||||
];
|
];
|
||||||
const WIDGET_CATS = [["favorites","galleryFavorites"],["taal","catTaal"],["rekenen","catRekenen"],["class","catClass"],["tools","catTools"],["media","catMedia"]];
|
const WIDGET_CATS = [["favorites","galleryFavorites"],["taal","catTaal"],["rekenen","catRekenen"],["class","catClass"],["tools","catTools"],["media","catMedia"]];
|
||||||
|
|
||||||
/* houdt een (opgeslagen of standaard) widgetgrootte binnen het bord - zonder
|
/* houdt een (opgeslagen of standaard) widgetgrootte binnen het bord. Op een
|
||||||
dit passen desktop-formaten (tot 760px breed) niet op een telefoon/tablet */
|
telefoon is de beschikbare ruimte leidend: een desktop-minimum van bv.
|
||||||
|
640px mag daar niet alsnog horizontale overflow afdwingen. */
|
||||||
|
function widgetSizeBounds(def, left=0, top=0){
|
||||||
|
const maxW = Math.max(1, board.clientWidth - left - 8);
|
||||||
|
const maxH = Math.max(1, board.clientHeight - top - 8);
|
||||||
|
return {
|
||||||
|
minW: Math.min(def.minW || 240, maxW),
|
||||||
|
minH: Math.min(def.minH || 180, maxH),
|
||||||
|
maxW, maxH,
|
||||||
|
};
|
||||||
|
}
|
||||||
function clampWidgetSize(w, h, def){
|
function clampWidgetSize(w, h, def){
|
||||||
const fw = Math.max(def.minW || 240, Math.min(w, board.clientWidth));
|
const {minW,minH,maxW,maxH} = widgetSizeBounds(def);
|
||||||
const fh = Math.max(def.minH || 180, Math.min(h, board.clientHeight));
|
return {
|
||||||
return { w: fw, h: fh };
|
w: Math.max(minW, Math.min(w, maxW)),
|
||||||
|
h: Math.max(minH, Math.min(h, maxH)),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stabiel widget-instantie-id, zelfde patroon als genBoardId() verderop - nodig
|
/* stabiel widget-instantie-id, zelfde patroon als genBoardId() verderop - nodig
|
||||||
|
|
@ -148,9 +160,14 @@ function makeWidget(def, saved){
|
||||||
win.style.display = "none";
|
win.style.display = "none";
|
||||||
pill = document.createElement("button");
|
pill = document.createElement("button");
|
||||||
pill.className = "dock-item";
|
pill.className = "dock-item";
|
||||||
pill.innerHTML = `<span class="di">${def.icon}</span><span class="dl"></span>`;
|
pill.innerHTML = `<span class="di">${def.icon}</span><span class="dl"></span><span class="dock-close" role="button">✕</span>`;
|
||||||
pill.querySelector(".dl").textContent = T("wg_"+def.id);
|
pill.querySelector(".dl").textContent = T("wg_"+def.id);
|
||||||
pill.title = T("wMax");
|
pill.title = T("wMax");
|
||||||
|
/* ook een geminimaliseerde widget is direct te sluiten, zonder hem
|
||||||
|
eerst terug op het bord te hoeven zetten */
|
||||||
|
const x = pill.querySelector(".dock-close");
|
||||||
|
x.title = T("close");
|
||||||
|
x.addEventListener("click", e=>{ e.stopPropagation(); removeWidget(); });
|
||||||
pill.addEventListener("click", ()=>setMin(false));
|
pill.addEventListener("click", ()=>setMin(false));
|
||||||
dock.appendChild(pill);
|
dock.appendChild(pill);
|
||||||
}else if(!m && pill){
|
}else if(!m && pill){
|
||||||
|
|
@ -206,7 +223,11 @@ function makeWidget(def, saved){
|
||||||
minBtn.title = T("wMin");
|
minBtn.title = T("wMin");
|
||||||
maxBtn.title = T(win.dataset.max==="1" ? "wUnfull" : "wFull");
|
maxBtn.title = T(win.dataset.max==="1" ? "wUnfull" : "wFull");
|
||||||
zBtn.title = T("wZoom");
|
zBtn.title = T("wZoom");
|
||||||
if(pill){ pill.querySelector(".dl").textContent = T("wg_"+def.id); pill.title = T("wMax"); }
|
if(pill){
|
||||||
|
pill.querySelector(".dl").textContent = T("wg_"+def.id);
|
||||||
|
pill.title = T("wMax");
|
||||||
|
pill.querySelector(".dock-close").title = T("close");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
setTitle();
|
setTitle();
|
||||||
document.addEventListener("langchange", setTitle);
|
document.addEventListener("langchange", setTitle);
|
||||||
|
|
@ -233,11 +254,13 @@ function makeWidget(def, saved){
|
||||||
dupBtn.title=T("widgetDuplicate");dupBtn.setAttribute("aria-label",dupBtn.title);previewBtn.title=T("widgetPreview");previewBtn.setAttribute("aria-label",previewBtn.title);
|
dupBtn.title=T("widgetDuplicate");dupBtn.setAttribute("aria-label",dupBtn.title);previewBtn.title=T("widgetPreview");previewBtn.setAttribute("aria-label",previewBtn.title);
|
||||||
dupBtn.addEventListener("click",()=>makeWidget(def,{x:win.offsetLeft+28,y:win.offsetTop+28,w:win.offsetWidth,h:win.offsetHeight,wz:+win.dataset.wz||1,state:api.getState?structuredClone(api.getState()):null}));
|
dupBtn.addEventListener("click",()=>makeWidget(def,{x:win.offsetLeft+28,y:win.offsetTop+28,w:win.offsetWidth,h:win.offsetHeight,wz:+win.dataset.wz||1,state:api.getState?structuredClone(api.getState()):null}));
|
||||||
instances.add(inst);
|
instances.add(inst);
|
||||||
close.addEventListener("click", ()=>{
|
/* gedeeld sluitpad voor de ✕ in de widgetkop én de ✕ op de dock-pil */
|
||||||
|
function removeWidget(){
|
||||||
markBoardChange();
|
markBoardChange();
|
||||||
if(pill){ pill.remove(); pill = null; }
|
if(pill){ pill.remove(); pill = null; }
|
||||||
instances.delete(inst); win.remove(); updateEmptyHint();
|
instances.delete(inst); win.remove(); updateEmptyHint();
|
||||||
});
|
}
|
||||||
|
close.addEventListener("click", removeWidget);
|
||||||
updateEmptyHint();
|
updateEmptyHint();
|
||||||
markBoardChange();
|
markBoardChange();
|
||||||
return inst;
|
return inst;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
/* version — shown until /api/version resolves (or if the fetch fails, e.g. offline).
|
/* version — shown until /api/version resolves (or if the fetch fails, e.g. offline).
|
||||||
Kept in sync by hand with the VERSION file at the repo root on every release. */
|
Kept in sync by hand with the VERSION file at the repo root on every release. */
|
||||||
const VERSION = "0.3.62-beta";
|
const VERSION = "0.3.63-beta";
|
||||||
(function(){
|
(function(){
|
||||||
const tag = document.getElementById("verTag");
|
const tag = document.getElementById("verTag");
|
||||||
tag.textContent = "v"+VERSION;
|
tag.textContent = "v"+VERSION;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue