Skip to content

Commit

Permalink
Merge pull request #2329 from framer/fix/handoff-waapi
Browse files Browse the repository at this point in the history
Fixing handoff of WAAPI animations
  • Loading branch information
mergetron[bot] authored Sep 4, 2023
2 parents 1609dcb + c3f344d commit da1cad3
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 9 deletions.
19 changes: 13 additions & 6 deletions dev/optimized-appear/resync.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
startOptimizedAppearAnimation,
optimizedAppearDataAttribute,
motionValue,
frame,
} = window.Motion
const { matchViewportBox } = window.Assert
const root = document.getElementById("root")
Expand Down Expand Up @@ -66,12 +67,18 @@
* On animation start, check the values we expect to see here
*/
onAnimationStart: () => {
// matchViewportBox(document.getElementById("box"), {
// top: 100,
// right: 250,
// left: 150,
// bottom: 200,
// })
frame.postRender(() => {
frame.postRender(() => {
const box = document.getElementById("box")

if (!box) return

const { opacity } = window.getComputedStyle(box)
if (parseFloat(opacity) < 0.65) {
showError(box, "Resync failed")
}
})
})
},
[optimizedAppearDataAttribute]: "a",
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EasingDefinition } from "../../../easing/types"
import { frame, cancelFrame } from "../../../frameloop"
import { frame, cancelFrame, frameData } from "../../../frameloop"
import type { VisualElement } from "../../../render/VisualElement"
import type { MotionValue } from "../../../value"
import { AnimationPlaybackControls, ValueAnimationOptions } from "../../types"
Expand Down Expand Up @@ -136,6 +136,18 @@ export function createAcceleratedAnimation(
}
)

/**
* WAAPI animations don't resolve startTime synchronously. But a blocked
* thread could delay the startTime resolution by a noticeable amount.
* For synching handoff animations with the new Motion animation we want
* to ensure startTime is synchronously set.
*/
if (options.syncStart) {
animation.startTime = frameData.isProcessing
? frameData.timestamp
: performance.now()
}

const cancelAnimation = () => animation.cancel()

const safeCancel = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { VisualElementAnimationOptions } from "./types"
import { animateMotionValue } from "./motion-value"
import { isWillChangeMotionValue } from "../../value/use-will-change/is"
import { setTarget } from "../../render/utils/setters"
import { AnimationPlaybackControls } from "../types"
import { AnimationPlaybackControls, Transition } from "../types"

/**
* Decide whether we should block this animation. Previously, we achieved this
Expand Down Expand Up @@ -62,7 +62,11 @@ export function animateTarget(
continue
}

const valueTransition = { delay, elapsed: 0, ...transition }
const valueTransition = {
delay,
elapsed: 0,
...transition,
}

/**
* If this is the first time a value is being animated, check
Expand All @@ -79,6 +83,7 @@ export function animateTarget(
value,
frame
)
;(valueTransition as Transition).syncStart = true
}
}

Expand Down
1 change: 1 addition & 0 deletions packages/framer-motion/src/animation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface Transition
type?: "decay" | "spring" | "keyframes" | "tween" | "inertia"
duration?: number
autoplay?: boolean
syncStart?: boolean
}

export interface ValueAnimationTransition<V = any>
Expand Down

0 comments on commit da1cad3

Please sign in to comment.