diff --git a/CHANGELOG.md b/CHANGELOG.md index b96d2de..672b5b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,9 @@ project follows [Semantic Versioning](https://semver.org/). each column's total depth (face-down cards included) and refills on the cold-start deal, every move, and on resize (incl. the Android safe-area-inset resize and fold/unfold), so a near-square viewport such as an unfolded Galaxy - Fold no longer leaves the bottom of the screen empty. + Fold no longer leaves the bottom of the screen empty. The fan spread cap was + raised so very tall / narrow viewports (e.g. a foldable cover screen) fill + further. - **Card-move animation jank.** A move now rebuilds a card's child visuals only when its appearance changes (flip / resize / accessibility) instead of despawning and respawning every card's children each `StateChangedEvent`, diff --git a/solitaire_engine/src/layout.rs b/solitaire_engine/src/layout.rs index d61d384..1b5d73a 100644 --- a/solitaire_engine/src/layout.rs +++ b/solitaire_engine/src/layout.rs @@ -99,7 +99,7 @@ const MAX_TABLEAU_CARDS: f32 = 13.0; /// clear overlap (a readable stack) while still filling most of a near-square / /// unfolded-foldable screen. Tunable purely for feel — no effect on correctness /// or hit-testing. -pub(crate) const MAX_DYNAMIC_FAN_FRAC: f32 = 0.6; +pub(crate) const MAX_DYNAMIC_FAN_FRAC: f32 = 0.9; /// Vertical pixel band reserved at the top of the play area for the HUD /// (action buttons, Score / Moves / Timer readouts). The card grid starts @@ -285,13 +285,12 @@ pub fn compute_layout( ); } - // Adaptive tableau fan fraction. On height-limited (desktop) windows the - // height-based sizing already ensures a worst-case 13-card column fits at - // TABLEAU_FAN_FRAC (0.25), so the formula returns ≈0.25 and the clamp - // keeps it there — no change from prior behaviour. On width-limited - // (portrait phone) windows card_size is small and lots of vertical space - // is unused; we solve for the fraction that exactly fills the available - // space to the bottom margin. + // Adaptive tableau fan fraction. On height-limited windows the height-based + // sizing already ensures a worst-case 13-card column fits at TABLEAU_FAN_FRAC, + // so the formula returns the minimum and the clamp keeps it there. On + // width-limited (portrait phone) windows card_size is small and lots of + // vertical space is unused; solve for the fraction that fills the available + // space. `apply_dynamic_tableau_fan` later refines this for the actual deal. // // avail = distance from the top of the first tableau card to the bottom // margin — i.e. the space available for 12 fan steps. @@ -302,20 +301,17 @@ pub fn compute_layout( } else { TABLEAU_FAN_FRAC }; - // Never go below the desktop minimum — avoids shrinking the fan on - // degenerate near-square windows where the formula might undershoot. let tableau_fan_frac = ideal_fan_frac.max(TABLEAU_FAN_FRAC); - // Scale the face-down fraction proportionally so rendering and hit-testing - // stay in sync (TABLEAU_FACEDOWN_FAN_FRAC / TABLEAU_FAN_FRAC = 0.48 ratio). let facedown_scale = TABLEAU_FACEDOWN_FAN_FRAC / TABLEAU_FAN_FRAC; let tableau_facedown_fan_frac = tableau_fan_frac * facedown_scale; + let available_tableau_height = avail; Layout { card_size, pile_positions, tableau_fan_frac, tableau_facedown_fan_frac, - available_tableau_height: avail, + available_tableau_height, } }