diff --git a/packages/framer-motion/src/projection/geometry/delta-apply.ts b/packages/framer-motion/src/projection/geometry/delta-apply.ts index 8bb7d0efc6..a12badfaa2 100644 --- a/packages/framer-motion/src/projection/geometry/delta-apply.ts +++ b/packages/framer-motion/src/projection/geometry/delta-apply.ts @@ -154,34 +154,33 @@ export function translateAxis(axis: Axis, distance: number) { */ export function transformAxis( axis: Axis, - transforms: ResolvedValues, - [key, scaleKey, originKey]: string[] + axisTranslate: number, + axisScale: number, + boxScale?: number, + axisOrigin: number = 0.5 ): void { - const axisOrigin = - transforms[originKey] !== undefined ? transforms[originKey] : 0.5 - - const originPoint = mixNumber(axis.min, axis.max, axisOrigin as number) + const originPoint = mixNumber(axis.min, axis.max, axisOrigin) // Apply the axis delta to the final axis - applyAxisDelta( - axis, - transforms[key] as number, - transforms[scaleKey] as number, - originPoint, - transforms.scale as number - ) + applyAxisDelta(axis, axisTranslate, axisScale, originPoint, boxScale) } -/** - * The names of the motion values we want to apply as translation, scale and origin. - */ -const xKeys = ["x", "scaleX", "originX"] -const yKeys = ["y", "scaleY", "originY"] - /** * Apply a transform to a box from the latest resolved motion values. */ export function transformBox(box: Box, transform: ResolvedValues) { - transformAxis(box.x, transform, xKeys) - transformAxis(box.y, transform, yKeys) + transformAxis( + box.x, + transform.x as number, + transform.scaleX as number, + transform.scale as number, + transform.originX as number + ) + transformAxis( + box.y, + transform.y as number, + transform.scaleY as number, + transform.scale as number, + transform.originY as number + ) } diff --git a/packages/framer-motion/src/projection/geometry/delta-calc.ts b/packages/framer-motion/src/projection/geometry/delta-calc.ts index a0c76e9925..aa11fd21f0 100644 --- a/packages/framer-motion/src/projection/geometry/delta-calc.ts +++ b/packages/framer-motion/src/projection/geometry/delta-calc.ts @@ -2,11 +2,22 @@ import { ResolvedValues } from "../../render/types" import { mixNumber } from "../../utils/mix/number" import { Axis, AxisDelta, Box, Delta } from "./types" +const SCALE_PRECISION = 0.0001 +const SCALE_MIN = 1 - SCALE_PRECISION +const SCALE_MAX = 1 + SCALE_PRECISION +const TRANSLATE_PRECISION = 0.01 +const TRANSLATE_MIN = 0 - TRANSLATE_PRECISION +const TRANSLATE_MAX = 0 + TRANSLATE_PRECISION + export function calcLength(axis: Axis) { return axis.max - axis.min } -export function isNear(value: number, target = 0, maxDistance = 0.01): boolean { +export function isNear( + value: number, + target: number, + maxDistance: number +): boolean { return Math.abs(value - target) <= maxDistance } @@ -18,13 +29,24 @@ export function calcAxisDelta( ) { delta.origin = origin delta.originPoint = mixNumber(source.min, source.max, delta.origin) - delta.scale = calcLength(target) / calcLength(source) - if (isNear(delta.scale, 1, 0.0001) || isNaN(delta.scale)) delta.scale = 1 - delta.translate = mixNumber(target.min, target.max, delta.origin) - delta.originPoint - if (isNear(delta.translate) || isNaN(delta.translate)) delta.translate = 0 + + if ( + (delta.scale >= SCALE_MIN && delta.scale <= SCALE_MAX) || + isNaN(delta.scale) + ) { + delta.scale = 1 + } + + if ( + (delta.translate >= TRANSLATE_MIN && + delta.translate <= TRANSLATE_MAX) || + isNaN(delta.translate) + ) { + delta.translate = 0 + } } export function calcBoxDelta(