{"version":3,"file":"constraints.mjs","sources":["../../../../../src/gestures/drag/utils/constraints.ts"],"sourcesContent":["import { calcLength, mixNumber, type DragElastic, type ResolvedConstraints } from \"motion-dom\"\nimport {\n    Axis,\n    BoundingBox,\n    Box,\n    progress as calcProgress,\n    clamp,\n    Point,\n} from \"motion-utils\"\n\n/**\n * Apply constraints to a point. These constraints are both physical along an\n * axis, and an elastic factor that determines how much to constrain the point\n * by if it does lie outside the defined parameters.\n */\nexport function applyConstraints(\n    point: number,\n    { min, max }: Partial<Axis>,\n    elastic?: Axis\n): number {\n    if (min !== undefined && point < min) {\n        // If we have a min point defined, and this is outside of that, constrain\n        point = elastic\n            ? mixNumber(min, point, elastic.min)\n            : Math.max(point, min)\n    } else if (max !== undefined && point > max) {\n        // If we have a max point defined, and this is outside of that, constrain\n        point = elastic\n            ? mixNumber(max, point, elastic.max)\n            : Math.min(point, max)\n    }\n\n    return point\n}\n\n/**\n * Calculates a min projection point based on a pointer, pointer progress\n * within the drag target, and constraints.\n *\n * For instance if an element was 100px width, we were dragging from 0.25\n * along this axis, the pointer is at 200px, and there were no constraints,\n * we would calculate a min projection point of 175px.\n */\nexport function calcConstrainedMinPoint(\n    point: number,\n    length: number,\n    progress: number,\n    constraints?: Partial<Axis>,\n    elastic?: Axis\n): number {\n    // Calculate a min point for this axis and apply it to the current pointer\n    const min = point - length * progress\n\n    return constraints ? applyConstraints(min, constraints, elastic) : min\n}\n\n/**\n * Calculate constraints in terms of the viewport when defined relatively to the\n * measured axis. This is measured from the nearest edge, so a max constraint of 200\n * on an axis with a max value of 300 would return a constraint of 500 - axis length\n */\nexport function calcRelativeAxisConstraints(\n    axis: Axis,\n    min?: number,\n    max?: number\n): Partial<Axis> {\n    return {\n        min: min !== undefined ? axis.min + min : undefined,\n        max:\n            max !== undefined\n                ? axis.max + max - (axis.max - axis.min)\n                : undefined,\n    }\n}\n\n/**\n * Calculate constraints in terms of the viewport when\n * defined relatively to the measured bounding box.\n */\nexport function calcRelativeConstraints(\n    layoutBox: Box,\n    { top, left, bottom, right }: Partial<BoundingBox>\n): ResolvedConstraints {\n    return {\n        x: calcRelativeAxisConstraints(layoutBox.x, left, right),\n        y: calcRelativeAxisConstraints(layoutBox.y, top, bottom),\n    }\n}\n\n/**\n * Calculate viewport constraints when defined as another viewport-relative axis\n */\nexport function calcViewportAxisConstraints(\n    layoutAxis: Axis,\n    constraintsAxis: Axis\n) {\n    let min = constraintsAxis.min - layoutAxis.min\n    let max = constraintsAxis.max - layoutAxis.max\n\n    // If the constraints axis is actually smaller than the layout axis then we can\n    // flip the constraints\n    if (\n        constraintsAxis.max - constraintsAxis.min <\n        layoutAxis.max - layoutAxis.min\n    ) {\n        ;[min, max] = [max, min]\n    }\n\n    return { min, max }\n}\n\n/**\n * Calculate viewport constraints when defined as another viewport-relative box\n */\nexport function calcViewportConstraints(layoutBox: Box, constraintsBox: Box) {\n    return {\n        x: calcViewportAxisConstraints(layoutBox.x, constraintsBox.x),\n        y: calcViewportAxisConstraints(layoutBox.y, constraintsBox.y),\n    }\n}\n\n/**\n * Calculate a transform origin relative to the source axis, between 0-1, that results\n * in an asthetically pleasing scale/transform needed to project from source to target.\n */\nexport function calcOrigin(source: Axis, target: Axis): number {\n    let origin = 0.5\n    const sourceLength = calcLength(source)\n    const targetLength = calcLength(target)\n\n    if (targetLength > sourceLength) {\n        origin = calcProgress(target.min, target.max - sourceLength, source.min)\n    } else if (sourceLength > targetLength) {\n        origin = calcProgress(source.min, source.max - targetLength, target.min)\n    }\n\n    return clamp(0, 1, origin)\n}\n\n/**\n * Calculate the relative progress of one constraints box relative to another.\n * Imagine a page scroll bar. At the top, this would return 0, at the bottom, 1.\n * Anywhere in-between, a value between 0 and 1.\n *\n * This also handles flipped constraints, for instance a draggable container within\n * a smaller viewport like a scrollable view.\n */\nexport function calcProgressWithinConstraints(\n    layoutBox: Box,\n    constraintsBox: Box\n): Point {\n    return {\n        x: calcOrigin(layoutBox.x, constraintsBox.x),\n        y: calcOrigin(layoutBox.y, constraintsBox.y),\n    }\n}\n\n/**\n * Calculate the an axis position based on two axes and a progress value.\n */\nexport function calcPositionFromProgress(\n    axis: Axis,\n    constraints: Axis,\n    progress: number\n): Axis {\n    const axisLength = axis.max - axis.min\n    const min = mixNumber(\n        constraints.min,\n        constraints.max - axisLength,\n        progress\n    )\n    return { min, max: min + axisLength }\n}\n\n/**\n * Rebase the calculated viewport constraints relative to the layout.min point.\n */\nexport function rebaseAxisConstraints(\n    layout: Axis,\n    constraints: Partial<Axis>\n): Partial<Axis> {\n    const relativeConstraints: Partial<Axis> = {}\n\n    if (constraints.min !== undefined) {\n        relativeConstraints.min = constraints.min - layout.min\n    }\n\n    if (constraints.max !== undefined) {\n        relativeConstraints.max = constraints.max - layout.min\n    }\n\n    return relativeConstraints\n}\n\nexport const defaultElastic = 0.35\n/**\n * Accepts a dragElastic prop and returns resolved elastic values for each axis.\n */\nexport function resolveDragElastic(\n    dragElastic: DragElastic = defaultElastic\n): Box {\n    if (dragElastic === false) {\n        dragElastic = 0\n    } else if (dragElastic === true) {\n        dragElastic = defaultElastic\n    }\n\n    return {\n        x: resolveAxisElastic(dragElastic, \"left\", \"right\"),\n        y: resolveAxisElastic(dragElastic, \"top\", \"bottom\"),\n    }\n}\n\nexport function resolveAxisElastic(\n    dragElastic: DragElastic,\n    minLabel: string,\n    maxLabel: string\n): Axis {\n    return {\n        min: resolvePointElastic(dragElastic, minLabel),\n        max: resolvePointElastic(dragElastic, maxLabel),\n    }\n}\n\nexport function resolvePointElastic(\n    dragElastic: DragElastic,\n    label: string\n): number {\n    return typeof dragElastic === \"number\"\n        ? dragElastic\n        : dragElastic[label as keyof typeof dragElastic] || 0\n}\n"],"names":["calcProgress"],"mappings":"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"}