@react-native-ohos/react-native-reanimated 4.0.2 → 4.0.3-beta.1
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/CHANGELOG.md +1085 -0
- package/README.md +470 -0
- package/harmony/reanimated/BuildProfile.ets +1 -1
- package/harmony/reanimated/oh-package.json5 +1 -1
- package/harmony/reanimated/src/main/cpp/ReanimatedModule.cpp +4 -3
- package/harmony/reanimated/src/main/cpp/ReanimatedSensor.cpp +45 -48
- package/harmony/reanimated/src/main/cpp/ReanimatedSensor.h +12 -0
- package/harmony/reanimated/src/main/ets/ReanimatedModule.ts +100 -16
- package/harmony/reanimated.har +0 -0
- package/package.json +12 -4
package/README.md
ADDED
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
> 文档模板:v0.4.2
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<h1 align="center"> <code>react-native-reanimated</code> </h1>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
本项目基于 [react-native-reanimated](https://github.com/software-mansion/react-native-reanimated) 开发。
|
|
8
|
+
|
|
9
|
+
该第三方库的仓库已迁移至 Gitcode,且支持直接从 npm 下载,新的包名为:`@react-native-ohos/react-native-reanimated` 版本所属关系如下:
|
|
10
|
+
|
|
11
|
+
| 三方库名称 | 三方库版本(npm地址) | 发布信息 | 支持RN版本 | Autolink | 编译API版本 | 社区基线版本 | 源码地址 |
|
|
12
|
+
| ------------ | ------------ | ------------------------------ | ------------- | ------------- |------------------------ | ------------- | ------------- |
|
|
13
|
+
| @react-native-ohos/react-native-reanimated | [~ 4.0.0](https://www.npmjs.com/package/@react-native-ohos/react-native-reanimated) | [Gitcode Releases](https://gitcode.com/openharmony-sig/rntpc_react-native-reanimated/releases) | 0.82.* | 否 | API12+ | 4.2.1 | [br_rnoh0.82](https://gitcode.com/CPF-RN/rntpc_react-native-reanimated/tree/br_rnoh0.82) |
|
|
14
|
+
|
|
15
|
+
## 简介
|
|
16
|
+
|
|
17
|
+
react-native-reanimated 是面向 React Native 生态的第三方原生库,重构实现跨平台动画底层能力,提供声明式 JS 动画 API,实现运行在 UI 线程的高性能流畅动画交互。
|
|
18
|
+
|
|
19
|
+
## 下载安装
|
|
20
|
+
|
|
21
|
+
> [!TIP] 注意:
|
|
22
|
+
`react-native-worklets` 已单独独立成库,需要单独引入,参照[@react-native-ohos/react-native-worklets文档](https://gitcode.com/OpenHarmony-RN/usage-docs/blob/master/zh-cn/react-native-worklets.md),目前只支持 Hermes,不支持切换至其他 JS 引擎切换。
|
|
23
|
+
|
|
24
|
+
进入到工程目录并输入以下命令:
|
|
25
|
+
|
|
26
|
+
**npm**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install react-native-reanimated@4.2.1
|
|
30
|
+
npm install @react-native-ohos/react-native-reanimated
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**yarn**
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yarn add react-native-reanimated@4.2.1
|
|
37
|
+
yarn add @react-native-ohos/react-native-reanimated
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### 插件配置
|
|
41
|
+
|
|
42
|
+
添加插件到 `babel.config.js`:
|
|
43
|
+
|
|
44
|
+
> [!TIP] 为什么需要添加这个?Reanimated Babel 插件会自动转换特殊的 JavaScript 函数(称为 worklet),以便它们可以被传递并在 UI 线程上运行。
|
|
45
|
+
|
|
46
|
+
```js
|
|
47
|
+
module.exports = {
|
|
48
|
+
presets: [
|
|
49
|
+
... // don't add it here :)
|
|
50
|
+
],
|
|
51
|
+
plugins: [
|
|
52
|
+
...
|
|
53
|
+
'react-native-worklets/plugin',
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
清除 Metro 的缓存(推荐):
|
|
59
|
+
|
|
60
|
+
**npm**
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm start --reset-cache
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**yarn**
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
yarn start --reset-cache
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Link
|
|
73
|
+
|
|
74
|
+
| | 是否支持autolink | RN框架版本 |
|
|
75
|
+
|--------------------------------------|----------------|-----------|
|
|
76
|
+
| ~ 4.0.0 | No | 0.82 |
|
|
77
|
+
|
|
78
|
+
首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 `harmony`。
|
|
79
|
+
|
|
80
|
+
### 1. Overrides RN SDK
|
|
81
|
+
|
|
82
|
+
为了让工程依赖同一个版本的 RN SDK,需要在工程根目录的 `oh-package.json5` 添加 overrides 字段,指向工程需要使用的 RN SDK 版本。替换的版本既可以是一个具体的版本号,也可以是一个模糊版本,还可以是本地存在的 HAR 包或源码目录。
|
|
83
|
+
|
|
84
|
+
关于该字段的作用请阅读[官方说明](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/ide-oh-package-json5-V5#zh-cn_topic_0000001792256137_overrides)
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
...
|
|
89
|
+
"overrides": {
|
|
90
|
+
"@rnoh/react-native-openharmony" : "./react_native_openharmony",
|
|
91
|
+
"@react-native-ohos/react-native-worklets": "file:../node_modules/@react-native-ohos/react-native-worklets/harmony/worklets.har"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2. 引入原生端代码
|
|
97
|
+
|
|
98
|
+
目前有两种方法:
|
|
99
|
+
|
|
100
|
+
- 通过 har 包引入;
|
|
101
|
+
- 直接链接源码。
|
|
102
|
+
|
|
103
|
+
方法一:通过 har 包引入(推荐)
|
|
104
|
+
|
|
105
|
+
> [!TIP] har 包位于三方库安装路径的 `harmony` 文件夹下。
|
|
106
|
+
|
|
107
|
+
打开 `entry/oh-package.json5`,添加以下依赖
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
"dependencies": {
|
|
111
|
+
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
|
|
112
|
+
"@react-native-ohos/react-native-reanimated": "file:../../node_modules/@react-native-ohos/react-native-reanimated/harmony/reanimated.har",
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
点击右上角的 `sync` 按钮
|
|
117
|
+
|
|
118
|
+
或者在命令行终端执行:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
cd entry
|
|
122
|
+
ohpm install
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
方法二:直接链接源码
|
|
126
|
+
|
|
127
|
+
> [!TIP] 如需使用直接链接源码,请参考[直接链接源码说明](https://gitcode.com/CPF-RN/usage-docs/blob/master/zh-cn/link-source-code.md)
|
|
128
|
+
|
|
129
|
+
### 3. 配置 CMakeLists 和引入 ReanimatedPackage
|
|
130
|
+
|
|
131
|
+
打开 `entry/src/main/cpp/CMakeLists.txt`,添加:
|
|
132
|
+
|
|
133
|
+
```diff
|
|
134
|
+
project(rnapp)
|
|
135
|
+
cmake_minimum_required(VERSION 3.4.1)
|
|
136
|
+
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
137
|
+
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
|
|
138
|
+
set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
|
|
139
|
+
+ set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
|
|
140
|
+
|
|
141
|
+
# 若开启对应SVG的Feature flags,需配置如下:
|
|
142
|
+
+ add_compile_definitions(REANIMATED_FEATURE_FLAGS='[EXPERIMENTAL_CSS_ANIMATIONS_FOR_SVG_COMPONENTS:true][ENABLE_SHARED_ELEMENT_TRANSITIONS:false][DISABLE_COMMIT_PAUSING_MECHANISM:false][ANDROID_SYNCHRONOUSLY_UPDATE_UI_PROPS:false][IOS_SYNCHRONOUSLY_UPDATE_UI_PROPS:false][USE_SYNCHRONIZABLE_FOR_MUTABLES:false][USE_COMMIT_HOOK_ONLY_FOR_REACT_COMMITS:false][FORCE_REACT_RENDER_FOR_SETTLED_ANIMATIONS:false]')
|
|
143
|
+
|
|
144
|
+
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
|
|
145
|
+
|
|
146
|
+
# RNOH_BEGIN: manual_package_linking_1
|
|
147
|
+
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
|
|
148
|
+
|
|
149
|
+
+ add_subdirectory("${OH_MODULES}/@react-native-ohos/react-native-reanimated/src/main/cpp" ./reanimated)
|
|
150
|
+
|
|
151
|
+
# RNOH_END: manual_package_linking_1
|
|
152
|
+
|
|
153
|
+
add_library(rnoh_app SHARED
|
|
154
|
+
"./PackageProvider.cpp"
|
|
155
|
+
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
target_link_libraries(rnoh_app PUBLIC rnoh)
|
|
159
|
+
|
|
160
|
+
# RNOH_BEGIN: manual_package_linking_2
|
|
161
|
+
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
|
|
162
|
+
+ target_link_libraries(rnoh_app PUBLIC rnoh_reanimated)
|
|
163
|
+
|
|
164
|
+
# RNOH_END: manual_package_linking_2
|
|
165
|
+
```
|
|
166
|
+
> [!Tip] 注意:上面RNOH_CPP_DIR定义,为RNOH框架的安装路径,用户可以根据安装的实际路径定义RNOH_CPP_DIR
|
|
167
|
+
|
|
168
|
+
打开 `entry/src/main/cpp/PackageProvider.cpp`,添加:
|
|
169
|
+
|
|
170
|
+
```diff
|
|
171
|
+
#include "RNOH/PackageProvider.h"
|
|
172
|
+
#include "SamplePackage.h"
|
|
173
|
+
+ #include "ReanimatedPackage.h"
|
|
174
|
+
using namespace rnoh;
|
|
175
|
+
|
|
176
|
+
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
|
|
177
|
+
return {
|
|
178
|
+
std::make_shared<SamplePackage>(ctx),
|
|
179
|
+
+ std::make_shared<ReanimatedPackage>(ctx)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 4. 在 ArkTs 侧引入 ReanimatedPackage
|
|
185
|
+
|
|
186
|
+
打开 `entry/src/main/ets/RNPackagesFactory.ts`,添加:
|
|
187
|
+
|
|
188
|
+
```diff
|
|
189
|
+
...
|
|
190
|
+
+ import { ReanimatedPackage} from '@react-native-ohos/react-native-reanimated/ts';
|
|
191
|
+
|
|
192
|
+
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
|
|
193
|
+
return [
|
|
194
|
+
new SamplePackage(ctx),
|
|
195
|
+
+ new ReanimatedPackage(ctx),
|
|
196
|
+
];
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### 运行
|
|
201
|
+
|
|
202
|
+
点击右上角的 `sync` 按钮
|
|
203
|
+
|
|
204
|
+
或者在命令行终端执行:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
cd entry
|
|
208
|
+
ohpm install
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
然后编译、运行即可。
|
|
212
|
+
|
|
213
|
+
## 约束与限制
|
|
214
|
+
|
|
215
|
+
### 兼容性
|
|
216
|
+
|
|
217
|
+
本文档内容基于以下版本验证通过:
|
|
218
|
+
|
|
219
|
+
1. RNOH: 0.82.7; SDK: HarmonyOS 6.0.1 Release SDK; IDE: DevEco Studio 6.0.1.260; ROM: 6.0.0.130 SP15;
|
|
220
|
+
|
|
221
|
+
### 权限要求
|
|
222
|
+
|
|
223
|
+
> [!Tip] 使用传感器的功能,需要使用 >=4.0.0 的版本。如需使用传感器(如加速度传感器、陀螺仪),需要添加对应的传感器权限。
|
|
224
|
+
|
|
225
|
+
在 `entry` 目录下的 `module.json5` 中添加权限
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
"requestPermissions": [
|
|
229
|
+
+ {
|
|
230
|
+
+ "name": "ohos.permission.ACCELEROMETER", // 加速传感器权限名称
|
|
231
|
+
+ "reason": "$string:accele_reason",
|
|
232
|
+
+ "usedScene": {
|
|
233
|
+
+ "abilities": [
|
|
234
|
+
+ "EntryAbility"
|
|
235
|
+
+ ],
|
|
236
|
+
+ "when":"inuse"
|
|
237
|
+
+ }
|
|
238
|
+
+ },
|
|
239
|
+
+ {
|
|
240
|
+
+ "name": "ohos.permission.GYROSCOPE", // 陀螺仪传感器权限名称
|
|
241
|
+
+ "reason": "$string:gyr_reason",
|
|
242
|
+
+ "usedScene": {
|
|
243
|
+
+ "abilities": [
|
|
244
|
+
+ "EntryAbility"
|
|
245
|
+
+ ],
|
|
246
|
+
+ "when":"inuse"
|
|
247
|
+
+ }
|
|
248
|
+
+ },
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
在 entry 目录下添加申请以上权限的原因
|
|
253
|
+
打开 `entry/src/main/resources/base/element/string.json`,添加:
|
|
254
|
+
```
|
|
255
|
+
{
|
|
256
|
+
"string": [
|
|
257
|
+
+ {
|
|
258
|
+
+ "name": "accele_reason",
|
|
259
|
+
+ "value": "使用加速度传感器"
|
|
260
|
+
+ },
|
|
261
|
+
+ {
|
|
262
|
+
+ "name": "gyr_reason",
|
|
263
|
+
+ "value": "使用陀螺仪传感器"
|
|
264
|
+
+ },
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### 编译运行API要求
|
|
270
|
+
|
|
271
|
+
> [!TIP] 当前三方库所有版本均已实现版本隔离,支持在 `API12+` 工程编译,及 `API12+` ROM 运行。
|
|
272
|
+
|
|
273
|
+
> [!TIP] 以下功能依赖特定版本的API,使用 `低于指定API版本的工程编译` 或 `低于指定API版本的ROM运行` 均可能导致部分功能受限。
|
|
274
|
+
1. `4.0.2+` 版本新增支持 `useReducedMotion` API。该能力依托系统提供的 `isAnimationReduceEnabledSync` API 实现,用于检测设备是否开启减弱动效(reduced motion)辅助功能;该接口仅在 `API23 及以上版本的` ROM 环境中生效
|
|
275
|
+
|
|
276
|
+
## 使用示例
|
|
277
|
+
|
|
278
|
+
下面的代码展示了这个库的基本使用场景:
|
|
279
|
+
|
|
280
|
+
> [!WARNING] 使用时 import 的库名不变。
|
|
281
|
+
|
|
282
|
+
```js
|
|
283
|
+
import { Button, View } from "react-native";
|
|
284
|
+
import Animated, { useSharedValue, withSpring } from "react-native-reanimated";
|
|
285
|
+
|
|
286
|
+
export default function App() {
|
|
287
|
+
const width = useSharedValue(100);
|
|
288
|
+
|
|
289
|
+
const handlePress = () => {
|
|
290
|
+
width.value = withSpring(width.value + 50);
|
|
291
|
+
};
|
|
292
|
+
|
|
293
|
+
return (
|
|
294
|
+
<View style={{ flex: 1, alignItems: "center" }}>
|
|
295
|
+
<Animated.View
|
|
296
|
+
style={{
|
|
297
|
+
width,
|
|
298
|
+
height: 100,
|
|
299
|
+
backgroundColor: "violet",
|
|
300
|
+
}}
|
|
301
|
+
/>
|
|
302
|
+
<Button onPress={handlePress} title="Click me" />
|
|
303
|
+
</View>
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 接口说明
|
|
309
|
+
|
|
310
|
+
> [!TIP] "平台"列表示该属性在原三方库上支持的平台。
|
|
311
|
+
|
|
312
|
+
> [!TIP] "HarmonyOS平台支持"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
|
|
313
|
+
|
|
314
|
+
### API
|
|
315
|
+
|
|
316
|
+
| 名称 | 类型 | 参数类型 | 返回值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
317
|
+
| ------------------ |----------| -------- | ------ | -------- | -------- | ----------------- | ---- |
|
|
318
|
+
| `withTiming` | function | `(toValue: T, userConfig?: TimingConfig, callback?: AnimationCallback)` | `T` | No | All | yes | withTiming 可基于时长和缓动函数创建动画。 |
|
|
319
|
+
| `withSpring` | function | `(toValue: T, userConfig?: SpringConfig, callback?: AnimationCallback)` | `T` | No | All | yes | withSpring 可创建基于弹簧物理的动画。 |
|
|
320
|
+
| `withDecay` | function | `(userConfig: DecayConfig, callback?: AnimationCallback)` | `number` | No | All | yes | withDecay 可创建模拟带有摩擦力的运动物体的动画。动画将以给定的初速度开始,并根据给定的减速率随时间逐渐减速,直至停止。 |
|
|
321
|
+
| `withRepeat` | function | `(_animation: T, numberOfRepeats?: number, reverse?: boolean, callback?: AnimationCallback)` | `T` | No | All | yes | withRepeat 是一个动画修饰器,可将动画重复指定次数,或无限循环运行。 |
|
|
322
|
+
| `useSharedValue` | function | `(initialValue: Value)` | `SharedValue<Value>` | No | All | yes | useSharedValue 可在组件中定义共享值。 |
|
|
323
|
+
| `useAnimatedStyle` | function | `(updater: () => Style, dependencies?: DependencyList)` | `Style` | No | All | yes | useAnimatedStyle 可创建一个样式对象(类似于 StyleSheet 样式),并可通过共享值对其进行动画处理。 |
|
|
324
|
+
| `useAnimatedRef` | function | `/` | `AnimatedRef<T>` | No | All | yes | useAnimatedRef 可获取视图的引用。可与 measure、scrollTo 和 useScrollViewOffset 函数配合使用。 |
|
|
325
|
+
| `useDerivedValue` | function | `(updater: () => Value, dependencies?: DependencyList)` | `DerivedValue<Value>` | No | All | yes | useDerivedValue 可基于已有的共享值创建新的共享值,并保持其响应性。 |
|
|
326
|
+
| `cancelAnimation` | function | `(sharedValue: SharedValue<TValue>)` | `void` | No | All | yes | cancelAnimation 可取消与某个共享值关联的正在运行的动画。 |
|
|
327
|
+
| `runOnJS`<sup>deprecated</sup> | function | `(fn: Function)` | `(...args: any[]) => void` | No | All | yes | runOnJS 可异步运行未被 worklet 化的函数(这些函数通常无法在 UI 线程上运行)。这适用于大多数外部库,因为它们的函数未标记 "worklet" 指令。 |
|
|
328
|
+
| `runOnUI`<sup>deprecated</sup> | function | `(fn: Function)` | `(...args: any[]) => void` | No | All | yes | runOnUI 可在 UI 线程上异步运行被 worklet 化的函数。 |
|
|
329
|
+
| `measure` | function | `(animatedRef: AnimatedRef<TRef>)` | `MeasuredDimensions \| null` | No | All | yes | measure 可在 UI 线程上同步获取屏幕上视图的尺寸和位置。 |
|
|
330
|
+
| `Easing` | object | `/` | `/` | No | All | yes | 缓动函数,用于设置运动的轨迹。 |
|
|
331
|
+
| `useAnimatedKeyboard` | function | `(options?: AnimatedKeyboardOptions)` | `AnimatedKeyboardInfo` | No | All | yes | useAnimatedKeyboard 可基于虚拟键盘的状态和高度创建动画。 |
|
|
332
|
+
| `useComposedEventHandler`| function | `(handlers: (EventHandlerProcessed \| null)[])` | `ComposedHandlerProcessed` | No | All | yes | 这是一个 Hook,可将基于 useEvent 的事件处理器(如 useAnimatedScrollHandler 或自定义事件处理器)组合为一个单一的事件处理器。 |
|
|
333
|
+
| `makeMutable` | function | `(initial: Value)` | `Mutable<Value>` | No | All | yes | makeMutable 是 useSharedValue Hook 内部用于创建共享值的函数。 |
|
|
334
|
+
| `ReducedMotionConfig` | function | `(config: ReducedMotionConfig)` | `null` | No | All | yes | 根据设备的减弱动效辅助功能设置改变行为。 |
|
|
335
|
+
| `useAnimatedGestureHandler`<sup>deprecated</sup> | function | `(handlers: GestureHandlers, config?: Config)` | `OnGestureEvent` | No | All | No | 可基于手势处理器创建动画。 |
|
|
336
|
+
| `useScrollViewOffset` <sup> deprecated </sup> | function | `(animatedRef: AnimatedRef<AnimatedScrollView>, providedOffset?: SharedValue<number>)` | `SharedValue<number>` | No | All | yes | 可基于 ScrollView 的偏移量创建动画。 |
|
|
337
|
+
| `useScrollOffset` | function | `(animatedRef: AnimatedRef<TRef>, providedOffset?: SharedValue<number>)` | `SharedValue<number>` | No | All | yes | 可基于可滚动组件(如 ScrollView、FlatList、FlashList)的偏移量创建动画。 |
|
|
338
|
+
| `createAnimatedComponent ` | function | `(Component: React.ComponentType, options?: Options)` | `AnimatedComponentType` | No | All | yes | 可为任意 React Native 组件创建动画版本。 |
|
|
339
|
+
| `getStaticFeatureFlag` | function | `(name: keyof StaticFeatureFlagsSchema)` | `boolean` | No | All | yes | 用于获取静态功能标志(feature flags)的函数。 |
|
|
340
|
+
| `setDynamicFeatureFlag` | function | `(name: DynamicFlagName, value: boolean)` | `void` | No | All | yes | 用于动态设置功能标志的函数。 |
|
|
341
|
+
| `reanimatedVersion` | string | `/` | `/` | No | All | yes | 获取动画库的版本号。 |
|
|
342
|
+
| `useAnimatedProps` | function | `(updater: () => AnimatedProps, dependencies?: DependencyList)` | `AnimatedProps` | No | All | yes | React Native Reanimated 库中的一个自定义 Hook,用于创建可动画化的组件属性。 |
|
|
343
|
+
| `useReducedMotion`<sup>API>=23</sup> | function | `/` | `boolean` | No | All | yes | React Native Reanimated 库中的一个 Hook,用于检测设备是否启用了减弱动效(reduced motion)辅助功能设置。 |
|
|
344
|
+
|
|
345
|
+
### 属性
|
|
346
|
+
|
|
347
|
+
**WithSpringConfig**
|
|
348
|
+
|
|
349
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
350
|
+
| ----------------------- | ------------------------------------------------------------ | ---------------- | -------- | --------------- | ------------------ | ---- |
|
|
351
|
+
| clamp | `{ min?: number; max?: number }` | None | No | Android and iOS | yes | 限制运动范围。如果弹簧动画会超出此限制,则会降低 `dampingRatio`(使弹簧的弹性减弱) |
|
|
352
|
+
|
|
353
|
+
**SharedValue**
|
|
354
|
+
|
|
355
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
356
|
+
| --------------------- | ------------------------------------------------------------ | -------- | -------- | --------------- | ------------------ | ---- |
|
|
357
|
+
| get | `() => Value` | None | No | Android and iOS | yes | 返回当前值 |
|
|
358
|
+
| set | `(value: Value \| ((value: Value) => Value)) => void` | None | No | Android and iOS | yes | 更新存储的值(支持直接赋值或更新函数) |
|
|
359
|
+
| addListener | `(listenerID: number, listener: (value: Value) => void) => void` | None | No | Android and iOS | yes | 注册值变化监听器 |
|
|
360
|
+
| modify | `(modifier?: (value: Value) => Value, forceUpdate?: boolean) => void` | None | No | Android and iOS | yes | 对当前值应用变换 |
|
|
361
|
+
|
|
362
|
+
**DerivedValue**
|
|
363
|
+
|
|
364
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
365
|
+
| ------------------------------------ | --------------------------- | -------- | -------- | --------------- | ------------------ | ---- |
|
|
366
|
+
| set<sup>deprecated</sup> | None | None | No | Android and iOS | No | 派生值为只读 |
|
|
367
|
+
|
|
368
|
+
**CurrentLayoutAnimationsValues**
|
|
369
|
+
|
|
370
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
371
|
+
| ------------------------------------- | --------------------- | ------ | -------- | --------------- | ------------------ | ---- |
|
|
372
|
+
| currentBorderRadius | number | 0 | No | Android and iOS | No | 视图的圆角半径 |
|
|
373
|
+
|
|
374
|
+
**EntryAnimationsValues**
|
|
375
|
+
|
|
376
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
377
|
+
| ------------------------------------ | --------------------- | ------ | -------- | --------------- | ------------------ | ---- |
|
|
378
|
+
| targetBorderRadius | number | 0 | No | Android and iOS | No | 视图的圆角半径 |
|
|
379
|
+
|
|
380
|
+
**itemLayoutAnimation**
|
|
381
|
+
|
|
382
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
383
|
+
| ------------------------------------- | ----------------------------------------- | --------------- | -------- | --------------- | ------------------ | ---- |
|
|
384
|
+
| itemLayoutAnimation | `ILayoutAnimationBuilder` | None | No | Android and iOS | yes | 定义列表项的布局过渡动画 |
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
**CSS Transitions**
|
|
388
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
389
|
+
| ------------------------------------- | ----------------------------------------- | --------------- | -------- | --------------- | ------------------ | ---- |
|
|
390
|
+
| transitionProperty | `'all' \| 'none' \| keyof S \| string[]` | None | No | Android and iOS | yes | 用于指定要进行过渡动画的样式属性名称。 |
|
|
391
|
+
| transitionDuration | `TimeUnit`(`${number}s` / `${number}ms` / number) | None | No | Android and iOS | yes | 用于指定过渡动画持续的时间长度。 |
|
|
392
|
+
| transitionDelay | `TimeUnit`(`${number}s` / `${number}ms` / number) | None | No | Android and iOS | yes | 用于指定过渡动画开始前的等待时间。 |
|
|
393
|
+
| transitionTimingFunction | `CSSTimingFunction` | None | No | Android and iOS | yes | 用于调整过渡过程中中间值的计算方式。 |
|
|
394
|
+
| transitionBehavior | `'normal' \| 'allow-discrete'` | None | No | Android and iOS | yes | 用于确定过渡动画是否应用于离散属性。 |
|
|
395
|
+
|
|
396
|
+
|
|
397
|
+
**CSS Animations**
|
|
398
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
399
|
+
| ------------------------------------- | ----------------------------------------- | --------------- | -------- | --------------- | ------------------ | ---- |
|
|
400
|
+
| animationName | `CSSKeyframesRule \| CSSAnimationKeyframes \| 'none'` | None | No | Android and iOS | yes | 用于指定动画的关键帧。 |
|
|
401
|
+
| animationDuration | `TimeUnit`(`${number}s` / `${number}ms` / number) | None | No | Android and iOS | yes | 用于指定动画持续的时间长度。 |
|
|
402
|
+
| animationDelay | `TimeUnit`(`${number}s` / `${number}ms` / number) | None | No | Android and iOS | yes | 用于指定动画开始前的等待时间。 |
|
|
403
|
+
| animationTimingFunction | `CSSTimingFunction` | None | No | Android and iOS | yes | 用于调整动画过程中中间值的计算方式。 |
|
|
404
|
+
| animationDirection | `'normal' \| 'reverse' \| 'alternate' \| 'alternate-reverse'` | None | No | Android and iOS | yes | 用于指定动画的运行方向。 |
|
|
405
|
+
| animationIterationCount | `'infinite' \| number` | None | No | Android and iOS | yes | 用于指定动画重复播放的次数,或无限循环播放。 |
|
|
406
|
+
| animationFillMode | `'none' \| 'forwards' \| 'backwards' \| 'both'` | None | No | Android and iOS | yes | 用于指定动画开始前和结束后计算样式的保留方式。 |
|
|
407
|
+
| animationPlayState | `'running' \| 'paused'` | None | No | Android and iOS | yes | 用于播放和暂停动画。 |
|
|
408
|
+
|
|
409
|
+
**Common object**
|
|
410
|
+
| 名称 | 参数类型 | 默认值 | 必填 | 平台 | HarmonyOS平台支持 | 描述 |
|
|
411
|
+
| ------- | --------------------- | --------------- | -------- | --------------- | ------------------ | ---- |
|
|
412
|
+
| `GentleSpringConfig` | `SpringConfig` | `{ damping: 120, mass: 4, stiffness: 900 }` | No | All | yes | 这是一个预定义的弹簧动画配置,用于创建平滑、柔和的弹簧效果。 |
|
|
413
|
+
| `GentleSpringConfigWithDuration` | `SpringConfig` | `{ duration: 550, dampingRatio: 1 }` | No | All | yes | 这是 GentleSpringConfig 的另一种形式,使用 duration 和 dampingRatio 参数来定义弹簧动画。 |
|
|
414
|
+
| `Reanimated3DefaultSpringConfig` | `SpringConfig` | `{ damping: 10, mass: 1, stiffness: 100 }` | No | All | yes | 会生成一个高弹性且具有明显振荡的动画。 |
|
|
415
|
+
| `Reanimated3DefaultSpringConfigWithDuration` | `SpringConfig` | `{ duration: 1333, dampingRatio: 0.5 }` | No | All | yes | 会生成一个灵活的动画。 |
|
|
416
|
+
| `SnappySpringConfig` | `SpringConfig` | `{ damping: 110, mass: 4, stiffness: 900, overshootClamping: true }` | No | All | yes | 该配置定义了“敏捷”(Snappy)的弹簧动画。 |
|
|
417
|
+
| `SnappySpringConfigWithDuration` | `SpringConfig` | `{ duration: 550, dampingRatio: 0.92, overshootClamping: true }` | No | All | yes | 该配置定义了“快速”(Snappy)的弹簧动画。 |
|
|
418
|
+
| `WigglySpringConfig` | `SpringConfig` | `{ damping: 90, mass: 4, stiffness: 900 }` | No | All | yes | 该配置定义了“摇摆”(Wiggly)的弹簧动画,会产生明显的摇摆/弹跳效果。 |
|
|
419
|
+
| `WigglySpringConfigWithDuration` | `SpringConfig` | `{ duration: 550, dampingRatio: 0.75 }` | No | All | yes | 该配置定义了“摇摆”(Wiggly)的弹簧动画,会在 550ms 内完成动画,并产生明显的振荡效果(欠阻尼) |
|
|
420
|
+
| `EasingFunctionFactory` | `{ factory: () => EasingFunction }` | None | No | All | yes | 库中的一个类型定义,用作创建缓动函数的工厂函数 |
|
|
421
|
+
| `EntryOrExitLayoutType` | `BaseAnimationBuilder \| typeof BaseAnimationBuilder \| EntryExitAnimationFunction \| ReanimatedKeyframe` | None | No | All | yes | 一个组合类型,用于定义进入或退出动画的类型 |
|
|
422
|
+
| `DynamicColorIOS` | `(tuple: DynamicColorIOSTuple) => OpaqueColorValue` | None | No | iOS | no | 专为在 Reanimated 中使用而设计,用于定义能够自动适应 iOS 浅色和深色模式的颜色 |
|
|
423
|
+
|
|
424
|
+
## 遗留问题
|
|
425
|
+
|
|
426
|
+
## 其他
|
|
427
|
+
- [React Native中LayoutAnimation与react-native-reanimated存在不兼容,推荐使用react-native-reanimated](https://github.com/software-mansion/react-native-reanimated/issues/6751)
|
|
428
|
+
|
|
429
|
+
## 目录结构
|
|
430
|
+
````
|
|
431
|
+
/rntpc_react-native-reanimated # 项目根目录
|
|
432
|
+
├── package # 发布包
|
|
433
|
+
│ ├── react-native-reanimated # reanimated 鸿蒙适配
|
|
434
|
+
│ │ ├── harmony # 鸿蒙适配代码
|
|
435
|
+
│ │ │ ├── reanimated.har # har 包
|
|
436
|
+
│ │ │ └── reanimated # 鸿蒙适配核心代码
|
|
437
|
+
│ │ │ ├── index.ets # 鸿蒙适配代码入口
|
|
438
|
+
│ │ │ └── src/main
|
|
439
|
+
│ │ │ ├── cpp # C++ 原生层(ReanimatedPackage、ReanimatedModule 等)
|
|
440
|
+
│ │ │ ├── ets # ArkTS 层
|
|
441
|
+
│ │ │ └── module.json5
|
|
442
|
+
│ │ ├── src # RN / TS 代码
|
|
443
|
+
│ │ │ └── index.ts # 入口文件
|
|
444
|
+
│ │ └── package.json
|
|
445
|
+
│ └── react-native-worklets # worklets 依赖(需单独引入)
|
|
446
|
+
│ ├── harmony # 鸿蒙适配代码
|
|
447
|
+
│ │ ├── worklets.har # har 包
|
|
448
|
+
│ │ └── worklets # 鸿蒙适配核心代码
|
|
449
|
+
│ │ ├── index.ets # 鸿蒙适配代码入口
|
|
450
|
+
│ │ └── src/main
|
|
451
|
+
│ │ ├── cpp # C++ 原生层
|
|
452
|
+
│ │ ├── ets # ArkTS 层
|
|
453
|
+
│ │ └── module.json5
|
|
454
|
+
│ ├── src # RN / TS 代码
|
|
455
|
+
│ │ └── index.ts # 入口文件
|
|
456
|
+
│ └── package.json
|
|
457
|
+
├── example # 示例工程
|
|
458
|
+
├── README.md # 中文安装使用方法
|
|
459
|
+
├── README_en.md # 英文安装使用方法
|
|
460
|
+
├── CHANGELOG.md # 更新日志
|
|
461
|
+
└── OAT.xml # 开源合规
|
|
462
|
+
````
|
|
463
|
+
|
|
464
|
+
## 贡献代码
|
|
465
|
+
|
|
466
|
+
使用过程中发现任何问题都可以提交 [Issue](https://gitcode.com/CPF-RN/rntpc_react-native-reanimated/issues),当然,也非常欢迎提交 [PR](https://gitcode.com/CPF-RN/rntpc_react-native-reanimated/pulls) 。
|
|
467
|
+
|
|
468
|
+
## 开源协议
|
|
469
|
+
|
|
470
|
+
本项目基于 [The MIT License (MIT)](https://github.com/software-mansion/react-native-reanimated/blob/main/LICENSE) ,请自由地享受和参与开源。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Use these variables when you tailor your ArkTS code. They must be of the const type.
|
|
3
3
|
*/
|
|
4
|
-
export const HAR_VERSION = '4.0.
|
|
4
|
+
export const HAR_VERSION = '4.0.3-beta.1';
|
|
5
5
|
export const BUILD_MODE_NAME = 'debug';
|
|
6
6
|
export const DEBUG = true;
|
|
7
7
|
export const TARGET_NAME = 'default';
|
|
@@ -115,11 +115,12 @@ void ReanimatedModule::installTurboModule(facebook::jsi::Runtime &rt) {
|
|
|
115
115
|
self->keyboardEventDataUpdater_ = std::move(keyboardEventDataUpdater);
|
|
116
116
|
auto weakExecutor = std::weak_ptr(self->m_ctx.taskExecutor);
|
|
117
117
|
if (auto taskExecutor = weakExecutor.lock()) {
|
|
118
|
-
taskExecutor->runTask(TaskThread::MAIN, [ctx = self->m_ctx, isStatusBarTranslucent]() {
|
|
118
|
+
taskExecutor->runTask(TaskThread::MAIN, [ctx = self->m_ctx, isStatusBarTranslucent, isNavigationBarTranslucent]() {
|
|
119
119
|
ArkJS arkJs(ctx.env);
|
|
120
|
-
|
|
120
|
+
auto napiStatusBarTranslucent = arkJs.createBoolean(isStatusBarTranslucent);
|
|
121
|
+
auto napiNavigationBarTranslucent = arkJs.createBoolean(isNavigationBarTranslucent);
|
|
121
122
|
auto napiTurboModuleObject = arkJs.getObject(ctx.arkTSTurboModuleInstanceRef);
|
|
122
|
-
napiTurboModuleObject.call("subscribeKeyBordListeners", {});
|
|
123
|
+
napiTurboModuleObject.call("subscribeKeyBordListeners", {napiStatusBarTranslucent, napiNavigationBarTranslucent});
|
|
123
124
|
});
|
|
124
125
|
}
|
|
125
126
|
return 0;
|
|
@@ -52,54 +52,21 @@ void SensorDataCallbackImpl(Sensor_Event *event) {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
switch (sensorType) {
|
|
55
|
-
case SENSOR_TYPE_ACCELEROMETER:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
data[1],
|
|
59
|
-
data[2],
|
|
60
|
-
};
|
|
61
|
-
sensorInstance->runSensor(sendData);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
case SENSOR_TYPE_GYROSCOPE: {
|
|
65
|
-
double sendData[] = {
|
|
66
|
-
data[0],
|
|
67
|
-
data[1],
|
|
68
|
-
data[2],
|
|
69
|
-
};
|
|
70
|
-
sensorInstance->runSensor(sendData);
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
case SENSOR_TYPE_GRAVITY: {
|
|
74
|
-
double sendData[] = {
|
|
75
|
-
data[0],
|
|
76
|
-
data[1],
|
|
77
|
-
data[2],
|
|
78
|
-
};
|
|
79
|
-
sensorInstance->runSensor(sendData);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
55
|
+
case SENSOR_TYPE_ACCELEROMETER:
|
|
56
|
+
case SENSOR_TYPE_GYROSCOPE:
|
|
57
|
+
case SENSOR_TYPE_GRAVITY:
|
|
82
58
|
case SENSOR_TYPE_MAGNETIC_FIELD: {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
};
|
|
88
|
-
sensorInstance->runSensor(sendData);
|
|
59
|
+
if (length < 3) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
sensorInstance->runSensor({data[0], data[1], data[2]});
|
|
89
63
|
return;
|
|
90
64
|
}
|
|
91
65
|
case SENSOR_TYPE_ROTATION_VECTOR: {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
data[3], // w
|
|
97
|
-
// ios
|
|
98
|
-
0, // yaw
|
|
99
|
-
0, // pitch
|
|
100
|
-
0 // roll
|
|
101
|
-
};
|
|
102
|
-
sensorInstance->runSensor(sendData);
|
|
66
|
+
if (length < 4) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
sensorInstance->runSensor({data[0], data[1], data[2], data[3], 0, 0, 0});
|
|
103
70
|
return;
|
|
104
71
|
}
|
|
105
72
|
default:
|
|
@@ -214,18 +181,48 @@ bool rnoh::ReanimatedSensor::isSupportSensor() {
|
|
|
214
181
|
return isSupport;
|
|
215
182
|
}
|
|
216
183
|
|
|
217
|
-
void rnoh::ReanimatedSensor::runSensor(double
|
|
218
|
-
if (value && setter_ && runOnTheMainThread_) {
|
|
219
|
-
runOnTheMainThread_([weakSelf = weak_from_this(), value]() {
|
|
184
|
+
void rnoh::ReanimatedSensor::runSensor(std::vector<double> value) {
|
|
185
|
+
if (!value.empty() && setter_ && runOnTheMainThread_) {
|
|
186
|
+
runOnTheMainThread_([weakSelf = weak_from_this(), value = std::move(value)]() mutable {
|
|
220
187
|
auto self = weakSelf.lock();
|
|
221
188
|
if (!self) {
|
|
222
189
|
return;
|
|
223
190
|
}
|
|
224
|
-
|
|
191
|
+
try {
|
|
192
|
+
self->setter_(value.data(), self->getInterfaceOrientation());
|
|
193
|
+
} catch (const std::exception& e) {
|
|
194
|
+
LOG(ERROR) << "ReanimatedSensor::runSensor: setter_ exception: " << e.what();
|
|
195
|
+
}
|
|
225
196
|
});
|
|
226
197
|
}
|
|
227
198
|
}
|
|
228
199
|
|
|
200
|
+
/**
|
|
201
|
+
* @deprecated: 改用 `runSensor(std::vector<double> value)`。
|
|
202
|
+
* 按 sensorType_ 推导元素个数,拷贝到堆上 vector 后委托给新接口,
|
|
203
|
+
* 避免外部旧调用方因签名变更编译失败。
|
|
204
|
+
*/
|
|
205
|
+
void rnoh::ReanimatedSensor::runSensor(double *value) {
|
|
206
|
+
if (value == nullptr) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
size_t length = 0;
|
|
210
|
+
switch (sensorType_) {
|
|
211
|
+
case SENSOR_TYPE_ACCELEROMETER:
|
|
212
|
+
case SENSOR_TYPE_GYROSCOPE:
|
|
213
|
+
case SENSOR_TYPE_GRAVITY:
|
|
214
|
+
case SENSOR_TYPE_MAGNETIC_FIELD:
|
|
215
|
+
length = 3;
|
|
216
|
+
break;
|
|
217
|
+
case SENSOR_TYPE_ROTATION_VECTOR:
|
|
218
|
+
length = 7;
|
|
219
|
+
break;
|
|
220
|
+
default:
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
runSensor(std::vector<double>(value, value + length));
|
|
224
|
+
}
|
|
225
|
+
|
|
229
226
|
int rnoh::ReanimatedSensor::getInterfaceOrientation() {
|
|
230
227
|
NativeDisplayManager_Rotation rotation;
|
|
231
228
|
auto ret = OH_NativeDisplayManager_GetDefaultDisplayRotation(&rotation);
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
#define HARMONY_REANIMATEDSENSOR_H
|
|
7
7
|
#include <functional>
|
|
8
8
|
#include <mutex>
|
|
9
|
+
#include <vector>
|
|
9
10
|
#include <sensors/oh_sensor_type.h>
|
|
10
11
|
#include "RNOH/TaskExecutor/TaskExecutor.h"
|
|
11
12
|
|
|
@@ -18,6 +19,17 @@ public:
|
|
|
18
19
|
bool initialize();
|
|
19
20
|
void cancel();
|
|
20
21
|
void castSensorType(int sensorType);
|
|
22
|
+
/**
|
|
23
|
+
* @brief 传入传感器数据,异步投递到主线程执行 setter_。
|
|
24
|
+
* @param value 传感器数据(按值捕获,生命周期随 lambda 绑定)。
|
|
25
|
+
*/
|
|
26
|
+
void runSensor(std::vector<double> value);
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated: 改用 `runSensor(std::vector<double> value)`。
|
|
29
|
+
* 保留以免外部 C++ 插件因签名变更编译失败。内部按 sensorType_ 推导
|
|
30
|
+
* 数据元素个数后拷贝到堆上 vector,再委托给新接口。
|
|
31
|
+
* 调用方需保证 value 在本函数返回前有效(返回后已拷贝无需保持)。
|
|
32
|
+
*/
|
|
21
33
|
void runSensor(double *value);
|
|
22
34
|
std::function<void(double[], int)> setter_;
|
|
23
35
|
Sensor_Type sensorType_{SENSOR_TYPE_ACCELEROMETER};
|