fix: vastgezette lat kleeft altijd en vinger-jitter breekt de snap niet meer (v0.3.78-beta)
Some checks failed
dev - build & deploy naar test / build-and-deploy (push) Failing after 32s

- 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 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149FgUQvuwxKKEdvQGmNngF
This commit is contained in:
Ramon 2026-07-16 14:45:51 +02:00
parent 7a5d7c57ff
commit 2a0de85152
4 changed files with 14 additions and 8 deletions

View file

@ -1 +1 @@
0.3.77-beta
0.3.78-beta

View file

@ -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 ---------- */

View file

@ -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);

View file

@ -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;