securityos/node_modules/framer-motion/dist/es/gestures/drag/utils/constraints.mjs

126 lines
4.7 KiB
JavaScript

import { progress } from '../../../utils/progress.mjs';
import { calcLength } from '../../../projection/geometry/delta-calc.mjs';
import { clamp } from '../../../utils/clamp.mjs';
import { mix } from '../../../utils/mix.mjs';
/**
* Apply constraints to a point. These constraints are both physical along an
* axis, and an elastic factor that determines how much to constrain the point
* by if it does lie outside the defined parameters.
*/
function applyConstraints(point, { min, max }, elastic) {
if (min !== undefined && point < min) {
// If we have a min point defined, and this is outside of that, constrain
point = elastic ? mix(min, point, elastic.min) : Math.max(point, min);
}
else if (max !== undefined && point > max) {
// If we have a max point defined, and this is outside of that, constrain
point = elastic ? mix(max, point, elastic.max) : Math.min(point, max);
}
return point;
}
/**
* Calculate constraints in terms of the viewport when defined relatively to the
* measured axis. This is measured from the nearest edge, so a max constraint of 200
* on an axis with a max value of 300 would return a constraint of 500 - axis length
*/
function calcRelativeAxisConstraints(axis, min, max) {
return {
min: min !== undefined ? axis.min + min : undefined,
max: max !== undefined
? axis.max + max - (axis.max - axis.min)
: undefined,
};
}
/**
* Calculate constraints in terms of the viewport when
* defined relatively to the measured bounding box.
*/
function calcRelativeConstraints(layoutBox, { top, left, bottom, right }) {
return {
x: calcRelativeAxisConstraints(layoutBox.x, left, right),
y: calcRelativeAxisConstraints(layoutBox.y, top, bottom),
};
}
/**
* Calculate viewport constraints when defined as another viewport-relative axis
*/
function calcViewportAxisConstraints(layoutAxis, constraintsAxis) {
let min = constraintsAxis.min - layoutAxis.min;
let max = constraintsAxis.max - layoutAxis.max;
// If the constraints axis is actually smaller than the layout axis then we can
// flip the constraints
if (constraintsAxis.max - constraintsAxis.min <
layoutAxis.max - layoutAxis.min) {
[min, max] = [max, min];
}
return { min, max };
}
/**
* Calculate viewport constraints when defined as another viewport-relative box
*/
function calcViewportConstraints(layoutBox, constraintsBox) {
return {
x: calcViewportAxisConstraints(layoutBox.x, constraintsBox.x),
y: calcViewportAxisConstraints(layoutBox.y, constraintsBox.y),
};
}
/**
* Calculate a transform origin relative to the source axis, between 0-1, that results
* in an asthetically pleasing scale/transform needed to project from source to target.
*/
function calcOrigin(source, target) {
let origin = 0.5;
const sourceLength = calcLength(source);
const targetLength = calcLength(target);
if (targetLength > sourceLength) {
origin = progress(target.min, target.max - sourceLength, source.min);
}
else if (sourceLength > targetLength) {
origin = progress(source.min, source.max - targetLength, target.min);
}
return clamp(0, 1, origin);
}
/**
* Rebase the calculated viewport constraints relative to the layout.min point.
*/
function rebaseAxisConstraints(layout, constraints) {
const relativeConstraints = {};
if (constraints.min !== undefined) {
relativeConstraints.min = constraints.min - layout.min;
}
if (constraints.max !== undefined) {
relativeConstraints.max = constraints.max - layout.min;
}
return relativeConstraints;
}
const defaultElastic = 0.35;
/**
* Accepts a dragElastic prop and returns resolved elastic values for each axis.
*/
function resolveDragElastic(dragElastic = defaultElastic) {
if (dragElastic === false) {
dragElastic = 0;
}
else if (dragElastic === true) {
dragElastic = defaultElastic;
}
return {
x: resolveAxisElastic(dragElastic, "left", "right"),
y: resolveAxisElastic(dragElastic, "top", "bottom"),
};
}
function resolveAxisElastic(dragElastic, minLabel, maxLabel) {
return {
min: resolvePointElastic(dragElastic, minLabel),
max: resolvePointElastic(dragElastic, maxLabel),
};
}
function resolvePointElastic(dragElastic, label) {
return typeof dragElastic === "number"
? dragElastic
: dragElastic[label] || 0;
}
export { applyConstraints, calcOrigin, calcRelativeAxisConstraints, calcRelativeConstraints, calcViewportAxisConstraints, calcViewportConstraints, defaultElastic, rebaseAxisConstraints, resolveAxisElastic, resolveDragElastic, resolvePointElastic };