From d0bd19540ded28cb747a49bf6689dfdfde18d6e0 Mon Sep 17 00:00:00 2001 From: Matt Perry Date: Mon, 4 Sep 2023 12:32:05 +0200 Subject: [PATCH] Manually resolving startTime --- dev/optimized-appear/resync.html | 15 ++++++++------- .../waapi/create-accelerated-animation.ts | 14 +++++++++++++- .../animation/interfaces/visual-element-target.ts | 10 ++++++++-- packages/framer-motion/src/animation/types.ts | 1 + 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/dev/optimized-appear/resync.html b/dev/optimized-appear/resync.html index b2902b08e8..ad0dfb366a 100644 --- a/dev/optimized-appear/resync.html +++ b/dev/optimized-appear/resync.html @@ -68,15 +68,16 @@ */ onAnimationStart: () => { frame.postRender(() => { - const box = document.getElementById("box") + frame.postRender(() => { + const box = document.getElementById("box") - if (!box) return + if (!box) return - const { opacity } = window.getComputedStyle(box) - - if (parseFloat(opacity) < 0.7) { - showError(box, "Resync failed") - } + const { opacity } = window.getComputedStyle(box) + if (parseFloat(opacity) < 0.65) { + showError(box, "Resync failed") + } + }) }) }, [optimizedAppearDataAttribute]: "a", diff --git a/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts b/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts index 7f39304b51..e8c923acb9 100644 --- a/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts +++ b/packages/framer-motion/src/animation/animators/waapi/create-accelerated-animation.ts @@ -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" @@ -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 = () => { diff --git a/packages/framer-motion/src/animation/interfaces/visual-element-target.ts b/packages/framer-motion/src/animation/interfaces/visual-element-target.ts index dfcaec86cf..7f27fc44bd 100644 --- a/packages/framer-motion/src/animation/interfaces/visual-element-target.ts +++ b/packages/framer-motion/src/animation/interfaces/visual-element-target.ts @@ -2,7 +2,7 @@ import { frame } from "../../frameloop" import { transformProps } from "../../render/html/utils/transform" import type { AnimationTypeState } from "../../render/utils/animation-state" import type { VisualElement } from "../../render/VisualElement" -import type { TargetAndTransition } from "../../types" +import type { TargetAndTransition, Transition } from "../../types" import { optimizedAppearDataAttribute } from "../optimized-appear/data-id" import type { VisualElementAnimationOptions } from "./types" import { animateMotionValue } from "./motion-value" @@ -62,7 +62,12 @@ export function animateTarget( continue } - const valueTransition = { delay, elapsed: 0, ...transition } + const valueTransition = { + delay, + syncStart: false, + elapsed: 0, + ...transition, + } /** * If this is the first time a value is being animated, check @@ -79,6 +84,7 @@ export function animateTarget( value, frame ) + valueTransition.syncStart = true } } diff --git a/packages/framer-motion/src/animation/types.ts b/packages/framer-motion/src/animation/types.ts index 8ad1026ac9..79878f674c 100644 --- a/packages/framer-motion/src/animation/types.ts +++ b/packages/framer-motion/src/animation/types.ts @@ -25,6 +25,7 @@ export interface Transition type?: "decay" | "spring" | "keyframes" | "tween" | "inertia" duration?: number autoplay?: boolean + syncStart?: boolean } export interface ValueAnimationTransition