fix(tabletop): default tilt to 1 degree for all parts

Apply the default 1 degree tilt even when a route has no stacking
strategy, so every placed part is tilted consistently.
This commit is contained in:
2026-08-10 00:29:23 +08:00
parent 8d0e393100
commit f12b40e82b
3 changed files with 9 additions and 10 deletions
+1 -1
View File
@@ -373,7 +373,7 @@ layout:
`1`. See the positioning process below.
- `tilt` — rotation in degrees applied to every shown part about the card's
local Y (long) axis. It applies even without a `curve`, so a bare `tilt`
rotates a straight pile.
rotates a straight pile. Defaults to `1` when not specified.
- `zStart` / `zEnd` — the height (surface-normal) in mm at the start and end
of the `curve`. The stack ramps linearly between them across its span,
lifting it in 3D. Requires a `curve`.
+4 -5
View File
@@ -44,9 +44,8 @@ describe('pointAt', () => {
});
describe('stackingOffset', () => {
it('returns no offset without a curve', () => {
expect(stackingOffset(undefined, 0, 3)).toBe(NO_OFFSET);
// A stacking strategy defaults to a 1° tilt, so it's not the identity.
it('defaults to a 1° tilt without a curve', () => {
expect(stackingOffset(undefined, 0, 3)).toEqual({ x: 0, y: 0, rotation: 0, z: 0, tilt: 1 });
expect(stackingOffset({ limit: 5 }, 0, 3)).toEqual({ x: 0, y: 0, rotation: 0, z: 0, tilt: 1 });
});
@@ -114,7 +113,7 @@ describe('stackingOffset', () => {
expect(last.z).toBeCloseTo(40);
});
it('returns no offset without a stacking strategy', () => {
expect(stackingOffset(undefined, 0, 3)).toBe(NO_OFFSET);
it('returns no offset for an empty stack', () => {
expect(stackingOffset(undefined, 0, 0)).toBe(NO_OFFSET);
});
});
+4 -4
View File
@@ -27,8 +27,8 @@ export const NO_OFFSET: StackOffset = { x: 0, y: 0, rotation: 0, z: 0, tilt: 0 }
/**
* Compute the offset/rotation for the piece at `index` of a `stackSize`-piece
* stack, given the route's stacking strategy. Returns `NO_OFFSET` when there's
* no curve, no tilt, and no z profile, or the stack is empty.
* stack, given the route's stacking strategy. Returns `NO_OFFSET` when the
* stack is empty. Every placed part gets a default 1° tilt unless overridden.
*/
export function stackingOffset(
stacking: Stacking | undefined,
@@ -45,8 +45,8 @@ export function stackingOffset(
// `tilt` rotates each shown part about its local Y (long) axis by the same
// amount. It applies even without a curve. Defaults to 1° when a stacking
// strategy is present but doesn't specify a tilt.
const tilt = stacking?.tilt ?? (stacking ? 1 : 0);
// strategy doesn't specify a tilt.
const tilt = stacking?.tilt ?? 1;
// The horizontal position along the curve (or a straight pile when there's
// no curve), plus the normalized progress used to ramp the z height.