clamp held-channel rgb scroll to stay inside the color cube

Hunter
Wednesday, April 15th, 2026 at 3:40 PM

index.html+16-6

index.html
464  		if (wheelMode === 'color') {
465  			// inverted: scroll up = less, scroll down = more
466  			const dir = e.deltaY < 0 ? -1 : 1;
    -			const step = 8 * dir;
    -			let nr = r, ng = g, nb = b;
    -			if (keys['r']) nr = clamp(r + step, 0, 255);
    -			if (keys['g']) ng = clamp(g + step, 0, 255);
    -			if (keys['b']) nb = clamp(b + step, 0, 255);
    -			setColor(nr, ng, nb);
467 +			const held = [];
468 +			if (keys['r']) held.push(r);
469 +			if (keys['g']) held.push(g);
470 +			if (keys['b']) held.push(b);
471 +			if (held.length === 0) return;
472 +			// clamp the shared delta so no held channel overshoots [0, 255]
473 +			let step = 8 * dir;
474 +			for (const v of held) {
475 +				const headroom = dir > 0 ? 255 - v : -v;
476 +				step = dir > 0 ? Math.min(step, headroom) : Math.max(step, headroom);
477 +			}
478 +			setColor(
479 +				keys['r'] ? r + step : r,
480 +				keys['g'] ? g + step : g,
481 +				keys['b'] ? b + step : b
482 +			);
483  			requestDraw();
484  			return;
485  		}