From 2a0de85152b9d2287bf861a8d9d2180817319e99 Mon Sep 17 00:00:00 2001 From: Ramon Date: Thu, 16 Jul 2026 14:45:51 +0200 Subject: [PATCH] fix: vastgezette lat kleeft altijd en vinger-jitter breekt de snap niet meer (v0.3.78-beta) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Op een aanraakscherm wiebelt een vinger in de eerste millimeters: de richtingstoets wees de snap daardoor af en de haal bleef de vinger volgen - Vastgezet gereedschap (🔒) kleeft nu onvoorwaardelijk binnen 28px van de rand - geen richtingstoets; het slot betekent "hier teken ik langs" - Losse lat: richting wordt over een langere basis gemeten (10px i.p.v. 7) met een ruimere hoek (40° i.p.v. 30°), zodat vinger-jitter de evenwijdige intentie niet meer maskeert - Inktlaag kreeg touch-action:none zodat de browser vingerhalen nooit als scroll-gebaar afvangt - Geverifieerd met échte touch-events (CDP) inclusief nagebootste vinger-jitter: 7 nieuwe checks (vastgezet kleeft mét jitter, op de lat tekenen zonder verschuiven, los evenwijdig kleeft, wegdraaiend blijft vrij) + de vier bestaande muis-suites (42 checks) blijven groen Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF --- VERSION | 2 +- public/css/teach.css | 2 +- public/js/board.js | 16 +++++++++++----- public/js/core.js | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/VERSION b/VERSION index 5c6f58f..8cfe0a7 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.3.77-beta +0.3.78-beta diff --git a/public/css/teach.css b/public/css/teach.css index 4000333..0b3a78a 100644 --- a/public/css/teach.css +++ b/public/css/teach.css @@ -126,7 +126,7 @@ /* 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 #boardInk{pointer-events:auto; cursor:crosshair; touch-action:none;} body.pen.pen-text #boardInk{cursor:text;} body.pen.pen-hand #boardInk{pointer-events:none;} /* hand tool: interact with everything */ /* ---------- Leerling-omgeving ---------- */ diff --git a/public/js/board.js b/public/js/board.js index 825c9ee..f4086dc 100644 --- a/public/js/board.js +++ b/public/js/board.js @@ -941,19 +941,19 @@ function toolEdges(){ const dx = x - t.offsetWidth/2, dy = y - t.offsetHeight/2; return [cx + dx*cosA - dy*sinA, cy + dx*sinA + dy*cosA]; }; - t._edges.forEach(seg=>edges.push([rot(seg[0]), rot(seg[1])])); + t._edges.forEach(seg=>edges.push({ a:rot(seg[0]), b:rot(seg[1]), locked:!!t._locked })); }); return edges; } function nearestEdge(px, py){ let best = null; - toolEdges().forEach(([a,b])=>{ + toolEdges().forEach(({a, b, locked})=>{ const ux = b[0]-a[0], uy = b[1]-a[1], len = Math.hypot(ux,uy); if(len < 1) return; const along = Math.max(0, Math.min(len, ((px-a[0])*ux + (py-a[1])*uy)/len)); const qx = a[0] + ux/len*along, qy = a[1] + uy/len*along; const d = Math.hypot(px-qx, py-qy); - if(!best || d < best.d) best = { d, ax:a[0], ay:a[1], ux:ux/len, uy:uy/len, len }; + if(!best || d < best.d) best = { d, ax:a[0], ay:a[1], ux:ux/len, uy:uy/len, len, locked }; }); return best; } @@ -988,6 +988,10 @@ function startInkStroke(e, fromTool = false){ const hit = nearestEdge(bx/k, by/k); if(fromTool){ if(hit && hit.d <= 24) bSnap = hit; + }else if(hit && hit.locked && hit.d <= 28){ + /* vastgezet gereedschap = "hier teken ik langs": altijd direct kleven, + zonder richtingstoets - dat is waar het slot voor is */ + bSnap = hit; }else if(hit && hit.d <= 22){ bPend = { x0:bx, y0:by, hit }; return; /* nog niets tekenen; de eerste beweging beslist (flush hieronder) */ @@ -1008,11 +1012,13 @@ bInk.addEventListener("pointermove", e=>{ if(bPend){ const k = bInk.width / board.clientWidth; const dx = rx - bPend.x0, dy = ry - bPend.y0; - if(Math.hypot(dx, dy)/k < 7) return; /* nog te weinig beweging om te beslissen */ + /* een vinger wiebelt in de eerste millimeters: meet de richting over + een langere basis (10px) en wees ruimhartig met de hoek (≤40°) */ + if(Math.hypot(dx, dy)/k < 10) return; const move = Math.atan2(dy, dx), edge = Math.atan2(bPend.hit.uy, bPend.hit.ux); let diff = Math.abs(move - edge) % Math.PI; diff = Math.min(diff, Math.PI - diff); - if(diff <= Math.PI/6) bSnap = bPend.hit; + if(diff <= Math.PI/4.5) bSnap = bPend.hit; const [sx, sy] = snapPoint(bPend.x0, bPend.y0); bx = sx; by = sy; bMidX = bMidY = null; bStroke(sx+0.01, sy+0.01, ev.pressure, ev.pointerType); diff --git a/public/js/core.js b/public/js/core.js index 26d11c6..a53ec6c 100644 --- a/public/js/core.js +++ b/public/js/core.js @@ -2,7 +2,7 @@ "use strict"; /* 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. */ -const VERSION = "0.3.77-beta"; +const VERSION = "0.3.78-beta"; (function(){ const tag = document.getElementById("verTag"); tag.textContent = "v"+VERSION;