diff --git a/VERSION b/VERSION
index c39603d..131ab5f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.3.64-beta
+0.3.65-beta
diff --git a/public/css/teach.css b/public/css/teach.css
index 828a62c..354ce52 100644
--- a/public/css/teach.css
+++ b/public/css/teach.css
@@ -123,6 +123,9 @@
/* drawing layer on the board: sits ABOVE widgets like a transparency sheet,
so you can annotate over everything; clicks pass through when pen is off */
#boardInk{position:absolute; inset:0; pointer-events:none; z-index:4000;}
+ /* live-laag van de markeerstift: dekkend getekend, doorschijnend getoond;
+ bij het loslaten wordt de haal in één keer op de inktlaag gezet */
+ #boardMark{position:absolute; inset:0; pointer-events:none; z-index:4000; opacity:.32;}
body.pen #boardInk{pointer-events:auto; cursor:crosshair;}
body.pen.pen-text #boardInk{cursor:text;}
body.pen.pen-hand #boardInk{pointer-events:none;} /* hand tool: interact with everything */
@@ -360,6 +363,16 @@
box-shadow:0 2px 6px rgba(0,0,0,.25);
}
.dtool-opts button:hover{background:var(--accent-soft);}
+ /* lengteknop toont de maat ("10 cm") en is dus breder dan een rond knopje */
+ .dtool-opts .do-wide{width:auto; min-width:48px; padding:0 9px; border-radius:12px;}
+ /* live hoek-uitlezing tijdens het draaien van liniaal/geodriehoek */
+ .dtool-deg{
+ display:none; position:absolute; left:50%; top:50%; margin:-16px 0 0 -24px;
+ width:48px; height:32px; line-height:32px; text-align:center; pointer-events:none;
+ background:rgba(30,50,90,.85); color:#fff; font-size:14px; font-weight:800;
+ border-radius:9px; z-index:3;
+ }
+ .dtool-deg.snapped{background:var(--green);}
.dtool-lens{z-index:4500;} /* the glass sits above the ink sheet */
.dtool-lens canvas{
border:5px solid #5a6c85; box-shadow:0 8px 22px rgba(0,0,0,.3);
diff --git a/public/js/board.js b/public/js/board.js
index fdabac9..5b2cd6e 100644
--- a/public/js/board.js
+++ b/public/js/board.js
@@ -352,16 +352,27 @@ const bInk = document.createElement("canvas");
bInk.id = "boardInk";
board.insertBefore(bInk, board.firstChild);
const bCtx = bInk.getContext("2d");
-const bDpr = window.devicePixelRatio || 1;
+/* aparte laag voor de markeerstift: dáár tekent hij dekkend, de laag zelf is
+ doorschijnend (CSS), en pas bij het loslaten wordt de hele haal in één keer
+ met 32% op de inktlaag gezet. Zo stapelen overlappende lijnstukjes binnen
+ één haal niet meer tot donkere vlekken op elke overgang. */
+const bMark = document.createElement("canvas");
+bMark.id = "boardMark";
+board.insertBefore(bMark, bInk.nextSibling);
+const bMarkCtx = bMark.getContext("2d");
+let bDpr = window.devicePixelRatio || 1;
function bResize(){
const w = board.clientWidth, h = board.clientHeight;
if(w<2 || h<2) return;
+ bDpr = window.devicePixelRatio || 1; /* vers: verhuizen naar ander scherm/zoom */
const keep = document.createElement("canvas");
keep.width = bInk.width; keep.height = bInk.height;
if(bInk.width) keep.getContext("2d").drawImage(bInk,0,0);
bInk.width = Math.round(w*bDpr); bInk.height = Math.round(h*bDpr);
if(keep.width) bCtx.drawImage(keep,0,0);
bCtx.lineCap = "round"; bCtx.lineJoin = "round";
+ bMark.width = bInk.width; bMark.height = bInk.height;
+ bMarkCtx.lineCap = "round"; bMarkCtx.lineJoin = "round";
}
new ResizeObserver(bResize).observe(board);
bResize();
@@ -555,11 +566,25 @@ function makeMovable(t){
const r = t.getBoundingClientRect();
const cx = r.left+r.width/2, cy = r.top+r.height/2;
const start = Math.atan2(e.clientY-cy, e.clientX-cx)*180/Math.PI - ang;
+ /* klikt vast op veelvouden van 45° (waterpas/haaks in één beweging)
+ en toont tijdens het draaien de hoek in graden */
+ const badge = t.querySelector(".dtool-deg") || t.appendChild(Object.assign(document.createElement("div"), { className:"dtool-deg" }));
+ badge.style.display = "block";
const mv = ev=>{
- ang = Math.atan2(ev.clientY-cy, ev.clientX-cx)*180/Math.PI - start;
+ let a = Math.atan2(ev.clientY-cy, ev.clientX-cx)*180/Math.PI - start;
+ const near = Math.round(a/45)*45;
+ if(Math.abs(a-near) < 4) a = near;
+ ang = a;
t.style.transform = `rotate(${ang}deg)`;
+ const shown = Math.round(((ang % 360) + 360) % 360);
+ badge.textContent = shown + "°";
+ badge.style.transform = `rotate(${-ang}deg)`; /* leesbaar houden */
+ badge.classList.toggle("snapped", Math.abs(((ang % 45) + 45) % 45) < 0.01);
+ };
+ const up = ()=>{
+ badge.style.display = "none";
+ document.removeEventListener("pointermove",mv); document.removeEventListener("pointerup",up);
};
- const up = ()=>{ document.removeEventListener("pointermove",mv); document.removeEventListener("pointerup",up); };
document.addEventListener("pointermove",mv); document.addEventListener("pointerup",up);
return;
}
@@ -582,17 +607,21 @@ function toggleDTool(kind){
const t = document.createElement("div");
t.className = "dtool dtool-"+kind;
if(kind==="ruler"){
- t._len = 600; t._hc = false;
+ /* 50px = 1 cm; logische lengtes in hele centimeters, schaal begint bij 0
+ met een kleine kantlijn zoals op een echte liniaal */
+ const RULER_CMS = [5, 10, 15, 20];
+ t._cm = 10; t._hc = false;
const drawRuler = ()=>{
- const L = t._len, hc = t._hc;
+ const cmLen = Math.min(t._cm, Math.max(5, Math.floor((board.clientWidth-60)/50)));
+ const pad = 18, scale = cmLen*50, L = scale + pad*2, hc = t._hc;
const ink = hc ? "#000" : "#5a4a20";
const bg = hc ? "rgba(255,214,0,.95)" : "rgba(255,243,205,.82)";
let ticks = "";
- for(let i=5; i