configurable allowance

This commit is contained in:
Ryan Di 2025-05-02 17:52:14 +10:00
parent 2d0c0afa34
commit 4208c97b62

View File

@ -11,6 +11,7 @@ import { getNormalizedZoom } from "./normalize";
* *
* @param scrollConstraints - The constraints of the scrollable area including width, height, and position. * @param scrollConstraints - The constraints of the scrollable area including width, height, and position.
* @param appState - An object containing the current horizontal and vertical scroll positions. * @param appState - An object containing the current horizontal and vertical scroll positions.
* @param overscrollAllowance - Optional parameter to specify the overscroll allowance percentage.
* @returns An object containing the calculated optimal horizontal and vertical scroll positions and zoom level. * @returns An object containing the calculated optimal horizontal and vertical scroll positions and zoom level.
* *
* @example * @example
@ -20,6 +21,7 @@ import { getNormalizedZoom } from "./normalize";
export const calculateConstrainedScrollCenter = ( export const calculateConstrainedScrollCenter = (
state: AppState, state: AppState,
{ scrollX, scrollY }: Pick<AppState, "scrollX" | "scrollY">, { scrollX, scrollY }: Pick<AppState, "scrollX" | "scrollY">,
overscrollAllowance?: number,
): { ): {
scrollX: AppState["scrollX"]; scrollX: AppState["scrollX"];
scrollY: AppState["scrollY"]; scrollY: AppState["scrollY"];
@ -57,6 +59,7 @@ export const calculateConstrainedScrollCenter = (
height, height,
zoom: _zoom, zoom: _zoom,
allowOverscroll: false, allowOverscroll: false,
overscrollAllowance,
}); });
return { return {
@ -167,15 +170,22 @@ const calculateConstraints = ({
height, height,
zoom, zoom,
allowOverscroll, allowOverscroll,
overscrollAllowance,
}: { }: {
scrollConstraints: ScrollConstraints; scrollConstraints: ScrollConstraints;
width: AppState["width"]; width: AppState["width"];
height: AppState["height"]; height: AppState["height"];
zoom: AppState["zoom"]; zoom: AppState["zoom"];
allowOverscroll: boolean; allowOverscroll: boolean;
overscrollAllowance?: number;
}) => { }) => {
// Set the overscroll allowance percentage // Validate the overscroll allowance percentage
const OVERSCROLL_ALLOWANCE_PERCENTAGE = 0.2; const validatedOverscroll =
overscrollAllowance != null &&
overscrollAllowance >= 0 &&
overscrollAllowance <= 1
? overscrollAllowance
: 0.2;
/** /**
* Calculates the center position of the constrained scroll area. * Calculates the center position of the constrained scroll area.
@ -194,10 +204,8 @@ const calculateConstraints = ({
* @returns The overscroll allowance values for the X and Y axes. * @returns The overscroll allowance values for the X and Y axes.
*/ */
const calculateOverscrollAllowance = () => { const calculateOverscrollAllowance = () => {
const overscrollAllowanceX = const overscrollAllowanceX = validatedOverscroll * scrollConstraints.width;
OVERSCROLL_ALLOWANCE_PERCENTAGE * scrollConstraints.width; const overscrollAllowanceY = validatedOverscroll * scrollConstraints.height;
const overscrollAllowanceY =
OVERSCROLL_ALLOWANCE_PERCENTAGE * scrollConstraints.height;
return Math.min(overscrollAllowanceX, overscrollAllowanceY); return Math.min(overscrollAllowanceX, overscrollAllowanceY);
}; };
@ -284,14 +292,14 @@ const calculateConstraints = ({
); );
const { constrainedScrollCenterX, constrainedScrollCenterY } = const { constrainedScrollCenterX, constrainedScrollCenterY } =
calculateConstrainedScrollCenter(constrainedZoom); calculateConstrainedScrollCenter(constrainedZoom);
const overscrollAllowance = calculateOverscrollAllowance(); const overscrollAllowanceValue = calculateOverscrollAllowance();
const shouldAdjustForCenteredViewX = constrainedZoom <= zoomLevelX; const shouldAdjustForCenteredViewX = constrainedZoom <= zoomLevelX;
const shouldAdjustForCenteredViewY = constrainedZoom <= zoomLevelY; const shouldAdjustForCenteredViewY = constrainedZoom <= zoomLevelY;
const { maxScrollX, minScrollX, maxScrollY, minScrollY } = const { maxScrollX, minScrollX, maxScrollY, minScrollY } =
calculateMinMaxScrollValues( calculateMinMaxScrollValues(
shouldAdjustForCenteredViewX, shouldAdjustForCenteredViewX,
shouldAdjustForCenteredViewY, shouldAdjustForCenteredViewY,
overscrollAllowance, overscrollAllowanceValue,
constrainedScrollCenterX, constrainedScrollCenterX,
constrainedScrollCenterY, constrainedScrollCenterY,
constrainedZoom, constrainedZoom,