-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: move requestAnimationFrame back to Reanimated (#6991)
## Summary I introduced a regression in #6973 by moving JS implementation of `requestAnimationFrame` to Worklets. Native version of `requestAnimationFrame` is injected in Reanimated's `UIRuntimeDecorator.cpp` so `requestAnimationFrame` must be overwritten in Reanimated, not in Worklets. Since all the native implementation is in Reanimated and it would be a hard task to extract it right now, I decided to keep it for the time being unless we decide where it should land eventually. ## Test plan The only difference is the lack of batching with my regression introduced. You can `console.log(currentCallbacks.length)` to see that the batching is restored.
- Loading branch information
Showing
4 changed files
with
51 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
packages/react-native-reanimated/src/requestAnimationFrame.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
'use strict'; | ||
|
||
import { callMicrotasks } from './WorkletsResolver'; | ||
|
||
export function setupRequestAnimationFrame() { | ||
'worklet'; | ||
|
||
// Jest mocks requestAnimationFrame API and it does not like if that mock gets overridden | ||
// so we avoid doing requestAnimationFrame batching in Jest environment. | ||
const nativeRequestAnimationFrame = global.requestAnimationFrame; | ||
|
||
let animationFrameCallbacks: Array<(timestamp: number) => void> = []; | ||
let flushRequested = false; | ||
|
||
global.__flushAnimationFrame = (frameTimestamp: number) => { | ||
const currentCallbacks = animationFrameCallbacks; | ||
animationFrameCallbacks = []; | ||
currentCallbacks.forEach((f) => f(frameTimestamp)); | ||
callMicrotasks(); | ||
}; | ||
|
||
global.requestAnimationFrame = ( | ||
callback: (timestamp: number) => void | ||
): number => { | ||
animationFrameCallbacks.push(callback); | ||
if (!flushRequested) { | ||
flushRequested = true; | ||
nativeRequestAnimationFrame((timestamp) => { | ||
flushRequested = false; | ||
global.__frameTimestamp = timestamp; | ||
global.__flushAnimationFrame(timestamp); | ||
global.__frameTimestamp = undefined; | ||
}); | ||
} | ||
// Reanimated currently does not support cancelling callbacks requested with | ||
// requestAnimationFrame. We return -1 as identifier which isn't in line | ||
// with the spec but it should give users better clue in case they actually | ||
// attempt to store the value returned from rAF and use it for cancelling. | ||
return -1; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters