1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "core/components_ng/render/adapter/rosen_transition_effect.h"
17
18 #include "core/components_ng/render/adapter/rosen_render_context.h"
19 #include "core/components_ng/render/adapter/rosen_transition_effect_impl.h"
20
21 namespace OHOS::Ace::NG {
22 namespace {
23 constexpr float SLIDE_SWITCH_FRAME_PERCENT = 0.333f;
24 constexpr float SLIDE_SWITCH_SCALE = 0.85f;
25 const auto SLIDE_SWITCH_DEFAULT_CURVE = AceType::MakeRefPtr<CubicCurve>(0.24f, 0.0f, 0.50f, 1.0f);
26 constexpr int32_t SLIDE_SWITCH_DEFAULT_DURATION = 600;
27 const auto SLIDE_SWITCH_DEFAULT_OPTION =
28 std::make_shared<AnimationOption>(SLIDE_SWITCH_DEFAULT_CURVE, SLIDE_SWITCH_DEFAULT_DURATION);
29 const std::vector<std::pair<float, Rosen::Vector2f>> SLIDE_SWITCH_KEYFRAMES = {
30 { SLIDE_SWITCH_FRAME_PERCENT, Rosen::Vector2f { SLIDE_SWITCH_SCALE, SLIDE_SWITCH_SCALE } },
31 };
32 } // namespace
33
Attach(const RefPtr<RosenRenderContext> & context,bool activeTransition)34 void RosenTransitionEffect::Attach(const RefPtr<RosenRenderContext>& context, bool activeTransition)
35 {
36 OnAttach(context, activeTransition);
37 if (chainedEffect_) {
38 chainedEffect_->Attach(context, activeTransition);
39 }
40 }
41
Detach(RosenRenderContext * context)42 void RosenTransitionEffect::Detach(RosenRenderContext* context)
43 {
44 OnDetach(context);
45 if (chainedEffect_) {
46 chainedEffect_->Detach(context);
47 }
48 }
49
50 // Updates the transition context
UpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)51 void RosenTransitionEffect::UpdateTransitionContext(
52 const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
53 {
54 OnUpdateTransitionContext(context, selfRect, viewSize);
55 if (chainedEffect_) {
56 chainedEffect_->UpdateTransitionContext(context, selfRect, viewSize);
57 }
58 }
59
60 // Disappears with animation option if activeTransition is true
Disappear(bool activeTransition)61 void RosenTransitionEffect::Disappear(bool activeTransition)
62 {
63 ApplyAnimationOption(
64 [this, activeTransition]() {
65 OnDisappear(activeTransition);
66 if (chainedEffect_) {
67 chainedEffect_->Disappear(activeTransition);
68 }
69 },
70 activeTransition);
71 }
72
73 // Appears with animation option
Appear()74 void RosenTransitionEffect::Appear()
75 {
76 ApplyAnimationOption([this]() {
77 OnAppear();
78 if (chainedEffect_) {
79 chainedEffect_->Appear();
80 }
81 });
82 }
83
84 // Combines with another effect
CombineWith(const RefPtr<RosenTransitionEffect> & effect)85 void RosenTransitionEffect::CombineWith(const RefPtr<RosenTransitionEffect>& effect)
86 {
87 chainedEffect_ = effect;
88 }
89
SetAnimationOption(const std::shared_ptr<AnimationOption> & option)90 void RosenTransitionEffect::SetAnimationOption(const std::shared_ptr<AnimationOption>& option)
91 {
92 animationOption_ = option;
93 }
94
95 // Applies the animation option if needed
ApplyAnimationOption(const std::function<void ()> & func,bool withAnimation)96 void RosenTransitionEffect::ApplyAnimationOption(const std::function<void()>& func, bool withAnimation)
97 {
98 // If there is no animation option or animation is disabled, just call func directly
99 if (withAnimation == false || animationOption_ == nullptr) {
100 func();
101 return;
102 }
103 // Update animation option and reuse the finish callback (the callback in animationOption will be ignored)
104 AnimationUtils::AnimateWithCurrentCallback(*animationOption_, [&func]() { func(); });
105 }
106
107 // Converts ChainedTransitionEffect to RosenTransitionEffect
ConvertToRosenTransitionEffect(const RefPtr<NG::ChainedTransitionEffect> & effect)108 RefPtr<RosenTransitionEffect> RosenTransitionEffect::ConvertToRosenTransitionEffect(
109 const RefPtr<NG::ChainedTransitionEffect>& effect)
110 {
111 RefPtr<RosenTransitionEffect> res;
112 RefPtr<RosenTransitionEffect> tailRSEffect;
113 RefPtr<ChainedTransitionEffect> currentEffect = effect;
114 while (currentEffect) {
115 RefPtr<RosenTransitionEffect> currentRSEffect;
116 switch (currentEffect->GetType()) {
117 case ChainedTransitionEffectType::IDENTITY: {
118 currentRSEffect = AceType::MakeRefPtr<RosenIdentityTransitionEffect>();
119 break;
120 }
121 case ChainedTransitionEffectType::OPACITY: {
122 auto opacityEffect = AceType::DynamicCast<ChainedOpacityEffect>(currentEffect);
123 auto opacity = opacityEffect->GetEffect();
124 currentRSEffect = AceType::MakeRefPtr<RosenOpacityTransitionEffect>(1.0f, opacity);
125 break;
126 }
127 case ChainedTransitionEffectType::MOVE: {
128 auto moveEffect = AceType::DynamicCast<ChainedMoveEffect>(currentEffect);
129 const auto& edge = moveEffect->GetEffect();
130 currentRSEffect = AceType::MakeRefPtr<RosenMoveTransitionEffect>(edge);
131 break;
132 }
133 case ChainedTransitionEffectType::ROTATE: {
134 auto rotateEffect = AceType::DynamicCast<ChainedRotateEffect>(currentEffect);
135 const auto& rotateOption = rotateEffect->GetEffect();
136 currentRSEffect = AceType::MakeRefPtr<RosenRotation3DTransitionEffect>(rotateOption);
137 break;
138 }
139 case ChainedTransitionEffectType::SCALE: {
140 auto scaleEffect = AceType::DynamicCast<ChainedScaleEffect>(currentEffect);
141 const auto& scaleOption = scaleEffect->GetEffect();
142 // Scale z is not considered
143 currentRSEffect = AceType::MakeRefPtr<RosenScaleTransitionEffect>(scaleOption);
144 break;
145 }
146 case ChainedTransitionEffectType::TRANSLATE: {
147 auto translateEffect = AceType::DynamicCast<ChainedTranslateEffect>(currentEffect);
148 const auto& translateOption = translateEffect->GetEffect();
149 currentRSEffect = AceType::MakeRefPtr<RosenTranslateTransitionEffect>(translateOption);
150 break;
151 }
152 case ChainedTransitionEffectType::ASYMMETRIC: {
153 auto asymmetricEffect = AceType::DynamicCast<ChainedAsymmetricEffect>(currentEffect);
154 auto rsAppearTransition = ConvertToRosenTransitionEffect(asymmetricEffect->GetAppearEffect());
155 auto rsDisappearTransition = ConvertToRosenTransitionEffect(asymmetricEffect->GetDisappearEffect());
156 currentRSEffect =
157 AceType::MakeRefPtr<RosenAsymmetricTransitionEffect>(rsAppearTransition, rsDisappearTransition);
158 break;
159 }
160 case ChainedTransitionEffectType::SLIDE_SWITCH: {
161 currentRSEffect = AceType::MakeRefPtr<RosenSlideSwitchTransitionEffect>();
162 break;
163 }
164 default: {
165 return res;
166 }
167 }
168 currentRSEffect->SetAnimationOption(currentEffect->GetAnimationOption());
169 if (tailRSEffect) {
170 tailRSEffect->CombineWith(currentRSEffect);
171 } else {
172 res = currentRSEffect;
173 }
174 tailRSEffect = currentRSEffect;
175 currentEffect = currentEffect->GetNext();
176 }
177 return res;
178 }
179
180 // Update RosenTransitionEffect in place, return false if structure is not matched
UpdateRosenTransitionEffect(const RefPtr<RosenTransitionEffect> & rosenEffect,const RefPtr<ChainedTransitionEffect> & chainedEffect)181 bool RosenTransitionEffect::UpdateRosenTransitionEffect(
182 const RefPtr<RosenTransitionEffect>& rosenEffect, const RefPtr<ChainedTransitionEffect>& chainedEffect)
183 {
184 if (!chainedEffect && !rosenEffect) {
185 return true;
186 }
187 auto nowEffect = chainedEffect;
188 auto nowRSEffect = rosenEffect;
189 while (nowEffect) {
190 CHECK_NULL_RETURN(nowRSEffect, false);
191 switch (nowEffect->GetType()) {
192 case ChainedTransitionEffectType::IDENTITY: {
193 if (!AceType::InstanceOf<RosenIdentityTransitionEffect>(nowRSEffect)) {
194 return false;
195 }
196 break;
197 }
198 case ChainedTransitionEffectType::OPACITY: {
199 auto rosenOpacityEffect = AceType::DynamicCast<RosenOpacityTransitionEffect>(nowRSEffect);
200 if (!rosenOpacityEffect) {
201 return false;
202 }
203 auto opacityEffect = AceType::DynamicCast<ChainedOpacityEffect>(nowEffect);
204 rosenOpacityEffect->SetActiveValue(opacityEffect->GetEffect());
205 break;
206 }
207 case ChainedTransitionEffectType::MOVE: {
208 auto rosenMoveEffect = AceType::DynamicCast<RosenMoveTransitionEffect>(nowRSEffect);
209 if (!rosenMoveEffect) {
210 return false;
211 }
212 auto moveEffect = AceType::DynamicCast<ChainedMoveEffect>(nowEffect);
213 rosenMoveEffect->SetMoveEffect(moveEffect->GetEffect());
214 break;
215 }
216 case ChainedTransitionEffectType::ROTATE: {
217 auto rosenRotateEffect = AceType::DynamicCast<RosenRotation3DTransitionEffect>(nowRSEffect);
218 if (!rosenRotateEffect) {
219 return false;
220 }
221 auto rotateEffect = AceType::DynamicCast<ChainedRotateEffect>(nowEffect);
222 rosenRotateEffect->SetRotateEffect(rotateEffect->GetEffect());
223 break;
224 }
225 case ChainedTransitionEffectType::SCALE: {
226 auto rosenScaleEffect = AceType::DynamicCast<RosenScaleTransitionEffect>(nowRSEffect);
227 if (!rosenScaleEffect) {
228 return false;
229 }
230 auto scaleEffect = AceType::DynamicCast<ChainedScaleEffect>(nowEffect);
231 rosenScaleEffect->SetScaleEffect(scaleEffect->GetEffect());
232 break;
233 }
234 case ChainedTransitionEffectType::TRANSLATE: {
235 auto rosenTranslateEffect = AceType::DynamicCast<RosenTranslateTransitionEffect>(nowRSEffect);
236 if (!rosenTranslateEffect) {
237 return false;
238 }
239 auto translateEffect = AceType::DynamicCast<ChainedTranslateEffect>(nowEffect);
240 rosenTranslateEffect->SetTranslateEffect(translateEffect->GetEffect());
241 break;
242 }
243 case ChainedTransitionEffectType::ASYMMETRIC: {
244 auto rosenAsymmetricEffect = AceType::DynamicCast<RosenAsymmetricTransitionEffect>(nowRSEffect);
245 if (!rosenAsymmetricEffect) {
246 return false;
247 }
248 auto asymmetricEffect = AceType::DynamicCast<ChainedAsymmetricEffect>(nowEffect);
249 if (!UpdateRosenTransitionEffect(
250 rosenAsymmetricEffect->GetTransitionInEffect(), asymmetricEffect->GetAppearEffect())) {
251 return false;
252 }
253 if (!UpdateRosenTransitionEffect(
254 rosenAsymmetricEffect->GetTransitionOutEffect(), asymmetricEffect->GetDisappearEffect())) {
255 return false;
256 }
257 break;
258 }
259 case ChainedTransitionEffectType::SLIDE_SWITCH: {
260 if (!AceType::InstanceOf<RosenSlideSwitchTransitionEffect>(nowRSEffect)) {
261 return false;
262 }
263 break;
264 }
265 default: {
266 return false;
267 }
268 }
269 nowRSEffect->SetAnimationOption(nowEffect->GetAnimationOption());
270 nowRSEffect = nowRSEffect->chainedEffect_;
271 nowEffect = nowEffect->GetNext();
272 }
273 // All effects are updated correctly
274 return nowRSEffect == nullptr;
275 }
276
277 // Identity animation option, with duration 0 and delay 0.
278 static const auto identityOption = std::make_shared<AnimationOption>();
RosenIdentityTransitionEffect()279 RosenIdentityTransitionEffect::RosenIdentityTransitionEffect() : RosenTransitionEffect()
280 {
281 // Identity transition effect comes with default identity animation option.
282 RosenTransitionEffect::SetAnimationOption(identityOption);
283 }
284
285 template<typename Modifier, typename PropertyType>
SetIdentityValue(PropertyType identityValue)286 void PropertyTransitionEffectTemplate<Modifier, PropertyType>::SetIdentityValue(PropertyType identityValue)
287 {
288 identityValue_ = identityValue;
289 if (!isActive_) {
290 property_->Set(identityValue_);
291 }
292 }
293
294 template<typename Modifier, typename PropertyType>
SetActiveValue(PropertyType activeValue)295 void PropertyTransitionEffectTemplate<Modifier, PropertyType>::SetActiveValue(PropertyType activeValue)
296 {
297 activeValue_ = activeValue;
298 if (isActive_) {
299 property_->Set(activeValue_);
300 }
301 }
302
303 template<typename Modifier, typename PropertyType>
OnAttach(const RefPtr<RosenRenderContext> & context,bool activeTransition)304 void PropertyTransitionEffectTemplate<Modifier, PropertyType>::OnAttach(
305 const RefPtr<RosenRenderContext>& context, bool activeTransition)
306 {
307 // record the current status
308 isActive_ = activeTransition;
309 if (modifier_ != nullptr) {
310 property_->Set(activeTransition ? activeValue_ : identityValue_);
311 return;
312 }
313
314 // create the property corresponding to current status
315 property_ =
316 std::make_shared<Rosen::RSAnimatableProperty<PropertyType>>(activeTransition ? activeValue_ : identityValue_);
317 // create the modifier and attach it to the context
318 modifier_ = std::make_shared<Modifier>(property_);
319 context->AddModifier(modifier_);
320 }
321
322 template<typename Modifier, typename PropertyType>
OnDetach(RosenRenderContext * context)323 void PropertyTransitionEffectTemplate<Modifier, PropertyType>::OnDetach(RosenRenderContext* context)
324 {
325 // remove the modifier
326 context->RemoveModifier(modifier_);
327 property_.reset();
328 modifier_.reset();
329 }
330
SetPivot(const Dimension & centerX,const Dimension & centerY,const Dimension & centerZ)331 void RosenPivotTransitionEffect::SetPivot(const Dimension& centerX, const Dimension& centerY, const Dimension& centerZ)
332 {
333 centerX_ = centerX;
334 centerY_ = centerY;
335 centerZ_ = centerZ;
336 }
337
RosenPivotTransitionEffect(const Dimension & centerX,const Dimension & centerY,const Dimension & centerZ)338 RosenPivotTransitionEffect::RosenPivotTransitionEffect(
339 const Dimension& centerX, const Dimension& centerY, const Dimension& centerZ)
340 : centerX_(centerX), centerY_(centerY), centerZ_(centerZ)
341 {}
342
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)343 void RosenPivotTransitionEffect::OnUpdateTransitionContext(
344 const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
345 {
346 // calculate and set the pivot
347 float xPivot = RosenRenderContext::ConvertDimensionToScaleBySize(centerX_, selfRect.Width());
348 float yPivot = RosenRenderContext::ConvertDimensionToScaleBySize(centerY_, selfRect.Height());
349 float zPivot = static_cast<float>(centerZ_.ConvertToPx());
350 context->SetPivot(xPivot, yPivot, zPivot);
351 }
352
RosenAsymmetricTransitionEffect(const RefPtr<RosenTransitionEffect> & transitionIn,const RefPtr<RosenTransitionEffect> & transitionOut)353 RosenAsymmetricTransitionEffect::RosenAsymmetricTransitionEffect(
354 const RefPtr<RosenTransitionEffect>& transitionIn, const RefPtr<RosenTransitionEffect>& transitionOut)
355 : transitionIn_(transitionIn), transitionOut_(transitionOut)
356 {}
357
SetTransitionInEffect(const RefPtr<RosenTransitionEffect> & transitionIn)358 void RosenAsymmetricTransitionEffect::SetTransitionInEffect(const RefPtr<RosenTransitionEffect>& transitionIn)
359 {
360 transitionIn_ = transitionIn;
361 }
362
SetTransitionOutEffect(const RefPtr<RosenTransitionEffect> & transitionOut)363 void RosenAsymmetricTransitionEffect::SetTransitionOutEffect(const RefPtr<RosenTransitionEffect>& transitionOut)
364 {
365 transitionOut_ = transitionOut;
366 }
367
OnAttach(const RefPtr<RosenRenderContext> & context,bool activeTransition)368 void RosenAsymmetricTransitionEffect::OnAttach(const RefPtr<RosenRenderContext>& context, bool activeTransition)
369 {
370 // upon attach, we should only trigger the transitionIn_ branch if activeTransition is true.
371 if (transitionIn_) {
372 transitionIn_->Attach(context, activeTransition);
373 }
374 if (transitionOut_) {
375 transitionOut_->Attach(context, false);
376 }
377 }
378
OnDetach(RosenRenderContext * context)379 void RosenAsymmetricTransitionEffect::OnDetach(RosenRenderContext* context)
380 {
381 if (transitionIn_) {
382 transitionIn_->Detach(context);
383 }
384 if (transitionOut_) {
385 transitionOut_->Detach(context);
386 }
387 }
388
OnAppear()389 void RosenAsymmetricTransitionEffect::OnAppear()
390 {
391 // upon node appear & reappear, we should trigger all transitions
392 if (transitionIn_ != nullptr) {
393 transitionIn_->Appear();
394 }
395 if (transitionOut_ != nullptr) {
396 transitionOut_->Appear();
397 }
398 }
399
OnDisappear(bool activeTransition)400 void RosenAsymmetricTransitionEffect::OnDisappear(bool activeTransition)
401 {
402 // upon node disappear, we should only trigger the transitionOut branch
403 if (transitionIn_) {
404 transitionIn_->Disappear(false);
405 }
406 if (transitionOut_) {
407 transitionOut_->Disappear(activeTransition);
408 }
409 }
410
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)411 void RosenAsymmetricTransitionEffect::OnUpdateTransitionContext(
412 const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
413 {
414 if (transitionIn_) {
415 transitionIn_->UpdateTransitionContext(context, selfRect, viewSize);
416 }
417 if (transitionOut_) {
418 transitionOut_->UpdateTransitionContext(context, selfRect, viewSize);
419 }
420 }
421
HasDisappearTransition() const422 bool RosenAsymmetricTransitionEffect::HasDisappearTransition() const
423 {
424 return transitionOut_ && transitionOut_->HasDisappearTransition();
425 }
426
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)427 void RosenTranslateTransitionEffect::OnUpdateTransitionContext(
428 const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
429 {
430 // translate dimension to pixel, and update active value
431 float translateX = translateValue_.x.ConvertToPxWithSize(selfRect.Width());
432 float translateY = translateValue_.y.ConvertToPxWithSize(selfRect.Height());
433 float translateZ = translateValue_.z.ConvertToPx();
434 std::get<InternalTranslateEffect>(effects_).SetActiveValue({ translateX, translateY });
435 std::get<InternalTranslateZEffect>(effects_).SetActiveValue(translateZ);
436 }
437
SetTranslateEffect(const TranslateOptions & option)438 void RosenTranslateTransitionEffect::SetTranslateEffect(const TranslateOptions& option)
439 {
440 translateValue_ = option;
441 }
442
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)443 void RosenMoveTransitionEffect::OnUpdateTransitionContext(
444 const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
445 {
446 // move node to the edge of the view
447 Rosen::Vector2f value { 0.0f, 0.0f };
448 switch (edge_) {
449 case TransitionEdge::TOP: {
450 value[1] = -selfRect.Bottom();
451 break;
452 }
453 case TransitionEdge::BOTTOM: {
454 value[1] = viewSize.Height() - selfRect.Top();
455 break;
456 }
457 case TransitionEdge::START: {
458 if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
459 value[0] = viewSize.Width() - selfRect.Left();
460 break;
461 }
462 value[0] = -selfRect.Right();
463 break;
464 }
465 case TransitionEdge::END: {
466 if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
467 value[0] = -selfRect.Right();
468 break;
469 }
470 value[0] = viewSize.Width() - selfRect.Left();
471 break;
472 }
473 default: {
474 break;
475 }
476 }
477 SetActiveValue(value);
478 }
479
SetMoveEffect(TransitionEdge edge)480 void RosenMoveTransitionEffect::SetMoveEffect(TransitionEdge edge)
481 {
482 edge_ = edge;
483 }
484
RosenAsyncMoveTransitionEffect(TransitionEdge inEdge,TransitionEdge outEdge)485 RosenAsyncMoveTransitionEffect ::RosenAsyncMoveTransitionEffect(TransitionEdge inEdge, TransitionEdge outEdge)
486 : RosenAsymmetricTransitionEffect(
487 MakeRefPtr<RosenMoveTransitionEffect>(inEdge), MakeRefPtr<RosenMoveTransitionEffect>(outEdge))
488 {}
489
RosenSlideTransitionEffect()490 RosenSlideTransitionEffect::RosenSlideTransitionEffect()
491 : RosenSlideTransitionEffect(TransitionEdge::END, TransitionEdge::START)
492 {}
493
RosenSlideTransitionEffect(TransitionEdge inEdge,TransitionEdge outEdge)494 RosenSlideTransitionEffect::RosenSlideTransitionEffect(TransitionEdge inEdge, TransitionEdge outEdge)
495 : RosenAsymmetricTransitionEffect(MakeRefPtr<InternalTranslateEffect>(), MakeRefPtr<InternalTranslateEffect>()),
496 inEdge_(inEdge), outEdge_(outEdge)
497 {}
498
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)499 void RosenSlideTransitionEffect ::OnUpdateTransitionContext(
500 const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
501 {
502 DynamicCast<InternalTranslateEffect>(transitionIn_)->SetActiveValue(GetTranslateValue(inEdge_, selfRect));
503 DynamicCast<InternalTranslateEffect>(transitionOut_)->SetActiveValue(GetTranslateValue(outEdge_, selfRect));
504 }
505
506 // convert the transition edge to the corresponding translate value
GetTranslateValue(TransitionEdge edge,const RectF & rect)507 Rosen::Vector2f RosenSlideTransitionEffect::GetTranslateValue(TransitionEdge edge, const RectF& rect)
508 {
509 switch (edge) {
510 case TransitionEdge::START:
511 return { -rect.Width(), 0.0f };
512 case TransitionEdge::END:
513 return { rect.Width(), 0.0f };
514 case TransitionEdge::TOP:
515 return { 0.0f, -rect.Height() };
516 case TransitionEdge::BOTTOM:
517 return { 0.0f, rect.Height() };
518 default:
519 return { 0.0f, 0.0f };
520 }
521 }
522
RosenRotation3DTransitionEffect(const RotateOptions & options)523 RosenRotation3DTransitionEffect::RosenRotation3DTransitionEffect(const RotateOptions& options)
524 : RosenCompositeTransitionEffect()
525 {
526 SetRotateEffect(options);
527 }
528
SetRotateEffect(const RotateOptions & options)529 void RosenRotation3DTransitionEffect::SetRotateEffect(const RotateOptions& options)
530 {
531 auto norm = static_cast<float>(
532 std::sqrt(std::pow(options.xDirection, 2) + std::pow(options.yDirection, 2) + std::pow(options.zDirection, 2)));
533 if (NearZero(norm)) {
534 norm = 1.0f;
535 }
536 // for rosen backend, the rotation angles in the x and y directions should be set to opposite angles
537 std::get<InternalRotationXEffect>(effects_).SetActiveValue(-options.angle * options.xDirection / norm);
538 std::get<InternalRotationYEffect>(effects_).SetActiveValue(-options.angle * options.yDirection / norm);
539 std::get<InternalRotationZEffect>(effects_).SetActiveValue(options.angle * options.zDirection / norm);
540 std::get<RosenPivotTransitionEffect>(effects_).SetPivot(options.centerX, options.centerY, options.centerZ);
541 }
542
RosenScaleTransitionEffect(const ScaleOptions & options)543 RosenScaleTransitionEffect::RosenScaleTransitionEffect(const ScaleOptions& options)
544 {
545 SetScaleEffect(options);
546 }
547
SetScaleEffect(const ScaleOptions & options)548 void RosenScaleTransitionEffect::SetScaleEffect(const ScaleOptions& options)
549 {
550 std::get<InternalScaleEffect>(effects_).SetActiveValue({ options.xScale, options.yScale });
551 std::get<RosenPivotTransitionEffect>(effects_).SetPivot(options.centerX, options.centerY);
552 }
553
554 template<>
PropertyTransitionEffectTemplate()555 RosenOpacityTransitionEffect::PropertyTransitionEffectTemplate() : identityValue_(1.0f), activeValue_(0.0f)
556 {}
557
558 template<>
PropertyTransitionEffectTemplate()559 InternalRotationXEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
560 {}
561
562 template<>
PropertyTransitionEffectTemplate()563 InternalRotationYEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
564 {}
565
566 template<>
PropertyTransitionEffectTemplate()567 InternalRotationZEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
568 {}
569
570 template<>
PropertyTransitionEffectTemplate()571 InternalTranslateEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f, 0.0f), activeValue_(0.0f, 0.0f)
572 {}
573
574 template<>
PropertyTransitionEffectTemplate()575 InternalTranslateZEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
576 {}
577
578 template<>
PropertyTransitionEffectTemplate()579 InternalScaleEffect::PropertyTransitionEffectTemplate() : identityValue_(1.0f, 1.0f), activeValue_(1.0f, 1.0f)
580 {}
581
CreateDefaultRosenTransitionEffect()582 RefPtr<RosenTransitionEffect> RosenTransitionEffect::CreateDefaultRosenTransitionEffect()
583 {
584 return AceType::MakeRefPtr<RosenOpacityTransitionEffect>();
585 }
586
RosenSlideSwitchTransitionEffect()587 RosenSlideSwitchTransitionEffect::RosenSlideSwitchTransitionEffect()
588 {
589 std::get<InternalScaleEffect>(effects_).SetKeyframes(SLIDE_SWITCH_KEYFRAMES);
590 SetAnimationOption(SLIDE_SWITCH_DEFAULT_OPTION);
591 }
592
SetAnimationOption(const std::shared_ptr<AnimationOption> & option)593 void RosenSlideSwitchTransitionEffect::SetAnimationOption(const std::shared_ptr<AnimationOption>& option)
594 {
595 RosenTransitionEffect::SetAnimationOption(option ? option : SLIDE_SWITCH_DEFAULT_OPTION);
596 }
597 } // namespace OHOS::Ace::NG
598