Skip to content

Commit

Permalink
Improving
Browse files Browse the repository at this point in the history
  • Loading branch information
mattgperry committed May 16, 2024
1 parent d4826ad commit 91aff08
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 41 deletions.
74 changes: 41 additions & 33 deletions dev/examples/useSpring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,42 @@ import { useEffect, useRef, useState } from "react"
const spring = {
stiffness: 300,
damping: 28,
restDelta: 0.001,
restSpeed: 0.001,
}

const useMousePosition = () => {
const [mousePosition, setMousePosition] = useState({ x: null, y: null })

const updateMousePosition = (e) => {
setMousePosition({ x: e.clientX, y: e.clientY })
}

useEffect(() => {
window.addEventListener("mousemove", updateMousePosition)

return () =>
window.removeEventListener("mousemove", updateMousePosition)
}, [])

return mousePosition
restDelta: 0.00001,
restSpeed: 0.00001,
}

function DragExample() {
const dragX = useMotionValue(0)
const dragY = useMotionValue(0)
const x = useSpring(dragX)
const y = useSpring(dragY, spring)
// const dragY = useMotionValue(0)
const x = useSpring(dragX, spring)
// const y = useSpring(dragY, spring)
return (
<motion.div
drag
drag="x"
dragMomentum={false}
_dragX={dragX}
_dragY={dragY}
style={{ width: 100, height: 100, background: "red", x, y }}
// _dragY={dragY}
style={{ width: 100, height: 100, background: "red", x }}
>
Drag
</motion.div>
)
}

function RerenderExample() {
const { x, y } = useMousePosition()
const [mousePosition, setMousePosition] = useState({ x: null, y: null })

const updateMousePosition = useRef((e) => {
setMousePosition({ x: e.clientX, y: e.clientY })
})

const size = 40
const ref = useRef<HTMLDivElement>(null)
console.log(x)
// console.log(x)
return (
<motion.div
ref={ref}
animate={{ x }}
animate={{ x: mousePosition.x }}
transition={spring}
style={{
width: 100,
Expand All @@ -60,6 +48,24 @@ function RerenderExample() {
position: "absolute",
inset: 0,
}}
onTapStart={() => {
window.addEventListener(
"mousemove",
updateMousePosition.current
)
}}
onTap={() => {
window.removeEventListener(
"mousemove",
updateMousePosition.current
)
}}
onTapCancel={() => {
window.removeEventListener(
"mousemove",
updateMousePosition.current
)
}}
>
Rerender
</motion.div>
Expand All @@ -69,15 +75,17 @@ function RerenderExample() {
function MouseEventExample() {
const xPoint = useMotionValue(0)
const yPoint = useMotionValue(0)
const x = useSpring(xPoint, spring)
const y = useSpring(yPoint, spring)
const x = useSpring(0, spring)
const y = useSpring(0, spring)
const ref = useRef<HTMLDivElement>(null)
const onMove = useRef<(event: MouseEvent) => void>(
({ clientX, clientY }: MouseEvent) => {
const element = ref.current!

xPoint.set(clientX - element.offsetLeft - element.offsetWidth / 2)
yPoint.set(clientY - element.offsetTop - element.offsetHeight / 2)
// frame.update(() => {
x.set(clientX - element.offsetLeft - element.offsetWidth / 2)
// y.set(clientY - element.offsetTop - element.offsetHeight / 2)
// })
}
)

Expand All @@ -92,7 +100,7 @@ function MouseEventExample() {
return (
<motion.div
ref={ref}
style={{ width: 100, height: 100, background: "yellow", x, y }}
style={{ width: 100, height: 100, background: "yellow", x }}
onTapStart={startPointer}
onTapCancel={cancelPointer}
onTap={cancelPointer}
Expand Down
3 changes: 3 additions & 0 deletions packages/framer-motion/src/frameloop/batcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export function createRenderBatcher(
delta: 0,
timestamp: 0,
isProcessing: false,
currentStep: "",
}

const steps = stepsOrder.reduce((acc, key) => {
Expand All @@ -32,7 +33,9 @@ export function createRenderBatcher(
}, {} as Steps)

const processStep = (stepId: StepId) => {
state.currentStep = stepId
steps[stepId].process(state)
state.currentStep = ""
}

const processBatch = () => {
Expand Down
1 change: 1 addition & 0 deletions packages/framer-motion/src/frameloop/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ export interface FrameData {
delta: number
timestamp: number
isProcessing: boolean
currentStep: StepId | ""
}
28 changes: 20 additions & 8 deletions packages/framer-motion/src/value/use-spring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useMotionValue } from "./use-motion-value"
import { MotionConfigContext } from "../context/MotionConfigContext"
import { SpringOptions } from "../animation/types"
import { useIsomorphicLayoutEffect } from "../utils/use-isomorphic-effect"
import { frameData } from "../frameloop"
import { frame, frameData } from "../frameloop"
import {
MainThreadAnimation,
animateValue,
Expand Down Expand Up @@ -47,13 +47,10 @@ export function useSpring(
}

useInsertionEffect(() => {
return value.attach((v, set) => {
/**
* A more hollistic approach to this might be to use isStatic to fix VisualElement animations
* at that level, but this will work for now
*/
if (isStatic) return set(v)
let latestValue: number
let set: (v: number) => void

const startAnimation = () => {
/**
* If the previous animation hasn't had the chance to even render a frame, render it now.
*/
Expand All @@ -64,15 +61,30 @@ export function useSpring(

stopAnimation()

console.log("useSpring", value.getVelocity(), frameData.currentStep)

activeSpringAnimation.current = animateValue({
keyframes: [value.get(), v],
keyframes: [value.get(), latestValue],
velocity: value.getVelocity(),
type: "spring",
restDelta: 0.001,
restSpeed: 0.01,
...config,
onUpdate: set,
})
}

return value.attach((v, frameSet) => {
/**
* A more hollistic approach to this might be to use isStatic to fix VisualElement animations
* at that level, but this will work for now
*/
if (isStatic) return set(v)

latestValue = v
set = frameSet

frame.update(startAnimation, true)

return value.get()
}, stopAnimation)
Expand Down

0 comments on commit 91aff08

Please sign in to comment.