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