@react-native-ohos/react-native-reanimated 4.0.2-beta.1 → 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/CMakeLists.txt +2 -5
- package/harmony/reanimated/src/main/cpp/ReanimatedModule.cpp +18 -4
- 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 +113 -18
- package/harmony/reanimated.har +0 -0
- package/package.json +12 -4
|
@@ -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};
|
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import { RNOHLogger, Tag, UITurboModule, UITurboModuleContext } from "@rnoh/react-native-openharmony/ts";
|
|
6
|
-
import { window } from '@kit.ArkUI';
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { } from
|
|
6
|
+
import { Animator, AnimatorResult, window } from '@kit.ArkUI';
|
|
7
|
+
import { KeyboardState } from './AnimationManager'
|
|
8
|
+
import deviceInfo from '@ohos.deviceInfo';
|
|
9
|
+
import { accessibility } from '@kit.AccessibilityKit';
|
|
10
10
|
|
|
11
11
|
export class ReanimatedModule extends UITurboModule {
|
|
12
12
|
static NAME = "ReanimatedModule"
|
|
13
13
|
private logger: RNOHLogger
|
|
14
|
-
private
|
|
14
|
+
private currentAnimator: AnimatorResult;
|
|
15
|
+
private currentAnimatedHeight = 0;
|
|
15
16
|
|
|
16
17
|
constructor(ctx: UITurboModuleContext) {
|
|
17
18
|
super(ctx);
|
|
@@ -23,24 +24,107 @@ export class ReanimatedModule extends UITurboModule {
|
|
|
23
24
|
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
public async subscribeKeyBordListeners() {
|
|
27
|
-
|
|
27
|
+
public async subscribeKeyBordListeners(isStatusBarTranslucent: boolean, isNavigationBarTranslucent: boolean) {
|
|
28
|
+
let windowInstance: window.Window;
|
|
29
|
+
try {
|
|
30
|
+
windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
|
|
31
|
+
} catch (e: ESObject) {
|
|
32
|
+
this.logger.error(`subscribeKeyBordListeners failed: ${e?.message ?? e}`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
28
36
|
windowInstance.on('keyboardHeightChange', async (height) => {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
animationManager.startAnimation(this.keyBordHeight, keyBordHeight, 200);
|
|
36
|
-
this.keyBordHeight = keyBordHeight;
|
|
37
|
+
const keyBordHeight = this.calculateKeyboardHeight(windowInstance, height, isNavigationBarTranslucent);
|
|
38
|
+
// Unchanged height, skip handle
|
|
39
|
+
if (Math.abs(keyBordHeight - this.currentAnimatedHeight) < 0.01) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
this.startKeyboardAnimator(keyBordHeight);
|
|
37
43
|
})
|
|
38
44
|
}
|
|
39
45
|
|
|
46
|
+
private calculateKeyboardHeight(windowInstance: window.Window, height: number, isNavigationBarTranslucent: boolean): number {
|
|
47
|
+
let navIndicatorHeight = 0;
|
|
48
|
+
try {
|
|
49
|
+
const navIndicatorArea = windowInstance.getWindowAvoidArea(
|
|
50
|
+
window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR
|
|
51
|
+
);
|
|
52
|
+
navIndicatorHeight = this.ctx.getUIContext().px2vp(
|
|
53
|
+
navIndicatorArea?.bottomRect?.height ?? 0
|
|
54
|
+
);
|
|
55
|
+
} catch (e) {
|
|
56
|
+
navIndicatorHeight = 0;
|
|
57
|
+
}
|
|
58
|
+
const isEdgeToEdge = this.isEdgeToEdgeMode(windowInstance);
|
|
59
|
+
const effectiveNavBarTranslucent = isEdgeToEdge && isNavigationBarTranslucent;
|
|
60
|
+
const rawKeyboardHeight = this.ctx.getUIContext().px2vp(height);
|
|
61
|
+
return effectiveNavBarTranslucent
|
|
62
|
+
? rawKeyboardHeight
|
|
63
|
+
: Math.max(0, rawKeyboardHeight - navIndicatorHeight);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private startKeyboardAnimator(keyBordHeight: number) {
|
|
67
|
+
const isOpening = keyBordHeight > this.currentAnimatedHeight;
|
|
68
|
+
this.cancelCurrentAnimator();
|
|
69
|
+
this.currentAnimator = Animator.create({
|
|
70
|
+
duration: isOpening ? 480 : 350,
|
|
71
|
+
delay: 0,
|
|
72
|
+
//simulate the keyboard pop-up and retraction animations in harmony
|
|
73
|
+
easing: isOpening ? "cubic-bezier(0.2, 0.0, 0.1, 1.0)"
|
|
74
|
+
: "cubic-bezier(0.0, 0.0, 0.1, 1.0)",
|
|
75
|
+
fill: "forwards",
|
|
76
|
+
direction: "normal",
|
|
77
|
+
iterations: 1,
|
|
78
|
+
begin: this.currentAnimatedHeight,
|
|
79
|
+
end: keyBordHeight
|
|
80
|
+
}
|
|
81
|
+
)
|
|
82
|
+
this.currentAnimator.onFrame = (progress: number) => {
|
|
83
|
+
this.currentAnimatedHeight = progress;
|
|
84
|
+
if (Math.abs(progress - keyBordHeight) < 0.01) { //The final instruction is sent by "onFinish".
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
let status = isOpening ? KeyboardState.OPENING : KeyboardState.CLOSING;
|
|
88
|
+
this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
|
|
89
|
+
{ keyboardHeight: progress, status: status.valueOf() });
|
|
90
|
+
}
|
|
91
|
+
this.currentAnimator.onFinish = () => {
|
|
92
|
+
this.currentAnimatedHeight = keyBordHeight;
|
|
93
|
+
let status = isOpening ? KeyboardState.OPEN : KeyboardState.CLOSED;
|
|
94
|
+
this.ctx.rnInstance.postMessageToCpp("REANIMATED_KEY_BOARD_CHANGE",
|
|
95
|
+
{ keyboardHeight: keyBordHeight, status: status.valueOf() });
|
|
96
|
+
}
|
|
97
|
+
this.currentAnimator.play();
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
private cancelCurrentAnimator() {
|
|
101
|
+
if (this.currentAnimator) {
|
|
102
|
+
this.currentAnimator.onFrame = null;
|
|
103
|
+
this.currentAnimator.onFinish = null;
|
|
104
|
+
this.currentAnimator.cancel();
|
|
105
|
+
this.currentAnimator = null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private isEdgeToEdgeMode(windowInstance: window.Window): boolean {
|
|
110
|
+
try {
|
|
111
|
+
return windowInstance.getWindowProperties().isLayoutFullScreen;
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
40
117
|
public async unsubscribeKeyBordListeners() {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
118
|
+
let windowInstance: window.Window;
|
|
119
|
+
try {
|
|
120
|
+
windowInstance = await window.getLastWindow(this.ctx.uiAbilityContext);
|
|
121
|
+
} catch (e: ESObject) {
|
|
122
|
+
this.logger.error(`unsubscribeKeyBordListeners failed: ${e?.message ?? e}`);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
windowInstance.off('keyboardHeightChange')
|
|
126
|
+
this.cancelCurrentAnimator();
|
|
127
|
+
this.currentAnimatedHeight = 0;
|
|
44
128
|
}
|
|
45
129
|
|
|
46
130
|
public setGestureHandlerState(handlerTag: Tag, newState: number) {
|
|
@@ -49,4 +133,15 @@ export class ReanimatedModule extends UITurboModule {
|
|
|
49
133
|
module.setGestureHandlerState(handlerTag, newState);
|
|
50
134
|
}
|
|
51
135
|
}
|
|
136
|
+
|
|
137
|
+
public isReducedMotionEnabled(): boolean {
|
|
138
|
+
try {
|
|
139
|
+
if (deviceInfo.sdkApiVersion >= 23) {
|
|
140
|
+
return (accessibility as ESObject).isAnimationReduceEnabledSync();
|
|
141
|
+
}
|
|
142
|
+
} catch (e) {
|
|
143
|
+
this.logger.warn(`isReducedMotionEnabled failed: ${JSON.stringify(e)}`);
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
52
147
|
}
|
package/harmony/reanimated.har
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -4,14 +4,21 @@
|
|
|
4
4
|
"alias": "react-native-reanimated",
|
|
5
5
|
"redirectInternalImports": true
|
|
6
6
|
},
|
|
7
|
-
"version": "4.0.
|
|
7
|
+
"version": "4.0.3-beta.1",
|
|
8
8
|
"description": "",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://gitcode.com/CPF-RN/rntpc_react-native-reanimated.git",
|
|
12
|
+
"directory": "package/react-native-reanimated"
|
|
13
|
+
},
|
|
14
|
+
"homepage": "https://gitcode.com/CPF-RN/rntpc_react-native-reanimated/blob/br_rnoh0.82/README.md",
|
|
9
15
|
"main": "lib/index.js",
|
|
10
16
|
"scripts": {
|
|
11
17
|
"build": "tsc",
|
|
12
18
|
"pack":"npm pack",
|
|
13
19
|
"pack:prod": "npm pack",
|
|
14
|
-
"prepack": "npm run build",
|
|
20
|
+
"prepack": "npm run build && node -e \"require('fs').copyFileSync('../../CHANGELOG.md','./CHANGELOG.md')\" && node -e \"require('fs').copyFileSync('../../README.md','./README.md')\"",
|
|
21
|
+
"postpack": "node -e \"require('fs').rmSync('./CHANGELOG.md',{force:true})\" && node -e \"require('fs').rmSync('./README.md',{force:true})\"",
|
|
15
22
|
"prepublishOnly": "npm run prepack && react-native verify-package-harmony --package-path . --skip-checks oh_package_name_is_derived_from_npm_package_name",
|
|
16
23
|
"update_version": "node ./scripts/update-version.js",
|
|
17
24
|
"deploy": "node ./scripts/deploy.js"
|
|
@@ -62,9 +69,10 @@
|
|
|
62
69
|
"files": [
|
|
63
70
|
"lib",
|
|
64
71
|
"harmony",
|
|
65
|
-
|
|
72
|
+
"scripts",
|
|
66
73
|
"src",
|
|
67
74
|
"./harmony.tar.gz",
|
|
68
|
-
|
|
75
|
+
"compatibility.json",
|
|
76
|
+
"CHANGELOG.md"
|
|
69
77
|
]
|
|
70
78
|
}
|