- commit
- a8c9766899d28d52c60b656db3bf4fc72378db71
- parent
- f889e9f1429814b147a5018650f55e3fc9d2cd0d
- author
- Dami <dami.etoile@gmail.com>
| M | src/ | 7 | ++++--- |
| M | tests/ | 15 | ++++++++++++++- |
@@ -59,16 +59,17 @@ export function drawStepCounter(ctx, value, x, y, options = {}) {
5959 ctx.textBaseline = 'middle';6060 ctx.font = '800 40px Recursive, monospace';6161 const digitWidth = Math.max(20, ctx.measureText('0').width);62+ const digitHeight = 34;6263 const right = x;63- const top = y - 20;64+ const top = y - digitHeight / 2;6465 for (let index = 0; index < digits.length; index += 1) {6566 const digitX = right - (digits.length - index - 0.5) * digitWidth;6667 ctx.save();6768 ctx.beginPath();68- ctx.rect(digitX - digitWidth / 2, top, digitWidth, 42);69+ ctx.rect(digitX - digitWidth / 2, top, digitWidth, digitHeight);6970 ctx.clip();7071 if (frame.changed[index] && frame.progress < 1) {71- const travel = digitWidth * frame.eased;72+ const travel = digitHeight * frame.eased;7273 const oldY = y - frame.direction * travel;7374 const newY = y + frame.direction * (digitWidth - travel);7475 ctx.textAlign = 'center';@@ -1,6 +1,6 @@
11 import test from 'node:test';22 import assert from 'node:assert/strict';3-import { drawInlineActions, drawLedger } from '../src/render/stage-hud.js';3+import { drawInlineActions, drawLedger, drawStepCounter } from '../src/render/stage-hud.js';44 55 function context() {66 const calls = [];@@ -16,6 +16,7 @@ function context() {
1616 lineTo(...args) { calls.push(['lineTo', ...args]); },1717 roundRect(...args) { calls.push(['roundRect', ...args]); },1818 rect(...args) { calls.push(['rect', ...args]); },19+ clip() { calls.push(['clip']); },1920 stroke() { calls.push(['stroke']); },2021 fillRect(...args) { calls.push(['fillRect', ...args]); },2122 fillText(...args) { calls.push(['fillText', ...args]); },@@ -58,3 +59,15 @@ test('drawInlineActions presses only the matching Win action keycap', () => {
5859 // The pressed keycap loses its lip fill while the other keeps both faces.5960 assert.equal(ctx.calls.filter(call => call[0] === 'fillRect').length, 3);6061 });62+63+test('odometer clips each rolling digit to one text box', () => {64+ const ctx = context();65+ drawStepCounter(ctx, 8, 100, 39, {66+ now: 60,67+ roll: { from: 7, to: 8, startedAt: 0, duration: 120 },68+ });69+ const clips = ctx.calls.filter(call => call[0] === 'rect');70+ assert.equal(clips.length, 2);71+ assert.ok(clips.every(call => call[2] === 22 && call[4] === 34));72+ assert.equal(ctx.calls.filter(call => call[0] === 'clip').length, 2);73+});