Skip to content

Show per-filter preview swatches in PhotosCrop Filters strip#305

Merged
muukii merged 1 commit into
v5from
claude/ecstatic-proskuriakova-b8e20d
Jun 16, 2026
Merged

Show per-filter preview swatches in PhotosCrop Filters strip#305
muukii merged 1 commit into
v5from
claude/ecstatic-proskuriakova-b8e20d

Conversation

@muukii

@muukii muukii commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

What

Each filter in the PhotosCrop Filters strip now renders a live thumbnail of the photo with that filter applied (Photos/Instagram-style), replacing the text-only pills — including an "Original" swatch.

How

  • New PhotosCropFilterThumbnail.swift — a @concurrent single-swatch renderer on a dedicated wide-gamut CIContext whose working/output color spaces match the editing canvas (extendedLinearDisplayP3displayP3), so a swatch and the live canvas resolve the same colors. It center-square-crops the session thumbnail, never upscales past the source, and threads a source-relative radiusReferenceExtent so host-supplied blur/sharpen presets preview at the correct strength.
  • Per-cell lazy rendering — each PhotosCropFilterChip renders its own swatch in a .task into its @State. A LazyHStack defers off-screen first renders and retains created chips, so scrolling never re-renders. No shared cache or stringly-typed dictionary.
  • Selected chip auto-centers via .scrollPosition(id:anchor:) on selection change (clamps at the ends, so Original / the last filter rest at the edge).
  • Selection ring uses a dark shadow halo so it stays legible on bright swatches (Original / Mono / Noir on light photos).
  • Swatches preview the filter only — not the user's manual Adjust edits, blur mask, or current crop — matching the Photos/Instagram strip.

Notes

  • Uses the iOS 17 scrollPosition(id:anchor:) modifier (not deprecated). The iOS 18 ScrollPosition struct would need if #available since the deployment floor is iOS 17.

Verification

  • BrightroomUI builds clean in Swift 6 language mode.
  • Verified on the iOS Simulator: all swatches render distinctly (Mono/Noir desaturated, Warm/Cool shifted, Fade washed, Vivid/Dramatic as expected), off-screen chips render lazily when scrolled into view, the selection ring is visible on bright swatches, and selecting a chip scrolls it to center.

🤖 Generated with Claude Code

Each filter in the PhotosCrop Filters strip now renders a live thumbnail of the
photo with that filter applied (Photos/Instagram-style), replacing the text-only
pills.

- New PhotosCropFilterThumbnailRenderer: a @Concurrent single-swatch renderer on
  a dedicated wide-gamut CIContext whose working/output color spaces match the
  editing canvas, so a swatch and the canvas resolve the same colors. Center-
  square-crops the session thumbnail, never upscales, and threads a source-
  relative radiusReferenceExtent so host blur/sharpen presets preview correctly.
- Per-cell lazy rendering: each PhotosCropFilterChip renders its own swatch in a
  .task into its @State; a LazyHStack defers off-screen first renders and retains
  created chips, so scrolling never re-renders. No shared cache or dict.
- Selected chip auto-centers via .scrollPosition(id:anchor:) on selection change.
- Selection ring uses a dark shadow halo so it stays legible on bright swatches.
- Swatches preview the filter only (not manual adjustments/blur/crop).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@muukii muukii merged commit 442b873 into v5 Jun 16, 2026
2 checks passed
@muukii muukii deleted the claude/ecstatic-proskuriakova-b8e20d branch June 16, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant