diff options
| author | Paul Buetow <paul@buetow.org> | 2026-06-22 18:22:04 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-06-22 18:22:04 +0300 |
| commit | 63fbea196e34c0783526980973f33fc1b82cbe71 (patch) | |
| tree | 5c57a490103dceba8bed2bef8f59467f9cbcc1f5 | |
| parent | 2b654d68bc450b50cfdc091912b67b0786acc57c (diff) | |
Cap the 2x2 feature tiles at two per page
Each tile rolled for a feature independently, so a page (or stats
gallery) could fill up with large 2x2 hero tiles. append_preview_grid
now counts the features it has placed and stops offering the "feature"
layout to tile_layout_for once two have been used, so any single grid
gets at most two feature tiles; later tiles fall back to subdivided or
single. The cap is per append_preview_grid call, so it applies to both
the main preview pages and the stats mini-album galleries.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| -rwxr-xr-x | bin/shuriken | 38 | ||||
| -rw-r--r-- | src/lib/album-render.source.sh | 38 |
2 files changed, 54 insertions, 22 deletions
diff --git a/bin/shuriken b/bin/shuriken index b2b5dc0..8c85bb8 100755 --- a/bin/shuriken +++ b/bin/shuriken @@ -2643,13 +2643,23 @@ append_preview_grid() { local -i count local layout local block + # Cap the big 2x2 feature tiles at this many per page; once reached, later + # tiles are no longer offered the "feature" layout (they fall back to + # subdivided/single), so a page never gets crowded with hero tiles. + local -ri max_features=2 + local -i features_used=0 while (( i < ${#photos[@]} )); do # Decide this tile's layout from the photos still available; the first # photo's name is the seeded-random context so the choice is stable. + # Features are only offered until the per-page cap is reached. read -r layout count < <( - tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" + tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" \ + "$(( features_used < max_features ? 1 : 0 ))" ) + if [ "$layout" = feature ]; then + (( ++features_used )) + fi block=$(build_tile_block \ "$thumbs_dir" "$backhref" "$href_prefix" "$layout" "$(( i + 1 ))" \ "${photos[@]:i:count}") @@ -2662,26 +2672,32 @@ append_preview_grid() { done } -# Decide the layout for the next tile, printing "<layout> <photo-count>". Each -# tile rolls first for a "feature" (one photo blown up to a 2x2 hero tile) with -# THUMB_FEATURE_PERCENT probability, then for a subdivision with +# Decide the layout for the next tile, printing "<layout> <photo-count>". When +# feature_allowed is non-zero each tile rolls first for a "feature" (one photo +# blown up to a 2x2 hero tile) with THUMB_FEATURE_PERCENT probability; the caller +# clears feature_allowed once a page has reached its per-page feature-tile cap +# (see append_preview_grid). Otherwise the tile rolls for a subdivision with # THUMB_SUBDIVIDE_PERCENT probability (only into a layout that fits the photos -# still remaining on the page); otherwise it is a single square thumbnail. The +# still remaining on the page); failing both it is a single square thumbnail. The # feature and subdivide rolls use independent seeded random_index namespaces, so -# builds stay reproducible when RANDOM_SEED is set (and varied otherwise). +# builds stay reproducible when RANDOM_SEED is set. tile_layout_for() { local -ri remaining="$1"; shift local -r context="$1"; shift + local -ri feature_allowed="$1"; shift local -a names=(two_wide) local -a counts=(2) local -i roll choice # A feature tile always fits (it consumes a single photo), so roll for it - # first. THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0). - roll=$(random_index "feature:$context" 100) - if (( roll < THUMB_FEATURE_PERCENT )); then - printf 'feature 1\n' - return + # first -- but only while the page has not used its one allowed feature. + # THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0). + if (( feature_allowed )); then + roll=$(random_index "feature:$context" 100) + if (( roll < THUMB_FEATURE_PERCENT )); then + printf 'feature 1\n' + return + fi fi # A single tile when subdivision is disabled, too few photos remain to fill diff --git a/src/lib/album-render.source.sh b/src/lib/album-render.source.sh index 6770b86..3024923 100644 --- a/src/lib/album-render.source.sh +++ b/src/lib/album-render.source.sh @@ -206,13 +206,23 @@ append_preview_grid() { local -i count local layout local block + # Cap the big 2x2 feature tiles at this many per page; once reached, later + # tiles are no longer offered the "feature" layout (they fall back to + # subdivided/single), so a page never gets crowded with hero tiles. + local -ri max_features=2 + local -i features_used=0 while (( i < ${#photos[@]} )); do # Decide this tile's layout from the photos still available; the first # photo's name is the seeded-random context so the choice is stable. + # Features are only offered until the per-page cap is reached. read -r layout count < <( - tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" + tile_layout_for "$(( ${#photos[@]} - i ))" "${photos[i]}" \ + "$(( features_used < max_features ? 1 : 0 ))" ) + if [ "$layout" = feature ]; then + (( ++features_used )) + fi block=$(build_tile_block \ "$thumbs_dir" "$backhref" "$href_prefix" "$layout" "$(( i + 1 ))" \ "${photos[@]:i:count}") @@ -225,26 +235,32 @@ append_preview_grid() { done } -# Decide the layout for the next tile, printing "<layout> <photo-count>". Each -# tile rolls first for a "feature" (one photo blown up to a 2x2 hero tile) with -# THUMB_FEATURE_PERCENT probability, then for a subdivision with +# Decide the layout for the next tile, printing "<layout> <photo-count>". When +# feature_allowed is non-zero each tile rolls first for a "feature" (one photo +# blown up to a 2x2 hero tile) with THUMB_FEATURE_PERCENT probability; the caller +# clears feature_allowed once a page has reached its per-page feature-tile cap +# (see append_preview_grid). Otherwise the tile rolls for a subdivision with # THUMB_SUBDIVIDE_PERCENT probability (only into a layout that fits the photos -# still remaining on the page); otherwise it is a single square thumbnail. The +# still remaining on the page); failing both it is a single square thumbnail. The # feature and subdivide rolls use independent seeded random_index namespaces, so -# builds stay reproducible when RANDOM_SEED is set (and varied otherwise). +# builds stay reproducible when RANDOM_SEED is set. tile_layout_for() { local -ri remaining="$1"; shift local -r context="$1"; shift + local -ri feature_allowed="$1"; shift local -a names=(two_wide) local -a counts=(2) local -i roll choice # A feature tile always fits (it consumes a single photo), so roll for it - # first. THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0). - roll=$(random_index "feature:$context" 100) - if (( roll < THUMB_FEATURE_PERCENT )); then - printf 'feature 1\n' - return + # first -- but only while the page has not used its one allowed feature. + # THUMB_FEATURE_PERCENT == 0 disables it (the roll can never be < 0). + if (( feature_allowed )); then + roll=$(random_index "feature:$context" 100) + if (( roll < THUMB_FEATURE_PERCENT )); then + printf 'feature 1\n' + return + fi fi # A single tile when subdivision is disabled, too few photos remain to fill |
