• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, RSPropertyType PropertyType, typename ValueType>
SetIdentityValue(ValueType identityValue)286 void PropertyTransitionEffectTemplate<Modifier, PropertyType, ValueType>::SetIdentityValue(ValueType identityValue)
287 {
288     identityValue_ = identityValue;
289     if (!isActive_) {
290         property_->Set(identityValue_);
291     }
292 }
293 
294 template<typename Modifier, RSPropertyType PropertyType, typename ValueType>
SetActiveValue(ValueType activeValue)295 void PropertyTransitionEffectTemplate<Modifier, PropertyType, ValueType>::SetActiveValue(ValueType activeValue)
296 {
297     activeValue_ = activeValue;
298     if (isActive_) {
299         property_->Set(activeValue_);
300     }
301 }
302 
303 template<typename Modifier, RSPropertyType PropertyType, typename ValueType>
OnAttach(const RefPtr<RosenRenderContext> & context,bool activeTransition)304 void PropertyTransitionEffectTemplate<Modifier, PropertyType, ValueType>::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<ValueType>>(activeTransition ? activeValue_ : identityValue_);
317     // create the modifier and attach it to the context
318     modifier_ = std::make_shared<Modifier>();
319     modifier_->AttachProperty(PropertyType, property_);
320     context->AddModifier(modifier_);
321 }
322 
323 template<typename Modifier, RSPropertyType PropertyType, typename ValueType>
OnDetach(RosenRenderContext * context)324 void PropertyTransitionEffectTemplate<Modifier, PropertyType, ValueType>::OnDetach(RosenRenderContext* context)
325 {
326     // remove the modifier
327     context->RemoveModifier(modifier_);
328     property_.reset();
329     modifier_.reset();
330 }
331 
SetPivot(const Dimension & centerX,const Dimension & centerY,const Dimension & centerZ)332 void RosenPivotTransitionEffect::SetPivot(const Dimension& centerX, const Dimension& centerY, const Dimension& centerZ)
333 {
334     centerX_ = centerX;
335     centerY_ = centerY;
336     centerZ_ = centerZ;
337 }
338 
RosenPivotTransitionEffect(const Dimension & centerX,const Dimension & centerY,const Dimension & centerZ)339 RosenPivotTransitionEffect::RosenPivotTransitionEffect(
340     const Dimension& centerX, const Dimension& centerY, const Dimension& centerZ)
341     : centerX_(centerX), centerY_(centerY), centerZ_(centerZ)
342 {}
343 
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)344 void RosenPivotTransitionEffect::OnUpdateTransitionContext(
345     const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
346 {
347     // calculate and set the pivot
348     float xPivot = RosenRenderContext::ConvertDimensionToScaleBySize(centerX_, selfRect.Width());
349     float yPivot = RosenRenderContext::ConvertDimensionToScaleBySize(centerY_, selfRect.Height());
350     float zPivot = static_cast<float>(centerZ_.ConvertToPx());
351     context->SetPivot(xPivot, yPivot, zPivot);
352 }
353 
RosenAsymmetricTransitionEffect(const RefPtr<RosenTransitionEffect> & transitionIn,const RefPtr<RosenTransitionEffect> & transitionOut)354 RosenAsymmetricTransitionEffect::RosenAsymmetricTransitionEffect(
355     const RefPtr<RosenTransitionEffect>& transitionIn, const RefPtr<RosenTransitionEffect>& transitionOut)
356     : transitionIn_(transitionIn), transitionOut_(transitionOut)
357 {}
358 
SetTransitionInEffect(const RefPtr<RosenTransitionEffect> & transitionIn)359 void RosenAsymmetricTransitionEffect::SetTransitionInEffect(const RefPtr<RosenTransitionEffect>& transitionIn)
360 {
361     transitionIn_ = transitionIn;
362 }
363 
SetTransitionOutEffect(const RefPtr<RosenTransitionEffect> & transitionOut)364 void RosenAsymmetricTransitionEffect::SetTransitionOutEffect(const RefPtr<RosenTransitionEffect>& transitionOut)
365 {
366     transitionOut_ = transitionOut;
367 }
368 
OnAttach(const RefPtr<RosenRenderContext> & context,bool activeTransition)369 void RosenAsymmetricTransitionEffect::OnAttach(const RefPtr<RosenRenderContext>& context, bool activeTransition)
370 {
371     // upon attach, we should only trigger the transitionIn_ branch if activeTransition is true.
372     if (transitionIn_) {
373         transitionIn_->Attach(context, activeTransition);
374     }
375     if (transitionOut_) {
376         transitionOut_->Attach(context, false);
377     }
378 }
379 
OnDetach(RosenRenderContext * context)380 void RosenAsymmetricTransitionEffect::OnDetach(RosenRenderContext* context)
381 {
382     if (transitionIn_) {
383         transitionIn_->Detach(context);
384     }
385     if (transitionOut_) {
386         transitionOut_->Detach(context);
387     }
388 }
389 
OnAppear()390 void RosenAsymmetricTransitionEffect::OnAppear()
391 {
392     // upon node appear & reappear, we should trigger all transitions
393     if (transitionIn_ != nullptr) {
394         transitionIn_->Appear();
395     }
396     if (transitionOut_ != nullptr) {
397         transitionOut_->Appear();
398     }
399 }
400 
OnDisappear(bool activeTransition)401 void RosenAsymmetricTransitionEffect::OnDisappear(bool activeTransition)
402 {
403     // upon node disappear, we should only trigger the transitionOut branch
404     if (transitionIn_) {
405         transitionIn_->Disappear(false);
406     }
407     if (transitionOut_) {
408         transitionOut_->Disappear(activeTransition);
409     }
410 }
411 
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)412 void RosenAsymmetricTransitionEffect::OnUpdateTransitionContext(
413     const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
414 {
415     if (transitionIn_) {
416         transitionIn_->UpdateTransitionContext(context, selfRect, viewSize);
417     }
418     if (transitionOut_) {
419         transitionOut_->UpdateTransitionContext(context, selfRect, viewSize);
420     }
421 }
422 
HasDisappearTransition() const423 bool RosenAsymmetricTransitionEffect::HasDisappearTransition() const
424 {
425     return transitionOut_ && transitionOut_->HasDisappearTransition();
426 }
427 
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)428 void RosenTranslateTransitionEffect::OnUpdateTransitionContext(
429     const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
430 {
431     // translate dimension to pixel, and update active value
432     float translateX = translateValue_.x.ConvertToPxWithSize(selfRect.Width());
433     float translateY = translateValue_.y.ConvertToPxWithSize(selfRect.Height());
434     float translateZ = translateValue_.z.ConvertToPx();
435     std::get<InternalTranslateEffect>(effects_).SetActiveValue({ translateX, translateY });
436     std::get<InternalTranslateZEffect>(effects_).SetActiveValue(translateZ);
437 }
438 
SetTranslateEffect(const TranslateOptions & option)439 void RosenTranslateTransitionEffect::SetTranslateEffect(const TranslateOptions& option)
440 {
441     translateValue_ = option;
442 }
443 
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)444 void RosenMoveTransitionEffect::OnUpdateTransitionContext(
445     const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
446 {
447     // move node to the edge of the view
448     Rosen::Vector2f value { 0.0f, 0.0f };
449     switch (edge_) {
450         case TransitionEdge::TOP: {
451             value[1] = -selfRect.Bottom();
452             break;
453         }
454         case TransitionEdge::BOTTOM: {
455             value[1] = viewSize.Height() - selfRect.Top();
456             break;
457         }
458         case TransitionEdge::START: {
459             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
460                 value[0] = viewSize.Width() - selfRect.Left();
461                 break;
462             }
463             value[0] = -selfRect.Right();
464             break;
465         }
466         case TransitionEdge::END: {
467             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
468                 value[0] = -selfRect.Right();
469                 break;
470             }
471             value[0] = viewSize.Width() - selfRect.Left();
472             break;
473         }
474         default: {
475             break;
476         }
477     }
478     SetActiveValue(value);
479 }
480 
SetMoveEffect(TransitionEdge edge)481 void RosenMoveTransitionEffect::SetMoveEffect(TransitionEdge edge)
482 {
483     edge_ = edge;
484 }
485 
RosenAsyncMoveTransitionEffect(TransitionEdge inEdge,TransitionEdge outEdge)486 RosenAsyncMoveTransitionEffect ::RosenAsyncMoveTransitionEffect(TransitionEdge inEdge, TransitionEdge outEdge)
487     : RosenAsymmetricTransitionEffect(
488           MakeRefPtr<RosenMoveTransitionEffect>(inEdge), MakeRefPtr<RosenMoveTransitionEffect>(outEdge))
489 {}
490 
RosenSlideTransitionEffect()491 RosenSlideTransitionEffect::RosenSlideTransitionEffect()
492     : RosenSlideTransitionEffect(TransitionEdge::END, TransitionEdge::START)
493 {}
494 
RosenSlideTransitionEffect(TransitionEdge inEdge,TransitionEdge outEdge)495 RosenSlideTransitionEffect::RosenSlideTransitionEffect(TransitionEdge inEdge, TransitionEdge outEdge)
496     : RosenAsymmetricTransitionEffect(MakeRefPtr<InternalTranslateEffect>(), MakeRefPtr<InternalTranslateEffect>()),
497       inEdge_(inEdge), outEdge_(outEdge)
498 {}
499 
OnUpdateTransitionContext(const RefPtr<RosenRenderContext> & context,const RectF & selfRect,const SizeF & viewSize)500 void RosenSlideTransitionEffect ::OnUpdateTransitionContext(
501     const RefPtr<RosenRenderContext>& context, const RectF& selfRect, const SizeF& viewSize)
502 {
503     DynamicCast<InternalTranslateEffect>(transitionIn_)->SetActiveValue(GetTranslateValue(inEdge_, selfRect));
504     DynamicCast<InternalTranslateEffect>(transitionOut_)->SetActiveValue(GetTranslateValue(outEdge_, selfRect));
505 }
506 
507 // convert the transition edge to the corresponding translate value
GetTranslateValue(TransitionEdge edge,const RectF & rect)508 Rosen::Vector2f RosenSlideTransitionEffect::GetTranslateValue(TransitionEdge edge, const RectF& rect)
509 {
510     switch (edge) {
511         case TransitionEdge::START:
512             return { -rect.Width(), 0.0f };
513         case TransitionEdge::END:
514             return { rect.Width(), 0.0f };
515         case TransitionEdge::TOP:
516             return { 0.0f, -rect.Height() };
517         case TransitionEdge::BOTTOM:
518             return { 0.0f, rect.Height() };
519         default:
520             return { 0.0f, 0.0f };
521     }
522 }
523 
RosenRotation3DTransitionEffect(const RotateOptions & options)524 RosenRotation3DTransitionEffect::RosenRotation3DTransitionEffect(const RotateOptions& options)
525     : RosenCompositeTransitionEffect()
526 {
527     SetRotateEffect(options);
528 }
529 
SetRotateEffect(const RotateOptions & options)530 void RosenRotation3DTransitionEffect::SetRotateEffect(const RotateOptions& options)
531 {
532     auto norm = static_cast<float>(
533         std::sqrt(std::pow(options.xDirection, 2) + std::pow(options.yDirection, 2) + std::pow(options.zDirection, 2)));
534     if (NearZero(norm)) {
535         norm = 1.0f;
536     }
537     // for rosen backend, the rotation angles in the x and y directions should be set to opposite angles
538     std::get<InternalRotationXEffect>(effects_).SetActiveValue(-options.angle * options.xDirection / norm);
539     std::get<InternalRotationYEffect>(effects_).SetActiveValue(-options.angle * options.yDirection / norm);
540     std::get<InternalRotationZEffect>(effects_).SetActiveValue(options.angle * options.zDirection / norm);
541     std::get<RosenPivotTransitionEffect>(effects_).SetPivot(options.centerX, options.centerY, options.centerZ);
542 }
543 
RosenScaleTransitionEffect(const ScaleOptions & options)544 RosenScaleTransitionEffect::RosenScaleTransitionEffect(const ScaleOptions& options)
545 {
546     SetScaleEffect(options);
547 }
548 
SetScaleEffect(const ScaleOptions & options)549 void RosenScaleTransitionEffect::SetScaleEffect(const ScaleOptions& options)
550 {
551     std::get<InternalScaleEffect>(effects_).SetActiveValue({ options.xScale, options.yScale });
552     std::get<RosenPivotTransitionEffect>(effects_).SetPivot(options.centerX, options.centerY);
553 }
554 
555 template<>
PropertyTransitionEffectTemplate()556 RosenOpacityTransitionEffect::PropertyTransitionEffectTemplate() : identityValue_(1.0f), activeValue_(0.0f)
557 {}
558 
559 template<>
PropertyTransitionEffectTemplate()560 InternalRotationXEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
561 {}
562 
563 template<>
PropertyTransitionEffectTemplate()564 InternalRotationYEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
565 {}
566 
567 template<>
PropertyTransitionEffectTemplate()568 InternalRotationZEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
569 {}
570 
571 template<>
PropertyTransitionEffectTemplate()572 InternalTranslateEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f, 0.0f), activeValue_(0.0f, 0.0f)
573 {}
574 
575 template<>
PropertyTransitionEffectTemplate()576 InternalTranslateZEffect::PropertyTransitionEffectTemplate() : identityValue_(0.0f), activeValue_(0.0f)
577 {}
578 
579 template<>
PropertyTransitionEffectTemplate()580 InternalScaleEffect::PropertyTransitionEffectTemplate() : identityValue_(1.0f, 1.0f), activeValue_(1.0f, 1.0f)
581 {}
582 
CreateDefaultRosenTransitionEffect()583 RefPtr<RosenTransitionEffect> RosenTransitionEffect::CreateDefaultRosenTransitionEffect()
584 {
585     return AceType::MakeRefPtr<RosenOpacityTransitionEffect>();
586 }
587 
RosenSlideSwitchTransitionEffect()588 RosenSlideSwitchTransitionEffect::RosenSlideSwitchTransitionEffect()
589 {
590     std::get<InternalScaleEffect>(effects_).SetKeyframes(SLIDE_SWITCH_KEYFRAMES);
591     SetAnimationOption(SLIDE_SWITCH_DEFAULT_OPTION);
592 }
593 
SetAnimationOption(const std::shared_ptr<AnimationOption> & option)594 void RosenSlideSwitchTransitionEffect::SetAnimationOption(const std::shared_ptr<AnimationOption>& option)
595 {
596     RosenTransitionEffect::SetAnimationOption(option ? option : SLIDE_SWITCH_DEFAULT_OPTION);
597 }
598 } // namespace OHOS::Ace::NG
599