UNPKG

framer-motion

Version:

An open source and production-ready motion library for React on the web

82 lines (72 loc) • 2.53 kB
import { useTransform } from "../value/use-transform" import { MotionValue } from "./" import { invariant, warning } from "hey-listen" import { useMotionValue } from "./use-motion-value" import { useVisualElementContext } from "../motion/context/MotionContext" interface ScaleMotionValues { scaleX: MotionValue<number> scaleY: MotionValue<number> } // Keep things reasonable and avoid scale: Infinity. In practise we might need // to add another value, opacity, that could interpolate scaleX/Y [0,0.01] => [0,1] // to simply hide content at unreasonable scales. const maxScale = 100000 export const invertScale = (scale: number) => scale > 0.001 ? 1 / scale : maxScale let hasWarned = false /** * Returns a `MotionValue` each for `scaleX` and `scaleY` that update with the inverse * of their respective parent scales. * * This is useful for undoing the distortion of content when scaling a parent component. * * By default, `useInvertedScale` will automatically fetch `scaleX` and `scaleY` from the nearest parent. * By passing other `MotionValue`s in as `useInvertedScale({ scaleX, scaleY })`, it will invert the output * of those instead. * * @motion * * ```jsx * const MyComponent = () => { * const { scaleX, scaleY } = useInvertedScale() * return <motion.div style={{ scaleX, scaleY }} /> * } * ``` * * @library * * ```jsx * function MyComponent() { * const { scaleX, scaleY } = useInvertedScale() * return <Frame scaleX={scaleX} scaleY={scaleY} /> * } * ``` * * @deprecated */ export function useInvertedScale( scale?: Partial<ScaleMotionValues> ): ScaleMotionValues { let parentScaleX = useMotionValue(1) let parentScaleY = useMotionValue(1) const visualElement = useVisualElementContext() invariant( !!(scale || visualElement), "If no scale values are provided, useInvertedScale must be used within a child of another motion component." ) warning( hasWarned, "useInvertedScale is deprecated and will be removed in 3.0. Use the layout prop instead." ) hasWarned = true if (scale) { parentScaleX = scale.scaleX || parentScaleX parentScaleY = scale.scaleY || parentScaleY } else if (visualElement) { parentScaleX = visualElement.getValue("scaleX", 1) parentScaleY = visualElement.getValue("scaleY", 1) } const scaleX = useTransform(parentScaleX, invertScale) const scaleY = useTransform(parentScaleY, invertScale) return { scaleX, scaleY } }