12
12
#include " RNSharedStyle.h"
13
13
14
14
#include " RNSharedNode.h"
15
+ #include " helper/Rect.h"
15
16
16
17
17
18
namespace rnoh {
@@ -35,6 +36,7 @@ class RNTransitionNode : public ArkUINode {
35
36
void setAlign (int align) {
36
37
if (align_ != align) {
37
38
align_ = align;
39
+ setAlignmentWithAlign ();
38
40
}
39
41
}
40
42
@@ -44,34 +46,103 @@ class RNTransitionNode : public ArkUINode {
44
46
mInitialNodePositionSet = true ;
45
47
}
46
48
}
49
+
50
+ using Alignment = ArkUI_Alignment;
51
+ void setAlignmentWithAlign () {
52
+ switch (align_) {
53
+ case 0 :
54
+ setAlignment (Alignment::ARKUI_ALIGNMENT_CENTER);
55
+ break ;
56
+ case 1 :
57
+ // left-top
58
+ setAlignment (Alignment::ARKUI_ALIGNMENT_TOP_START);
59
+ break ;
60
+ case 2 :
61
+ // left-center
62
+ setAlignment (Alignment::ARKUI_ALIGNMENT_START);
63
+ setAlignment (Alignment::ARKUI_ALIGNMENT_CENTER);
64
+ break ;
65
+ case 3 :
66
+ // left-bottom
67
+ setAlignment (Alignment::ARKUI_ALIGNMENT_BOTTOM_START);
68
+ break ;
69
+ case 4 :
70
+ // right-top
71
+ setAlignment (Alignment::ARKUI_ALIGNMENT_TOP_START);
72
+ break ;
73
+ case 5 :
74
+ // right-center
75
+ setAlignment (Alignment::ARKUI_ALIGNMENT_END);
76
+ setAlignment (Alignment::ARKUI_ALIGNMENT_CENTER);
77
+ break ;
78
+ case 6 :
79
+ // right-bottom
80
+ setAlignment (Alignment::ARKUI_ALIGNMENT_BOTTOM_END);
81
+ break ;
82
+ case 7 :
83
+ // center-top
84
+ setAlignment (Alignment::ARKUI_ALIGNMENT_TOP);
85
+ setAlignment (Alignment::ARKUI_ALIGNMENT_CENTER);
86
+ break ;
87
+ case 8 :
88
+ // center-center
89
+ setAlignment (Alignment::ARKUI_ALIGNMENT_CENTER);
90
+ break ;
91
+ case 9 :
92
+ // center-bottom
93
+ setAlignment (Alignment::ARKUI_ALIGNMENT_BOTTOM);
94
+ setAlignment (Alignment::ARKUI_ALIGNMENT_CENTER);
95
+ break ;
96
+ }
97
+ }
47
98
48
99
void beforeTransition (int item, std::shared_ptr<ComponentInstance> node,
49
100
std::shared_ptr<ComponentInstance> ancestor) {
50
101
if (node == nullptr ) {
51
102
return ;
52
103
}
53
- node->getLocalRootArkUINode ().setOpacity (0 );
54
- transitionNodes.push_back (node);
55
104
105
+ node->getLocalRootArkUINode ().setOpacity (0 );
56
106
107
+ transitionNodes.push_back (node);
108
+
57
109
if (item == 0 ) {
58
110
startNode = node;
111
+
112
+ if (animation_ == 2 ) {
113
+ startNode->getLocalRootArkUINode ().setOpacity (1 );
114
+ }
115
+
59
116
startImageStyle = std::make_shared<RNSharedStyle>();
60
117
std::shared_ptr<ComponentInstance> sourceNode = resolveNode (node, startImageStyle);
61
118
startSharedElementNode.setSize (
62
119
{startImageStyle->boundingBox .size .width , startImageStyle->boundingBox .size .height });
63
120
startSharedElementNode.setSources (startImageStyle->sourceItem .string );
121
+
122
+ auto borderRadius = NativeNodeApi::getInstance ()->getAttribute (
123
+ ancestor->getLocalRootArkUINode ().getArkUINodeHandle (), NODE_BORDER_RADIUS);
124
+ startImageStyle->setBorderRadius (borderRadius);
125
+
126
+ startImageStyle->parentBoundingBox = ancestor->getBoundingBox ();
127
+
64
128
} else {
65
129
endNode = node;
66
130
131
+ if (animation_ == 3 ) {
132
+ endNode->getLocalRootArkUINode ().setOpacity (1 );
133
+ }
134
+
67
135
endImageStyle = std::make_shared<RNSharedStyle>();
68
136
std::shared_ptr<ComponentInstance> sourceNode = resolveNode (node, endImageStyle);
69
137
endSharedElementNode.setSize (
70
138
{endImageStyle->boundingBox .size .width , endImageStyle->boundingBox .size .height });
71
139
endSharedElementNode.setSources (endImageStyle->sourceItem .string );
72
140
141
+ auto borderRadius = NativeNodeApi::getInstance ()->getAttribute (
142
+ ancestor->getLocalRootArkUINode ().getArkUINodeHandle (), NODE_BORDER_RADIUS);
143
+ endImageStyle->setBorderRadius (borderRadius);
73
144
74
- // endSharedElementNode.setUp(item );
145
+ endImageStyle-> parentBoundingBox = ancestor-> getBoundingBox ( );
75
146
}
76
147
}
77
148
@@ -92,6 +163,7 @@ class RNTransitionNode : public ArkUINode {
92
163
OH_ArkUI_NodeUtils_GetLayoutPositionInScreen (node->getLocalRootArkUINode ().getArkUINodeHandle (),
93
164
intOff);
94
165
style->offset = {intOff->x , intOff->y };
166
+
95
167
return child;
96
168
}
97
169
}
@@ -110,6 +182,7 @@ class RNTransitionNode : public ArkUINode {
110
182
// 取 start
111
183
recoverAlpha = mInitialNodePositionSet && nodePosition_ == 1 ;
112
184
}
185
+
113
186
if (recoverAlpha) {
114
187
for (std::shared_ptr<ComponentInstance> node : transitionNodes) {
115
188
node->getLocalRootArkUINode ().setOpacity (1 );
@@ -118,52 +191,126 @@ class RNTransitionNode : public ArkUINode {
118
191
} else {
119
192
if (direct == 1 ) {
120
193
setLayoutPosition (direct);
121
-
122
- Float scaleW = (endImageStyle->boundingBox .size .width - startImageStyle->boundingBox .size .width ) * (1 - nodePosition_);
123
- Float endW = endImageStyle->boundingBox .size .width - scaleW;
124
-
125
- Float scaleH = (endImageStyle->boundingBox .size .height - startImageStyle->boundingBox .size .height ) * (1 - nodePosition_);
126
- Float endH = endImageStyle->boundingBox .size .height - scaleH;
127
-
128
- float scalePositionX = static_cast <float >(endImageStyle->offset .x ) / pixelDensity + scaleW / 2 ;
129
- float scalePositionY = static_cast <float >(endImageStyle->offset .y ) / pixelDensity + scaleH / 2 ;
130
-
131
- if (endW < startImageStyle->boundingBox .size .width ) {
132
- endW = startImageStyle->boundingBox .size .width ;
133
- };
134
- if (endH < startImageStyle->boundingBox .size .height ) {
135
- endH = startImageStyle->boundingBox .size .height ;
136
- };
137
- setPosition ({scalePositionX, scalePositionY});
138
- setSize ({endW, endH});
139
- endSharedElementNode.setSize ({endW, endH});
194
+
195
+ if (endImageStyle->boundingBox .size .width > startImageStyle->boundingBox .size .width &&
196
+ endImageStyle->boundingBox .size .height > startImageStyle->boundingBox .size .height ) {
197
+ // endImageStyle 矩形在宽度和高度上都更大
198
+ Float scaleW = (endImageStyle->boundingBox .size .width - startImageStyle->boundingBox .size .width ) *
199
+ (1 - nodePosition_);
200
+ Float endW = endImageStyle->boundingBox .size .width - scaleW;
201
+
202
+ Float scaleH = (endImageStyle->boundingBox .size .height - startImageStyle->boundingBox .size .height ) *
203
+ (1 - nodePosition_);
204
+ Float endH = endImageStyle->boundingBox .size .height - scaleH;
205
+
206
+ float scalePositionX = static_cast <float >(endImageStyle->offset .x ) / pixelDensity + scaleW / 2 ;
207
+ float scalePositionY = static_cast <float >(endImageStyle->offset .y ) / pixelDensity + scaleH / 2 ;
208
+
209
+ if (endW < startImageStyle->boundingBox .size .width ) {
210
+ endW = startImageStyle->boundingBox .size .width ;
211
+ };
212
+ if (endH < startImageStyle->boundingBox .size .height ) {
213
+ endH = startImageStyle->boundingBox .size .height ;
214
+ };
215
+ setPosition ({scalePositionX, scalePositionY});
216
+ setSize ({endW, endH});
217
+ endSharedElementNode.setSize ({endW, endH});
218
+ } else if (endImageStyle->boundingBox .size .width < startImageStyle->boundingBox .size .width &&
219
+ endImageStyle->boundingBox .size .height < startImageStyle->boundingBox .size .height ) {
220
+ // startImageStyle 矩形在宽度和高度上都更大
221
+ // 计算宽度和高度的缩放量
222
+ Float scaleW = (startImageStyle->boundingBox .size .width - endImageStyle->boundingBox .size .width ) *
223
+ nodePosition_;
224
+ Float endW = startImageStyle->boundingBox .size .width - scaleW;
225
+
226
+ Float scaleH = (startImageStyle->boundingBox .size .height - endImageStyle->boundingBox .size .height ) *
227
+ nodePosition_;
228
+ Float endH = startImageStyle->boundingBox .size .height - scaleH;
229
+
230
+ // 计算缩放后的位置
231
+ float scalePositionX = static_cast <float >(startImageStyle->offset .x ) / pixelDensity + scaleW / 2 ;
232
+ float scalePositionY = static_cast <float >(startImageStyle->offset .y ) / pixelDensity + scaleH / 2 ;
233
+
234
+ // 确保宽度和高度不小于 endImageStyle 的最小值
235
+ if (endW > startImageStyle->boundingBox .size .width ) {
236
+ endW = startImageStyle->boundingBox .size .width ;
237
+ }
238
+ if (endH > startImageStyle->boundingBox .size .height ) {
239
+ endH = startImageStyle->boundingBox .size .height ;
240
+ }
241
+
242
+ // 设置位置和大小
243
+ setPosition ({scalePositionX, scalePositionY});
244
+ setSize ({endW, endH});
245
+ endSharedElementNode.setSize ({endW, endH});
246
+ }
247
+
248
+ applyOpacity (animation_);
249
+
140
250
maybeThrow (NativeNodeApi::getInstance ()->insertChildAt (
141
251
m_nodeHandle, endSharedElementNode.getArkUINodeHandle (), static_cast <int32_t >(-1 )));
142
252
} else {
143
- Float scaleW = (endImageStyle->boundingBox .size .width - startImageStyle->boundingBox .size .width ) * nodePosition_;
144
- Float startW = startImageStyle->boundingBox .size .width + scaleW;
145
-
146
- Float scaleH = (endImageStyle->boundingBox .size .height - startImageStyle->boundingBox .size .height ) * nodePosition_;
147
- Float startH = startImageStyle->boundingBox .size .width + scaleH;
148
-
149
- float scalePositionX = static_cast <float >(startImageStyle->offset .x ) / pixelDensity - scaleW / 2 ;
150
- float scalePositionY = static_cast <float >(startImageStyle->offset .y ) / pixelDensity - scaleH / 2 ;
151
-
152
- if (startW > endImageStyle->boundingBox .size .width ) {
153
- startW = endImageStyle->boundingBox .size .width ;
154
- };
155
- if (startH > endImageStyle->boundingBox .size .height ) {
156
- startH = endImageStyle->boundingBox .size .height ;
157
- };
158
- setPosition ({scalePositionX, scalePositionY});
159
- setSize ({startW, startH});
160
- startSharedElementNode.setSize ({startW, startH});
253
+ if (endImageStyle->boundingBox .size .width > startImageStyle->boundingBox .size .width &&
254
+ endImageStyle->boundingBox .size .height > startImageStyle->boundingBox .size .height ) {
255
+ // endImageStyle 矩形在宽度和高度上都更大
256
+ Float scaleW = (endImageStyle->boundingBox .size .width - startImageStyle->boundingBox .size .width ) *
257
+ nodePosition_;
258
+ Float startW = startImageStyle->boundingBox .size .width + scaleW;
259
+
260
+ Float scaleH = (endImageStyle->boundingBox .size .height - startImageStyle->boundingBox .size .height ) *
261
+ nodePosition_;
262
+ Float startH = startImageStyle->boundingBox .size .width + scaleH;
263
+
264
+ float scalePositionX = static_cast <float >(startImageStyle->offset .x ) / pixelDensity - scaleW / 2 ;
265
+ float scalePositionY = static_cast <float >(startImageStyle->offset .y ) / pixelDensity - scaleH / 2 ;
266
+
267
+ if (startW > endImageStyle->boundingBox .size .width ) {
268
+ startW = endImageStyle->boundingBox .size .width ;
269
+ };
270
+ if (startH > endImageStyle->boundingBox .size .height ) {
271
+ startH = endImageStyle->boundingBox .size .height ;
272
+ };
273
+
274
+ setPosition ({scalePositionX, scalePositionY});
275
+ setSize ({startW, startH});
276
+ startSharedElementNode.setSize ({startW, startH});
277
+ } else if (endImageStyle->boundingBox .size .width < startImageStyle->boundingBox .size .width &&
278
+ endImageStyle->boundingBox .size .height < startImageStyle->boundingBox .size .height ) {
279
+ // 计算缩放量
280
+ Float scaleW = (startImageStyle->boundingBox .size .width - endImageStyle->boundingBox .size .width ) *
281
+ (1 - nodePosition_);
282
+ Float startW = endImageStyle->boundingBox .size .width + scaleW;
283
+
284
+ Float scaleH = (startImageStyle->boundingBox .size .height - endImageStyle->boundingBox .size .height ) *
285
+ (1 - nodePosition_);
286
+ Float startH = endImageStyle->boundingBox .size .height + scaleH;
287
+
288
+ // 计算新的位置,保证中心对齐
289
+ float scalePositionX = static_cast <float >(endImageStyle->offset .x ) / pixelDensity - scaleW / 2 ;
290
+ float scalePositionY = static_cast <float >(endImageStyle->offset .y ) / pixelDensity - scaleH / 2 ;
291
+
292
+ // 设定最大值限制
293
+ if (startW > startImageStyle->boundingBox .size .width ) {
294
+ startW = startImageStyle->boundingBox .size .width ;
295
+ }
296
+ if (startH > startImageStyle->boundingBox .size .height ) {
297
+ startH = startImageStyle->boundingBox .size .height ;
298
+ }
299
+
300
+ // 设置新的位置和大小
301
+ setPosition ({scalePositionX, scalePositionY});
302
+ setSize ({startW, startH});
303
+ startSharedElementNode.setSize ({startW, startH});
304
+ }
305
+
306
+ applyOpacity (animation_);
307
+
161
308
maybeThrow (NativeNodeApi::getInstance ()->insertChildAt (
162
309
m_nodeHandle, startSharedElementNode.getArkUINodeHandle (), static_cast <int32_t >(-1 )));
163
310
}
164
311
}
165
312
};
166
-
313
+
167
314
int isSet = 0 ;
168
315
169
316
void setLayoutPosition (int direct) {
@@ -175,8 +322,18 @@ class RNTransitionNode : public ArkUINode {
175
322
}
176
323
}
177
324
325
+ void applyOpacity (int animationType) {
326
+ if (animationType == 1 || animationType == 3 ) {
327
+ setOpacity (0.5 );
328
+ } else if (animationType == 2 ) {
329
+ setOpacity (0.8 );
330
+ }
331
+ }
332
+
178
333
using Weak = std::weak_ptr<ComponentInstance>;
179
334
ComponentInstance::Weak parent;
335
+ std::shared_ptr<RNSharedStyle> startImageStyle = std::make_shared<RNSharedStyle>();
336
+ std::shared_ptr<RNSharedStyle> endImageStyle = std::make_shared<RNSharedStyle>();
180
337
181
338
private:
182
339
float pixelDensity = 3.25 ;
@@ -186,7 +343,6 @@ class RNTransitionNode : public ArkUINode {
186
343
float nodePosition_;
187
344
bool mInitialNodePositionSet = false ;
188
345
189
-
190
346
std::vector<facebook::react::SharedElementWarpNodeStruct> transitionItems;
191
347
192
348
bool mInitialNodeLayoutPositionSet = false ;
@@ -196,9 +352,6 @@ class RNTransitionNode : public ArkUINode {
196
352
std::shared_ptr<ComponentInstance> endNode = nullptr ;
197
353
198
354
ImageNode startSharedElementNode{};
199
- std::shared_ptr<RNSharedStyle> startImageStyle = std::make_shared<RNSharedStyle>();
200
-
201
355
ImageNode endSharedElementNode{};
202
- std::shared_ptr<RNSharedStyle> endImageStyle = std::make_shared<RNSharedStyle>();
203
356
};
204
357
} // namespace rnoh
0 commit comments