Skip to content

Feature/grid layout and transition feats - #58

Merged
marcelduin merged 24 commits into
mainfrom
feature/grid-layout-and-transition-feats
Oct 20, 2026
Merged

marcelduin merged 24 commits into
mainfrom
feature/grid-layout-and-transition-feats

Conversation

@sietsev-q42

@sietsev-q42 sietsev-q42 commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

This PR adds additional grid layout and transition features.

It involves changes to the api of the grid's set method parameters.

	interface GridImage {
		id: string
		size: [number, number?]
		area?: Camera.View
		view?: Camera.View
		/** Force this entry to render as an empty placeholder cell, even though it has an `id` */
		empty?: true | false;
		/**
		 * Optional source image id to animate this entry in from.
		 * Only applied for `grid.set(..., { transition: 'in-from-id' })` and only when this image is newly added.
		 */
		from?: string
		/** Optional stacking order override (higher values render on top). */
		z?: number
	}

The array of grid images now excepts empty grid cells, either by an entry not having an 'id' or by explicitly passing an 'empty' parameter of 'true'. e.g.

grid.set([
  { id: 'hero', size: [2, 2] },
  { empty: true, size: [1] },
  { id: 'detailA', size: [1] },
  { id: 'detailB', empty: true, size: [1] },
]);

Adding the options for empty cells gives additional control over layout

There's a new transition type named 'in-from-id'. I works together with a new 'from' parameter on the grid entries. e.g.

grid.set(
  [
    { id: 'hero', size: [2, 2] },
    { ..., from:  'hero' , size: [1] },
    { ..., from:  'hero' , size: [1] },
    { ..., from:  'hero' , size: [1] },
  ], 
  { 
     transition: 'in-from-id', 
     ... 
  }
);

Additionally there's a z parameter added to the grid entries to give more control over stacking order.

@sietsev-q42 sietsev-q42 added the enhancement New feature or request label Sep 28, 2026
Replace manual `_opacity/_targetOpacity` assignments with
`_setOpacityDirect(.9999)` in grid and transition flows so eased render opacity is updated consistently.

Also require base-tile draw timestamps to be newer than the current wait start when checking image readiness, avoiding
stale `_gotBase` values from earlier appearances.
@sietsev-q42
sietsev-q42 force-pushed the feature/grid-layout-and-transition-feats branch from 2f8e24e to 91ac8f6 Compare October 14, 2026 08:47
@sietsev-q42
sietsev-q42 requested a balanced review from Copilot October 14, 2026 10:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Placeholder history loss and asynchronous transition races can restore or overwrite incorrect layouts.

3 open findings
What changed in this PR

Adds empty grid cells and richer image transition behavior.

Changes:

  • Supports explicit placeholder cells in grid layouts.
  • Adds in-from-id transitions with readiness gating and stacking.
  • Introduces direct canvas-opacity updates.
File Description
templates/​grid/​README.md Documents placeholder cells.
src/​types/​models/​grid.ts Adds grid entries and transition types.
src/​render/​tile-canvas.ts Adds direct opacity control.
src/​grid/​transitions.ts Uses direct opacity updates.
src/​grid/​grid.ts Implements placeholders and gated transitions.
src/​grid/​grid.css Styles empty cells.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/grid/grid.ts Resolved
Comment thread src/grid/grid.ts Resolved
Comment thread src/render/tile-canvas.ts Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Stale readiness loops and reused canvas opacity can cause unnecessary rendering and incorrect transition visuals.

1 open finding
3 resolved since last review
Previously missed (3)

In code that hasn't changed since last review

Medium severity Reset reused canvases to zero opacity before fade-in

src/​grid/​grid.ts:493

Fade-in-place assumes the canvas is already at opacity 0, but a reused image can retain a nonzero opacity when a newer set() supersedes the set that started fading it out. In that case the newcomer is visible before the gate opens and may fade out before fading back in. Explicitly reset fade-in-place canvases to 0.

Medium severity Cancel stale render loops after superseded layout changes

src/​grid/​grid.ts:814

A superseded in-from-id set leaves this polling loop alive until every image becomes ready or the 4s+ timeout expires. Because check calls engine.render() and requeues itself every frame, rapid layout changes accumulate stale render loops even though their gates can no longer open. Pass the set token/cancellation predicate into this helper and stop scheduling as soon as that set is no longer current.

Low severity Clarify z as a temporary in-from-id stacking override

src/​types/​models/​grid.ts:40

This public description implies z applies generally, but the implementation reads it only inside the in-from-id branch and resets it when that transition completes. Clarify that it is a temporary stacking override for in-from-id transitions so API consumers do not expect persistent ordering.

🧠 Review effort: Balanced

Comment thread src/grid/grid.ts Resolved
@marcelduin
marcelduin marked this pull request as ready for review October 20, 2026 07:36
@marcelduin

Copy link
Copy Markdown
Member

The feature work here is Sietse's; I did two passes on top of it — one to stabilise
and document the new API, and a second review pass after that to fix the remaining
state/option bugs. Everything below is my commits, oldest first.

Empty cells & in-from-id stabilisation

  • c7d1518 — honour z on every set(), cancel the in-from-id readiness gate on
    teardown, and keep enlarge() aligned past placeholder cells. Pins appear-delayed
    staggering, placeholder forms and stale readiness with tests.
  • 7fd1e0a — move the in-from-id setup into transitions.ts, next to
    setupBehindTransition (no behaviour change).
  • 900c447 — new readinessTimeout option to cap how long the in-from-id gate may
    wait for base tiles.
  • a0552f9 — enlarge() rebuilds from the layout currently displayed instead of the
    last history entry (which could resize a cell from an earlier layout).
  • 338eb35 — test that the readiness gate stops when the grid is destroyed.

Docs & demo

  • d6d4b2b — document empty cells, from, z, in-from-id and columns/history in
    templates/grid/README.md; delete the temporary demo page.
  • 11a4409 — the grid template gets Empty cells and Grow from cell buttons.
  • 9871878 — grid.html uses the local dev entry, consistent with its ./grid.ts.

Second review pass

  • 0983712 — fix two stacking bugs: a superseded in-from-id left its
    1000/2000/3000 tiers on the canvases (outranking a focused cell's zIndex of 3), and
    an explicit z was dropped by any later delayed/in-from-id set even though the docs
    promise it persists. z is now remembered per image (survives later sets and
    focus/blur, forgotten when the image leaves the layout), and the gate unstacks its own
    tiers as soon as a newer set() arrives. Also: a non-finite readinessTimeout can no
    longer hang set(), and the stored layout is copied so caller-side mutation cannot
    corrupt back() / enlarge() / history.
  • 98367fe — regression tests for the stale tiers, z persistence through focus/blur
    and removal, and non-finite timeout values (all fail without 0983712).
  • 2ba0e8b — README now states the exact z lifetime and the readinessTimeout
    default (max(duration, crossfade) + 3s, at least 4s).

Verification

  • tsc --noEmit, oxlint --type-aware, oxfmt --check: clean.
  • tests/browser/grid: 8 files / 152 tests green (the 3 new ones were confirmed red
    on the pre-fix tree).

@marcelduin
marcelduin merged commit 757fd57 into main Oct 20, 2026
5 checks passed
@marcelduin
marcelduin deleted the feature/grid-layout-and-transition-feats branch October 20, 2026 07:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants