diff --git a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx
index 4903df216e..67284c14b1 100644
--- a/packages/framer-motion/src/value/__tests__/use-transform.test.tsx
+++ b/packages/framer-motion/src/value/__tests__/use-transform.test.tsx
@@ -1,6 +1,6 @@
import { render } from "../../../jest.setup"
import * as React from "react"
-import { motion } from "../../"
+import { frame, motion } from "../../"
import { useMotionValue } from "../use-motion-value"
import { useTransform } from "../use-transform"
import { MotionValue, motionValue } from ".."
@@ -56,6 +56,33 @@ describe("as function with multiple values", () => {
})
})
+describe("as function with no passed MotionValues", () => {
+ test("sets initial value", async () => {
+ const x = motionValue(4)
+ const Component = () => {
+ const y = useMotionValue("5px")
+ const z = useTransform(() => x.get() * parseFloat(y.get()))
+ return
+ }
+
+ const { container } = render()
+ expect(container.firstChild).toHaveStyle(
+ "transform: translateX(4px) translateY(5px) translateZ(20px)"
+ )
+
+ x.set(5)
+
+ await new Promise((resolve) => {
+ frame.postRender(() => {
+ expect(container.firstChild).toHaveStyle(
+ "transform: translateX(5px) translateY(5px) translateZ(25px)"
+ )
+ resolve()
+ })
+ })
+ })
+})
+
describe("as input/output range", () => {
test("sets initial value", async () => {
const Component = () => {
diff --git a/packages/framer-motion/src/value/index.ts b/packages/framer-motion/src/value/index.ts
index 4778ecf47c..3c3f87a288 100644
--- a/packages/framer-motion/src/value/index.ts
+++ b/packages/framer-motion/src/value/index.ts
@@ -48,6 +48,10 @@ export interface MotionValueOptions {
owner?: Owner
}
+export const collectMotionValues: { current: MotionValue[] | undefined } = {
+ current: undefined,
+}
+
/**
* `MotionValue` is used to track the state and velocity of motion values.
*
@@ -314,6 +318,10 @@ export class MotionValue {
* @public
*/
get() {
+ if (collectMotionValues.current) {
+ collectMotionValues.current.push(this)
+ }
+
return this.current
}
diff --git a/packages/framer-motion/src/value/use-computed.ts b/packages/framer-motion/src/value/use-computed.ts
index 5e4938e304..4c22f893ed 100644
--- a/packages/framer-motion/src/value/use-computed.ts
+++ b/packages/framer-motion/src/value/use-computed.ts
@@ -1,13 +1,21 @@
-import type { MotionValue } from "."
+import { collectMotionValues, type MotionValue } from "."
import { useCombineMotionValues } from "./use-combine-values"
-let collectMotionValues: MotionValue[] | undefined = undefined
-
export function useComputed(compute: () => O): MotionValue {
- collectMotionValues = []
+ /**
+ * Open session of collectMotionValues. Any MotionValue that calls get()
+ * will be saved into this array.
+ */
+ collectMotionValues.current = []
+
compute()
- const value = useCombineMotionValues(collectMotionValues, compute)
- collectMotionValues = undefined
+
+ const value = useCombineMotionValues(collectMotionValues.current, compute)
+
+ /**
+ * Synchronously close session of collectMotionValues.
+ */
+ collectMotionValues.current = undefined
return value
}
diff --git a/packages/framer-motion/src/value/use-transform.ts b/packages/framer-motion/src/value/use-transform.ts
index b530261168..4f0b43b5dc 100644
--- a/packages/framer-motion/src/value/use-transform.ts
+++ b/packages/framer-motion/src/value/use-transform.ts
@@ -2,6 +2,7 @@ import { MotionValue } from "../value"
import { transform, TransformOptions } from "../utils/transform"
import { useCombineMotionValues } from "./use-combine-values"
import { useConstant } from "../utils/use-constant"
+import { useComputed } from "./use-computed"
export type InputRange = number[]
type SingleTransformer = (input: I) => O