UNPKG

framer-motion

Version:

A simple and powerful JavaScript animation library

1 lines 3.44 kB
{"version":3,"file":"transform-viewbox-point.mjs","sources":["../../../src/utils/transform-viewbox-point.ts"],"sourcesContent":["import type { Point, TransformPoint } from \"motion-utils\"\nimport type { RefObject } from \"react\"\n\n/**\n * Creates a `transformPagePoint` function that accounts for SVG viewBox scaling.\n *\n * When dragging SVG elements inside an SVG with a viewBox that differs from\n * the rendered dimensions (e.g., `viewBox=\"0 0 100 100\"` but rendered at 500x500 pixels),\n * pointer coordinates need to be transformed to match the SVG's coordinate system.\n *\n * @example\n * ```jsx\n * function App() {\n * const svgRef = useRef<SVGSVGElement>(null)\n *\n * return (\n * <MotionConfig transformPagePoint={transformViewBoxPoint(svgRef)}>\n * <svg ref={svgRef} viewBox=\"0 0 100 100\" width={500} height={500}>\n * <motion.rect drag width={10} height={10} />\n * </svg>\n * </MotionConfig>\n * )\n * }\n * ```\n *\n * @param svgRef - A React ref to the SVG element\n * @returns A transformPagePoint function for use with MotionConfig\n *\n * @public\n */\nexport function transformViewBoxPoint(\n svgRef: RefObject<SVGSVGElement | null>\n): TransformPoint {\n return (point: Point): Point => {\n const svg = svgRef.current\n if (!svg) {\n return point\n }\n\n // Get the viewBox attribute\n const viewBox = svg.viewBox?.baseVal\n if (!viewBox || (viewBox.width === 0 && viewBox.height === 0)) {\n // No viewBox or empty viewBox - no transformation needed\n return point\n }\n\n // Get the rendered dimensions of the SVG\n const bbox = svg.getBoundingClientRect()\n if (bbox.width === 0 || bbox.height === 0) {\n return point\n }\n\n // Calculate scale factors\n const scaleX = viewBox.width / bbox.width\n const scaleY = viewBox.height / bbox.height\n\n // Get the SVG's position on the page\n const svgX = bbox.left + window.scrollX\n const svgY = bbox.top + window.scrollY\n\n // Transform the point:\n // 1. Calculate position relative to SVG\n // 2. Scale by viewBox/viewport ratio\n // 3. Add back the SVG position (but in SVG coordinates)\n return {\n x: (point.x - svgX) * scaleX + svgX,\n y: (point.y - svgY) * scaleY + svgY,\n }\n }\n}\n"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BG;AACG,SAAU,qBAAqB,CACjC,MAAuC,EAAA;IAEvC,OAAO,CAAC,KAAY,KAAW;AAC3B,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAA;QAC1B,IAAI,CAAC,GAAG,EAAE;AACN,YAAA,OAAO,KAAK,CAAA;SACf;;AAGD,QAAA,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,OAAO,CAAA;AACpC,QAAA,IAAI,CAAC,OAAO,KAAK,OAAO,CAAC,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE;;AAE3D,YAAA,OAAO,KAAK,CAAA;SACf;;AAGD,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,qBAAqB,EAAE,CAAA;AACxC,QAAA,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;AACvC,YAAA,OAAO,KAAK,CAAA;SACf;;QAGD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;;QAG3C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAA;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,OAAO,CAAA;;;;;QAMtC,OAAO;YACH,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,GAAG,IAAI;YACnC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,IAAI,MAAM,GAAG,IAAI;SACtC,CAAA;AACL,KAAC,CAAA;AACL;;;;"}