react-native-reanimated 2.1.0 → 2.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Common/cpp/SharedItems/MutableValue.cpp +22 -18
- package/Common/cpp/SharedItems/ShareableValue.cpp +1 -1
- package/Common/cpp/Tools/JSIStoreValueUser.cpp +28 -15
- package/Common/cpp/Tools/RuntimeDecorator.cpp +20 -14
- package/Common/cpp/headers/Tools/JSIStoreValueUser.h +8 -3
- package/Common/cpp/headers/Tools/RuntimeDecorator.h +10 -0
- package/README.md +3 -4
- package/RNReanimated.podspec +6 -6
- package/android/build.gradle +78 -2
- package/android/react-native-reanimated-63-hermes.aar +0 -0
- package/android/react-native-reanimated-63-jsc.aar +0 -0
- package/android/react-native-reanimated-64-hermes.aar +0 -0
- package/android/react-native-reanimated-64-jsc.aar +0 -0
- package/android/react-native-reanimated-65-hermes.aar +0 -0
- package/android/react-native-reanimated-65-jsc.aar +0 -0
- package/android/react-native-reanimated-66-hermes.aar +0 -0
- package/android/react-native-reanimated-66-jsc.aar +0 -0
- package/ios/REANodesManager.m +3 -0
- package/ios/native/NativeMethods.mm +2 -2
- package/ios/native/NativeProxy.mm +6 -2
- package/ios/native/REAInitializer.h +32 -0
- package/ios/native/REAInitializer.mm +54 -0
- package/ios/native/UIResponder+Reanimated.mm +8 -48
- package/lib/Animated.js +0 -3
- package/lib/createAnimatedComponent.js +8 -4
- package/lib/index.js +0 -3
- package/lib/reanimated1/animations/decay.js +4 -2
- package/lib/reanimated1/animations/spring.js +4 -3
- package/lib/reanimated1/animations/timing.js +1 -1
- package/lib/reanimated1/core/Core.test.js +30 -0
- package/lib/reanimated2/animations.js +33 -17
- package/lib/reanimated2/core.js +1 -1
- package/lib/reanimated2/jestUtils.js +55 -21
- package/lib/reanimated2/js-reanimated/JSReanimated.js +7 -4
- package/libSo/fbjni/jni/arm64-v8a/libfbjni.so +0 -0
- package/libSo/fbjni/jni/armeabi-v7a/libfbjni.so +0 -0
- package/libSo/fbjni/jni/x86/libfbjni.so +0 -0
- package/libSo/fbjni/jni/x86_64/libfbjni.so +0 -0
- package/mock.js +1 -1
- package/package.json +4 -3
- package/plugin.js +8 -0
- package/react-native-reanimated.d.ts +8 -2
- package/src/Animated.js +0 -3
- package/src/createAnimatedComponent.js +8 -4
- package/src/reanimated1/animations/decay.js +4 -2
- package/src/reanimated1/animations/spring.js +4 -3
- package/src/reanimated1/animations/timing.js +1 -1
- package/src/reanimated1/core/Core.test.js +30 -0
- package/src/reanimated2/animations.ts +48 -22
- package/src/reanimated2/core.ts +1 -1
- package/src/reanimated2/jestUtils.ts +63 -24
- package/src/reanimated2/js-reanimated/JSReanimated.ts +6 -4
- package/android/react-native-reanimated-62.aar +0 -0
- package/android/react-native-reanimated-63.aar +0 -0
- package/android/react-native-reanimated-64.aar +0 -0
- package/android/react-native-reanimated.aar +0 -0
|
@@ -1,21 +1,10 @@
|
|
|
1
1
|
#import "UIResponder+Reanimated.h"
|
|
2
|
-
#import
|
|
3
|
-
#import <RNReanimated/NativeProxy.h>
|
|
4
|
-
#import <RNReanimated/REAModule.h>
|
|
5
|
-
#import <ReactCommon/RCTTurboModuleManager.h>
|
|
6
|
-
#import <React/RCTBridge+Private.h>
|
|
7
|
-
#import <React/RCTCxxBridgeDelegate.h>
|
|
8
|
-
#import <RNReanimated/REAEventDispatcher.h>
|
|
2
|
+
#import "REAInitializer.h"
|
|
9
3
|
|
|
10
|
-
#if
|
|
11
|
-
#import <
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
#if RNVERSION < 63
|
|
15
|
-
#import <ReactCommon/BridgeJSCallInvoker.h>
|
|
16
|
-
#endif
|
|
17
|
-
|
|
18
|
-
#if __has_include(<React/HermesExecutorFactory.h>)
|
|
4
|
+
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
|
|
5
|
+
#import <reacthermes/HermesExecutorFactory.h>
|
|
6
|
+
typedef HermesExecutorFactory ExecutorFactory;
|
|
7
|
+
#elif __has_include(<React/HermesExecutorFactory.h>)
|
|
19
8
|
#import <React/HermesExecutorFactory.h>
|
|
20
9
|
typedef HermesExecutorFactory ExecutorFactory;
|
|
21
10
|
#else
|
|
@@ -25,45 +14,16 @@ typedef JSCExecutorFactory ExecutorFactory;
|
|
|
25
14
|
|
|
26
15
|
#ifndef DONT_AUTOINSTALL_REANIMATED
|
|
27
16
|
|
|
28
|
-
@interface RCTEventDispatcher(Reanimated)
|
|
29
|
-
|
|
30
|
-
- (void)setBridge:(RCTBridge*)bridge;
|
|
31
|
-
|
|
32
|
-
@end
|
|
33
|
-
|
|
34
17
|
@implementation UIResponder (Reanimated)
|
|
35
18
|
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
|
|
36
19
|
{
|
|
37
|
-
|
|
38
|
-
RCTEventDispatcher *eventDispatcher = [REAEventDispatcher new];
|
|
39
|
-
[eventDispatcher setBridge:bridge];
|
|
40
|
-
[bridge updateModuleWithInstance:eventDispatcher];
|
|
41
|
-
_bridge_reanimated = bridge;
|
|
42
|
-
__weak __typeof(self) weakSelf = self;
|
|
43
|
-
|
|
44
|
-
const auto executor = [weakSelf, bridge](facebook::jsi::Runtime &runtime) {
|
|
45
|
-
if (!bridge) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
__typeof(self) strongSelf = weakSelf;
|
|
49
|
-
if (strongSelf) {
|
|
50
|
-
#if RNVERSION >= 63
|
|
51
|
-
auto reanimatedModule = reanimated::createReanimatedModule(bridge.jsCallInvoker);
|
|
52
|
-
#else
|
|
53
|
-
auto callInvoker = std::make_shared<react::BridgeJSCallInvoker>(bridge.reactInstance);
|
|
54
|
-
auto reanimatedModule = reanimated::createReanimatedModule(callInvoker);
|
|
55
|
-
#endif
|
|
56
|
-
runtime.global().setProperty(runtime,
|
|
57
|
-
jsi::PropNameID::forAscii(runtime, "__reanimatedModuleProxy"),
|
|
58
|
-
jsi::Object::createFromHostObject(runtime, reanimatedModule));
|
|
59
|
-
}
|
|
60
|
-
};
|
|
20
|
+
const auto installer = reanimated::REAJSIExecutorRuntimeInstaller(bridge, NULL);
|
|
61
21
|
|
|
62
22
|
#if RNVERSION >= 64
|
|
63
23
|
// installs globals such as console, nativePerformanceNow, etc.
|
|
64
|
-
return std::make_unique<ExecutorFactory>(RCTJSIExecutorRuntimeInstaller(
|
|
24
|
+
return std::make_unique<ExecutorFactory>(RCTJSIExecutorRuntimeInstaller(installer));
|
|
65
25
|
#else
|
|
66
|
-
return std::make_unique<ExecutorFactory>(
|
|
26
|
+
return std::make_unique<ExecutorFactory>(installer);
|
|
67
27
|
#endif
|
|
68
28
|
}
|
|
69
29
|
|
package/lib/Animated.js
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
addWhitelistedNativeProps,
|
|
5
5
|
addWhitelistedUIProps,
|
|
6
6
|
} from './ConfigHelper';
|
|
7
|
-
import * as reanimated2 from './reanimated2';
|
|
8
7
|
import * as reanimated1 from './reanimated1';
|
|
9
8
|
|
|
10
9
|
const Animated = {
|
|
@@ -19,8 +18,6 @@ const Animated = {
|
|
|
19
18
|
addWhitelistedUIProps,
|
|
20
19
|
// reanimated 1
|
|
21
20
|
...reanimated1,
|
|
22
|
-
// reanimated 2
|
|
23
|
-
...reanimated2,
|
|
24
21
|
};
|
|
25
22
|
|
|
26
23
|
export * from './reanimated2';
|
|
@@ -57,7 +57,7 @@ function flattenArray(array) {
|
|
|
57
57
|
return resultArr;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export default function createAnimatedComponent(Component) {
|
|
60
|
+
export default function createAnimatedComponent(Component, options = {}) {
|
|
61
61
|
invariant(
|
|
62
62
|
typeof Component !== 'function' ||
|
|
63
63
|
(Component.prototype && Component.prototype.isReactComponent),
|
|
@@ -104,7 +104,7 @@ export default function createAnimatedComponent(Component) {
|
|
|
104
104
|
|
|
105
105
|
_attachNativeEvents() {
|
|
106
106
|
const node = this._getEventViewRef();
|
|
107
|
-
const viewTag = findNodeHandle(node);
|
|
107
|
+
const viewTag = findNodeHandle(options.setNativeProps ? this : node);
|
|
108
108
|
|
|
109
109
|
for (const key in this.props) {
|
|
110
110
|
const prop = this.props[key];
|
|
@@ -232,8 +232,12 @@ export default function createAnimatedComponent(Component) {
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
_updateFromNative(props) {
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
if (options.setNativeProps) {
|
|
236
|
+
options.setNativeProps(this._component, props);
|
|
237
|
+
} else {
|
|
238
|
+
// eslint-disable-next-line no-unused-expressions
|
|
239
|
+
this._component.setNativeProps?.(props);
|
|
240
|
+
}
|
|
237
241
|
}
|
|
238
242
|
|
|
239
243
|
_attachPropUpdater() {
|
package/lib/index.js
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
addWhitelistedNativeProps,
|
|
5
5
|
addWhitelistedUIProps,
|
|
6
6
|
} from './ConfigHelper';
|
|
7
|
-
import * as reanimated2 from './reanimated2';
|
|
8
7
|
import * as reanimated1 from './reanimated1';
|
|
9
8
|
|
|
10
9
|
const Animated = {
|
|
@@ -19,8 +18,6 @@ const Animated = {
|
|
|
19
18
|
addWhitelistedUIProps,
|
|
20
19
|
// reanimated 1
|
|
21
20
|
...reanimated1,
|
|
22
|
-
// reanimated 2
|
|
23
|
-
...reanimated2,
|
|
24
21
|
};
|
|
25
22
|
|
|
26
23
|
export * from './reanimated2';
|
|
@@ -45,8 +45,10 @@ const procDecay = proc(
|
|
|
45
45
|
decay(clock, { time, velocity, position, finished }, { deceleration })
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
export default (
|
|
48
|
+
export default function decayAnimation(
|
|
49
49
|
clock,
|
|
50
50
|
{ time, velocity, position, finished },
|
|
51
51
|
{ deceleration }
|
|
52
|
-
)
|
|
52
|
+
) {
|
|
53
|
+
return procDecay(clock, time, velocity, position, finished, deceleration);
|
|
54
|
+
}
|
|
@@ -167,7 +167,7 @@ const procSpring = proc(
|
|
|
167
167
|
)
|
|
168
168
|
);
|
|
169
169
|
|
|
170
|
-
export default (
|
|
170
|
+
export default function springAnimation(
|
|
171
171
|
clock,
|
|
172
172
|
{ finished, velocity, position, time, prevPosition },
|
|
173
173
|
{
|
|
@@ -179,8 +179,8 @@ export default (
|
|
|
179
179
|
restDisplacementThreshold,
|
|
180
180
|
restSpeedThreshold,
|
|
181
181
|
}
|
|
182
|
-
)
|
|
183
|
-
procSpring(
|
|
182
|
+
) {
|
|
183
|
+
return procSpring(
|
|
184
184
|
finished,
|
|
185
185
|
velocity,
|
|
186
186
|
position,
|
|
@@ -195,3 +195,4 @@ export default (
|
|
|
195
195
|
restDisplacementThreshold,
|
|
196
196
|
clock
|
|
197
197
|
);
|
|
198
|
+
}
|
|
@@ -50,7 +50,7 @@ const internalTiming = proc(function (
|
|
|
50
50
|
]);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
export default function (clock, state, config) {
|
|
53
|
+
export default function timing(clock, state, config) {
|
|
54
54
|
if (config.duration === 0) {
|
|
55
55
|
// when duration is zero we end the timing immediately
|
|
56
56
|
return block([set(state.position, config.toValue), set(state.finished, 1)]);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Animated from '../../Animated';
|
|
3
|
+
|
|
4
|
+
import renderer from 'react-test-renderer';
|
|
5
|
+
|
|
6
|
+
jest.mock('../../ReanimatedEventEmitter');
|
|
7
|
+
jest.mock('../../ReanimatedModule');
|
|
8
|
+
jest.mock('../../reanimated2/NativeReanimated');
|
|
9
|
+
|
|
10
|
+
describe('Core Animated components', () => {
|
|
11
|
+
xit('fails if something other then a node or function that returns a node is passed to Animated.Code exec prop', () => {
|
|
12
|
+
console.error = jest.fn();
|
|
13
|
+
|
|
14
|
+
expect(() =>
|
|
15
|
+
renderer.create(<Animated.Code exec="not a node" />)
|
|
16
|
+
).toThrowError(
|
|
17
|
+
"<Animated.Code /> expects the 'exec' prop or children to be an animated node or a function returning an animated node."
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
xit('fails if something other then a node or function that returns a node is passed to Animated.Code children', () => {
|
|
22
|
+
console.error = jest.fn();
|
|
23
|
+
|
|
24
|
+
expect(() =>
|
|
25
|
+
renderer.create(<Animated.Code>not a node</Animated.Code>)
|
|
26
|
+
).toThrowError(
|
|
27
|
+
"<Animated.Code /> expects the 'exec' prop or children to be an animated node or a function returning an animated node."
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { Easing } from './Easing';
|
|
5
5
|
import { isColor, convertToHSVA, toRGBA } from './Colors';
|
|
6
6
|
import NativeReanimated from './NativeReanimated';
|
|
7
|
+
import { Platform } from 'react-native';
|
|
7
8
|
let IN_STYLE_UPDATER = false;
|
|
8
9
|
export function initialUpdaterRun(updater) {
|
|
9
10
|
IN_STYLE_UPDATER = true;
|
|
@@ -293,43 +294,58 @@ export function withDecay(userConfig, callback) {
|
|
|
293
294
|
'worklet';
|
|
294
295
|
const config = {
|
|
295
296
|
deceleration: 0.998,
|
|
297
|
+
velocityFactor: Platform.OS !== 'web' ? 1 : 1000,
|
|
296
298
|
};
|
|
297
299
|
if (userConfig) {
|
|
298
300
|
Object.keys(userConfig).forEach((key) => (config[key] = userConfig[key]));
|
|
299
301
|
}
|
|
300
|
-
const VELOCITY_EPS =
|
|
302
|
+
const VELOCITY_EPS = Platform.OS !== 'web' ? 1 : 1 / 20;
|
|
303
|
+
const SLOPE_FACTOR = 0.1;
|
|
301
304
|
function decay(animation, now) {
|
|
302
|
-
const { lastTimestamp, initialVelocity, current, velocity } = animation;
|
|
305
|
+
const { lastTimestamp, startTimestamp, initialVelocity, current, velocity, } = animation;
|
|
303
306
|
const deltaTime = Math.min(now - lastTimestamp, 64);
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const v = v0 * kv * 1000;
|
|
309
|
-
const x = current + v0 * kx;
|
|
310
|
-
animation.current = x;
|
|
307
|
+
const v = velocity *
|
|
308
|
+
Math.exp(-(1 - config.deceleration) * (now - startTimestamp) * SLOPE_FACTOR);
|
|
309
|
+
animation.current =
|
|
310
|
+
current + (v * config.velocityFactor * deltaTime) / 1000; // /1000 because time is in ms not in s
|
|
311
311
|
animation.velocity = v;
|
|
312
|
-
|
|
313
|
-
if (
|
|
312
|
+
animation.lastTimestamp = now;
|
|
313
|
+
if (config.clamp) {
|
|
314
314
|
if (initialVelocity < 0 && animation.current <= config.clamp[0]) {
|
|
315
|
-
|
|
315
|
+
animation.current = config.clamp[0];
|
|
316
|
+
return true;
|
|
316
317
|
}
|
|
317
318
|
else if (initialVelocity > 0 &&
|
|
318
319
|
animation.current >= config.clamp[1]) {
|
|
319
|
-
|
|
320
|
+
animation.current = config.clamp[1];
|
|
321
|
+
return true;
|
|
320
322
|
}
|
|
321
323
|
}
|
|
322
|
-
if (Math.abs(v) < VELOCITY_EPS
|
|
323
|
-
if (toValueIsReached !== null) {
|
|
324
|
-
animation.current = toValueIsReached;
|
|
325
|
-
}
|
|
324
|
+
if (Math.abs(v) < VELOCITY_EPS) {
|
|
326
325
|
return true;
|
|
327
326
|
}
|
|
328
327
|
}
|
|
328
|
+
function validateConfig() {
|
|
329
|
+
if (config.clamp) {
|
|
330
|
+
if (Array.isArray(config.clamp)) {
|
|
331
|
+
if (config.clamp.length !== 2) {
|
|
332
|
+
console.error(`clamp array must contain 2 items but is given ${config.clamp.length}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
console.error(`config.clamp must be an array but is ${typeof config.clamp}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
if (config.velocityFactor <= 0) {
|
|
340
|
+
console.error(`config.velocityFactor must be greather then 0 but is ${config.velocityFactor}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
329
343
|
function onStart(animation, value, now) {
|
|
330
344
|
animation.current = value;
|
|
331
345
|
animation.lastTimestamp = now;
|
|
346
|
+
animation.startTimestamp = now;
|
|
332
347
|
animation.initialVelocity = config.velocity;
|
|
348
|
+
validateConfig();
|
|
333
349
|
}
|
|
334
350
|
return {
|
|
335
351
|
onFrame: decay,
|
package/lib/reanimated2/core.js
CHANGED
|
@@ -30,7 +30,7 @@ export const isConfigured = (throwError = false) => {
|
|
|
30
30
|
};
|
|
31
31
|
export const isConfiguredCheck = () => {
|
|
32
32
|
if (!isConfigured(true)) {
|
|
33
|
-
throw new Error('If you want to use Reanimated 2 then go through our installation steps https://docs.swmansion.com/react-native-reanimated/docs/installation');
|
|
33
|
+
throw new Error('If you want to use Reanimated 2 then go through our installation steps https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation');
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
function _toArrayReanimated(object) {
|
|
@@ -4,29 +4,62 @@ const MockDate = require('mockdate');
|
|
|
4
4
|
let config = {
|
|
5
5
|
fps: 60,
|
|
6
6
|
};
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
const isAnimatedStyle = (style) => {
|
|
8
|
+
return !!style.animatedStyle;
|
|
9
|
+
};
|
|
10
|
+
const getAnimatedStyleFromObject = (style) => {
|
|
11
|
+
return style.animatedStyle.current.value;
|
|
12
|
+
};
|
|
13
|
+
const getCurrentStyle = (received) => {
|
|
14
|
+
const styleObject = received.props.style;
|
|
15
|
+
let currentStyle = {};
|
|
16
|
+
if (Array.isArray(styleObject)) {
|
|
17
|
+
received.props.style.forEach((style) => {
|
|
18
|
+
if (isAnimatedStyle(style)) {
|
|
19
|
+
currentStyle = Object.assign(Object.assign({}, currentStyle), getAnimatedStyleFromObject(style));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
currentStyle = Object.assign(Object.assign({}, currentStyle), style);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
14
25
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
26
|
+
else {
|
|
27
|
+
if (isAnimatedStyle(styleObject)) {
|
|
28
|
+
currentStyle = getAnimatedStyleFromObject(styleObject);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
currentStyle = Object.assign(Object.assign({}, styleObject), received.props.animatedStyle.value);
|
|
32
|
+
}
|
|
18
33
|
}
|
|
19
|
-
|
|
20
|
-
return { isValid, message };
|
|
34
|
+
return currentStyle;
|
|
21
35
|
};
|
|
22
|
-
const
|
|
23
|
-
|
|
36
|
+
const checkEqual = (currentStyle, expectStyle) => {
|
|
37
|
+
if (Array.isArray(expectStyle)) {
|
|
38
|
+
if (expectStyle.length !== currentStyle.length)
|
|
39
|
+
return false;
|
|
40
|
+
for (let i = 0; i < currentStyle.length; i++) {
|
|
41
|
+
if (!checkEqual(currentStyle[i], expectStyle[i])) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (typeof currentStyle === 'object' && currentStyle) {
|
|
47
|
+
for (const property in expectStyle) {
|
|
48
|
+
if (!checkEqual(currentStyle[property], expectStyle[property])) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return currentStyle === expectStyle;
|
|
55
|
+
}
|
|
56
|
+
return true;
|
|
24
57
|
};
|
|
25
58
|
const findStyleDiff = (current, expect, requireAllMatch) => {
|
|
26
59
|
const diffs = [];
|
|
27
60
|
let isEqual = true;
|
|
28
61
|
for (const property in expect) {
|
|
29
|
-
if (current[property]
|
|
62
|
+
if (!checkEqual(current[property], expect[property])) {
|
|
30
63
|
isEqual = false;
|
|
31
64
|
diffs.push({
|
|
32
65
|
property: property,
|
|
@@ -51,8 +84,7 @@ const findStyleDiff = (current, expect, requireAllMatch) => {
|
|
|
51
84
|
return { isEqual, diffs };
|
|
52
85
|
};
|
|
53
86
|
const compareStyle = (received, expectedStyle, config) => {
|
|
54
|
-
|
|
55
|
-
if (!isValid) {
|
|
87
|
+
if (!received.props.style) {
|
|
56
88
|
return { message: () => message, pass: false };
|
|
57
89
|
}
|
|
58
90
|
const { exact } = config;
|
|
@@ -64,7 +96,7 @@ const compareStyle = (received, expectedStyle, config) => {
|
|
|
64
96
|
const currentStyleStr = JSON.stringify(currentStyle);
|
|
65
97
|
const expectedStyleStr = JSON.stringify(expectedStyle);
|
|
66
98
|
const differences = diffs
|
|
67
|
-
.map((diff) => `- '${diff.property}' should be ${diff.expect}, but is ${diff.current}`)
|
|
99
|
+
.map((diff) => `- '${diff.property}' should be ${JSON.stringify(diff.expect)}, but is ${JSON.stringify(diff.current)}`)
|
|
68
100
|
.join('\n');
|
|
69
101
|
return {
|
|
70
102
|
message: () => `Expected: ${expectedStyleStr}\nReceived: ${currentStyleStr}\n\nDifferences:\n${differences}`,
|
|
@@ -97,18 +129,20 @@ export const withReanimatedTimer = (animatonTest) => {
|
|
|
97
129
|
afterTest();
|
|
98
130
|
};
|
|
99
131
|
export const advanceAnimationByTime = (time = frameTime) => {
|
|
100
|
-
for (let i = 0; i
|
|
132
|
+
for (let i = 0; i <= Math.ceil(time / frameTime); i++) {
|
|
101
133
|
tickTravel();
|
|
102
134
|
}
|
|
135
|
+
jest.advanceTimersByTime(frameTime);
|
|
103
136
|
};
|
|
104
137
|
export const advanceAnimationByFrame = (count) => {
|
|
105
|
-
for (let i = 0; i
|
|
138
|
+
for (let i = 0; i <= count; i++) {
|
|
106
139
|
tickTravel();
|
|
107
140
|
}
|
|
141
|
+
jest.advanceTimersByTime(frameTime);
|
|
108
142
|
};
|
|
109
143
|
export const setUpTests = (userConfig = {}) => {
|
|
110
144
|
const expect = require('expect');
|
|
111
|
-
frameTime = 1000 / config.fps;
|
|
145
|
+
frameTime = Math.round(1000 / config.fps);
|
|
112
146
|
config = Object.assign(Object.assign({}, config), userConfig);
|
|
113
147
|
expect.extend({
|
|
114
148
|
toHaveAnimatedStyle(received, expectedStyle, config = {}) {
|
|
@@ -10,10 +10,13 @@ export default class JSReanimated {
|
|
|
10
10
|
this._renderRequested = false;
|
|
11
11
|
this._mapperRegistry = new MapperRegistry(this);
|
|
12
12
|
this._frames = [];
|
|
13
|
-
this.timeProvider =
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
this.timeProvider = {};
|
|
14
|
+
if (process.env.JEST_WORKER_ID) {
|
|
15
|
+
this.timeProvider.now = () => Date.now();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
this.timeProvider.now = () => window.performance.now();
|
|
19
|
+
}
|
|
17
20
|
}
|
|
18
21
|
pushFrame(frame) {
|
|
19
22
|
this._frames.push(frame);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/mock.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-reanimated",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.3",
|
|
4
4
|
"description": "More powerful alternative to Animated library for React Native.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "node node_modules/react-native/local-cli/cli.js start",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"Common/",
|
|
25
25
|
"src/",
|
|
26
26
|
"lib/",
|
|
27
|
+
"libSo/",
|
|
27
28
|
"android/src/main/AndroidManifest.xml",
|
|
28
29
|
"android/src/main/java/",
|
|
29
30
|
"android/build.gradle",
|
|
@@ -80,7 +81,7 @@
|
|
|
80
81
|
"@types/babel__generator": "^7.6.2",
|
|
81
82
|
"@types/babel__traverse": "^7.0.15",
|
|
82
83
|
"@types/jest": "^26.0.15",
|
|
83
|
-
"@types/react-native": "^0.
|
|
84
|
+
"@types/react-native": "^0.65.5",
|
|
84
85
|
"@typescript-eslint/eslint-plugin": "^4.15.1",
|
|
85
86
|
"@typescript-eslint/parser": "^4.15.1",
|
|
86
87
|
"babel-eslint": "^10.0.3",
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
"lint-staged": "^10.2.11",
|
|
100
101
|
"prettier": "^2.2.1",
|
|
101
102
|
"react": "17.0.1",
|
|
102
|
-
"react-native": "
|
|
103
|
+
"react-native": "0.66.0",
|
|
103
104
|
"react-native-gesture-handler": "^1.6.1",
|
|
104
105
|
"react-test-renderer": "17.0.1",
|
|
105
106
|
"release-it": "^13.1.1",
|
package/plugin.js
CHANGED
|
@@ -554,6 +554,14 @@ function removePluginsFromBlacklist(plugins) {
|
|
|
554
554
|
|
|
555
555
|
module.exports = function({ types: t }) {
|
|
556
556
|
return {
|
|
557
|
+
pre() {
|
|
558
|
+
// allows adding custom globals such as host-functions
|
|
559
|
+
if (this.opts != null && Array.isArray(this.opts.globals)) {
|
|
560
|
+
this.opts.globals.forEach((name) => {
|
|
561
|
+
globals.add(name)
|
|
562
|
+
})
|
|
563
|
+
}
|
|
564
|
+
},
|
|
557
565
|
visitor: {
|
|
558
566
|
CallExpression: {
|
|
559
567
|
exit(path, state) {
|
|
@@ -119,6 +119,7 @@ declare module 'react-native-reanimated' {
|
|
|
119
119
|
deceleration?: number;
|
|
120
120
|
velocity?: number;
|
|
121
121
|
clamp?: [number, number];
|
|
122
|
+
velocityFactor?: number;
|
|
122
123
|
}
|
|
123
124
|
export interface BackwardCompatibleWrapper {
|
|
124
125
|
start: (callback?: (data: { finished: boolean }) => any) => void;
|
|
@@ -246,11 +247,16 @@ declare module 'react-native-reanimated' {
|
|
|
246
247
|
}
|
|
247
248
|
export class Code extends Component<CodeProps> {}
|
|
248
249
|
|
|
250
|
+
type Options<P> = {
|
|
251
|
+
setNativeProps: (ref: any, props: P) => void;
|
|
252
|
+
}
|
|
249
253
|
export function createAnimatedComponent<P extends object>(
|
|
250
|
-
component: ComponentClass<P
|
|
254
|
+
component: ComponentClass<P>,
|
|
255
|
+
options?: Options<P>
|
|
251
256
|
): ComponentClass<AnimateProps<P>>;
|
|
252
257
|
export function createAnimatedComponent<P extends object>(
|
|
253
|
-
component: FunctionComponent<P
|
|
258
|
+
component: FunctionComponent<P>,
|
|
259
|
+
options?: Options<P>
|
|
254
260
|
): FunctionComponent<AnimateProps<P>>;
|
|
255
261
|
|
|
256
262
|
// classes
|
package/src/Animated.js
CHANGED
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
addWhitelistedNativeProps,
|
|
5
5
|
addWhitelistedUIProps,
|
|
6
6
|
} from './ConfigHelper';
|
|
7
|
-
import * as reanimated2 from './reanimated2';
|
|
8
7
|
import * as reanimated1 from './reanimated1';
|
|
9
8
|
|
|
10
9
|
const Animated = {
|
|
@@ -19,8 +18,6 @@ const Animated = {
|
|
|
19
18
|
addWhitelistedUIProps,
|
|
20
19
|
// reanimated 1
|
|
21
20
|
...reanimated1,
|
|
22
|
-
// reanimated 2
|
|
23
|
-
...reanimated2,
|
|
24
21
|
};
|
|
25
22
|
|
|
26
23
|
export * from './reanimated2';
|
|
@@ -57,7 +57,7 @@ function flattenArray(array) {
|
|
|
57
57
|
return resultArr;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
export default function createAnimatedComponent(Component) {
|
|
60
|
+
export default function createAnimatedComponent(Component, options = {}) {
|
|
61
61
|
invariant(
|
|
62
62
|
typeof Component !== 'function' ||
|
|
63
63
|
(Component.prototype && Component.prototype.isReactComponent),
|
|
@@ -104,7 +104,7 @@ export default function createAnimatedComponent(Component) {
|
|
|
104
104
|
|
|
105
105
|
_attachNativeEvents() {
|
|
106
106
|
const node = this._getEventViewRef();
|
|
107
|
-
const viewTag = findNodeHandle(node);
|
|
107
|
+
const viewTag = findNodeHandle(options.setNativeProps ? this : node);
|
|
108
108
|
|
|
109
109
|
for (const key in this.props) {
|
|
110
110
|
const prop = this.props[key];
|
|
@@ -232,8 +232,12 @@ export default function createAnimatedComponent(Component) {
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
_updateFromNative(props) {
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
if (options.setNativeProps) {
|
|
236
|
+
options.setNativeProps(this._component, props);
|
|
237
|
+
} else {
|
|
238
|
+
// eslint-disable-next-line no-unused-expressions
|
|
239
|
+
this._component.setNativeProps?.(props);
|
|
240
|
+
}
|
|
237
241
|
}
|
|
238
242
|
|
|
239
243
|
_attachPropUpdater() {
|
|
@@ -45,8 +45,10 @@ const procDecay = proc(
|
|
|
45
45
|
decay(clock, { time, velocity, position, finished }, { deceleration })
|
|
46
46
|
);
|
|
47
47
|
|
|
48
|
-
export default (
|
|
48
|
+
export default function decayAnimation(
|
|
49
49
|
clock,
|
|
50
50
|
{ time, velocity, position, finished },
|
|
51
51
|
{ deceleration }
|
|
52
|
-
)
|
|
52
|
+
) {
|
|
53
|
+
return procDecay(clock, time, velocity, position, finished, deceleration);
|
|
54
|
+
}
|
|
@@ -167,7 +167,7 @@ const procSpring = proc(
|
|
|
167
167
|
)
|
|
168
168
|
);
|
|
169
169
|
|
|
170
|
-
export default (
|
|
170
|
+
export default function springAnimation(
|
|
171
171
|
clock,
|
|
172
172
|
{ finished, velocity, position, time, prevPosition },
|
|
173
173
|
{
|
|
@@ -179,8 +179,8 @@ export default (
|
|
|
179
179
|
restDisplacementThreshold,
|
|
180
180
|
restSpeedThreshold,
|
|
181
181
|
}
|
|
182
|
-
)
|
|
183
|
-
procSpring(
|
|
182
|
+
) {
|
|
183
|
+
return procSpring(
|
|
184
184
|
finished,
|
|
185
185
|
velocity,
|
|
186
186
|
position,
|
|
@@ -195,3 +195,4 @@ export default (
|
|
|
195
195
|
restDisplacementThreshold,
|
|
196
196
|
clock
|
|
197
197
|
);
|
|
198
|
+
}
|
|
@@ -50,7 +50,7 @@ const internalTiming = proc(function (
|
|
|
50
50
|
]);
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
export default function (clock, state, config) {
|
|
53
|
+
export default function timing(clock, state, config) {
|
|
54
54
|
if (config.duration === 0) {
|
|
55
55
|
// when duration is zero we end the timing immediately
|
|
56
56
|
return block([set(state.position, config.toValue), set(state.finished, 1)]);
|