1 /*
2  * Copyright (c) 2021 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/common/properties/page_transition_option.h"
17 
18 namespace OHOS::Ace {
19 namespace {
20 
21 constexpr float TRANSITION_FACTOR = 0.8f;
22 constexpr float TRANSITION_FACTOR_IN = 0.5f;
23 constexpr float TRANSITION_FACTOR_OUT = 0.2f;
24 constexpr float BLACK_OPACITY = 0.3f;
25 constexpr float SHARED_TRANSITION_ENTER_START_OFFSET_X = 68.0f;
26 
CreateSharedInOption(bool isRightToLeft,double deviceViewScale,double deviceWidth,TweenOption & option)27 void CreateSharedInOption(bool isRightToLeft, double deviceViewScale, double deviceWidth, TweenOption& option)
28 {
29     // opacity. parameters only have local meaning, no need to define const variables.
30     auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f);   // start with invisible
31     auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.428f, 0.0f); // invisible at 42.8% of total duration
32     opacityKeyframe2->SetCurve(Curves::LINEAR);
33     auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // finally visible
34     opacityKeyframe3->SetCurve(Curves::FRICTION);
35     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
36     opacityAnimation->AddKeyframe(opacityKeyframe1);
37     opacityAnimation->AddKeyframe(opacityKeyframe2);
38     opacityAnimation->AddKeyframe(opacityKeyframe3);
39     option.SetOpacityAnimation(opacityAnimation);
40     // translate. parameters only have local meaning, no need to define const variables.
41     double startX = SHARED_TRANSITION_ENTER_START_OFFSET_X / deviceViewScale - deviceWidth;
42     double endX = 0.0;
43     if (isRightToLeft) {
44         startX = -1.0 * startX;
45         endX = 0.0;
46     }
47     auto translateXKeyframe1 =
48         AceType::MakeRefPtr<Keyframe<DimensionOffset>>(0.0f, Offset(startX, 0)); // start with startX
49     auto translateXKeyframe2 =
50         AceType::MakeRefPtr<Keyframe<DimensionOffset>>(0.428f, Offset(startX, 0)); // start at 42.8% of total duration
51     translateXKeyframe2->SetCurve(Curves::LINEAR);
52     auto translateXKeyframe3 = AceType::MakeRefPtr<Keyframe<DimensionOffset>>(1.0f, Offset(endX, 0)); // finally at endX
53     translateXKeyframe3->SetCurve(Curves::FRICTION);
54     auto translateXAnimation = AceType::MakeRefPtr<KeyframeAnimation<DimensionOffset>>();
55     translateXAnimation->AddKeyframe(translateXKeyframe1);
56     translateXAnimation->AddKeyframe(translateXKeyframe2);
57     translateXAnimation->AddKeyframe(translateXKeyframe3);
58     option.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateXAnimation);
59 }
60 
CreateSharedOutOption(TweenOption & option)61 void CreateSharedOutOption(TweenOption& option)
62 {
63     // opacity. parameters only have local meaning, no need to define const variables.
64     auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 1.0f);   // start with invisible
65     auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.714f, 0.0f); // invisible at 71.4% of total duration
66     opacityKeyframe2->SetCurve(Curves::FRICTION);
67     auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 0.0f); // finally visible
68     opacityKeyframe3->SetCurve(Curves::LINEAR);
69     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
70     opacityAnimation->AddKeyframe(opacityKeyframe1);
71     opacityAnimation->AddKeyframe(opacityKeyframe2);
72     opacityAnimation->AddKeyframe(opacityKeyframe3);
73     option.SetOpacityAnimation(opacityAnimation);
74 }
75 
76 // Follow Watch's UI Standard.
CreateSharedStaticOption(TweenOption & option)77 void CreateSharedStaticOption(TweenOption& option)
78 {
79     // opacity. parameters only have local meaning, no need to define const variables.
80     auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f);   // start with invisible
81     auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.428f, 0.0f); // invisible at 42.8% of total duration
82     opacityKeyframe2->SetCurve(Curves::LINEAR);
83     auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // finally visible
84     opacityKeyframe3->SetCurve(Curves::FRICTION);
85     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
86     opacityAnimation->AddKeyframe(opacityKeyframe1);
87     opacityAnimation->AddKeyframe(opacityKeyframe2);
88     opacityAnimation->AddKeyframe(opacityKeyframe3);
89     option.SetOpacityAnimation(opacityAnimation);
90 }
91 
92 } // namespace
93 
94 constexpr int32_t TRANSITION_PHONE_DURATION = 300; // 0.3s
95 constexpr int32_t TRANSITION_WATCH_DURATION = 300; // 0.3s
96 constexpr int32_t TRANSITION_TV_DURATION = 1000;   // 1s
97 constexpr double TRANSITION_DEFAULT_WIDTH = 750.0;
98 constexpr double TRANSITION_DEFAULT_HEIGHT = 1900.0;
99 constexpr double TRANSITION_DEFAULT_CORNER_RADIUS = 0.0;
100 
TransitionTweenOption(bool isRightToLeft,const WeakPtr<PipelineContext> & context)101 TransitionTweenOption::TransitionTweenOption(bool isRightToLeft, const WeakPtr<PipelineContext>& context)
102 {
103     auto pipelineContext = context.Upgrade();
104     if (pipelineContext) {
105         auto deviceWidth = pipelineContext->GetStageRect().Width();
106         deviceWidth_ = deviceWidth > 0.0 ? deviceWidth : deviceWidth_;
107         auto deviceHeight = pipelineContext->GetStageRect().Height();
108         deviceHeight_ = deviceHeight > 0.0 ? deviceHeight : deviceHeight_;
109         auto viewScale = pipelineContext->GetViewScale();
110         deviceViewScale_ = viewScale > 0.0 ? viewScale : deviceViewScale_;
111         isRightToLeft_ = isRightToLeft;
112         windowModal_ = pipelineContext->GetWindowModal();
113     }
114 }
115 
GetTransitionContentInOption() const116 const TweenOption& TransitionTweenOption::GetTransitionContentInOption() const
117 {
118     return contentInOption_;
119 }
120 
GetTransitionContentOutOption() const121 const TweenOption& TransitionTweenOption::GetTransitionContentOutOption() const
122 {
123     return contentOutOption_;
124 }
125 
GetTransitionBackgroundInOption() const126 const TweenOption& TransitionTweenOption::GetTransitionBackgroundInOption() const
127 {
128     return backgroundInOption_;
129 }
130 
GetTransitionBackgroundOutOption() const131 const TweenOption& TransitionTweenOption::GetTransitionBackgroundOutOption() const
132 {
133     return backgroundOutOption_;
134 }
135 
GetTransitionFrontDecorationOption() const136 const TweenOption& TransitionTweenOption::GetTransitionFrontDecorationOption() const
137 {
138     return frontDecorationOption_;
139 }
140 
GetSharedTransitionFrontDecorationOption() const141 const TweenOption& TransitionTweenOption::GetSharedTransitionFrontDecorationOption() const
142 {
143     return sharedFrontDecorationOption_;
144 }
145 
GetSharedInOption() const146 const TweenOption& TransitionTweenOption::GetSharedInOption() const
147 {
148     return sharedTransitionInOption_;
149 }
150 
GetSharedOutOption() const151 const TweenOption& TransitionTweenOption::GetSharedOutOption() const
152 {
153     return sharedTransitionOutOption_;
154 }
155 
TransitionTvTweenOption(bool isRightToLeft,const WeakPtr<PipelineContext> & context)156 TransitionTvTweenOption::TransitionTvTweenOption(bool isRightToLeft, const WeakPtr<PipelineContext>& context)
157     : TransitionTweenOption(isRightToLeft, context)
158 {
159     CreateTransitionInOption();
160     CreateTransitionOutOption();
161     // Currently, Tv Do not have UI standard, no need to create special shared transition.
162 }
163 
CreateTransitionInOption()164 void TransitionTvTweenOption::CreateTransitionInOption()
165 {
166     CreateTransitionInContentOption();
167     CreateTransitionInBackgroundOption();
168 }
169 
CreateTransitionInContentOption()170 void TransitionTvTweenOption::CreateTransitionInContentOption()
171 {
172     // content opacity. parameters only have local meaning, no need to define const variables.
173     auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f);  // start with invisible
174     auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.55f, 0.0f); // invisible at 55% of total duration
175     opacityKeyframe2->SetCurve(Curves::FRICTION);
176     auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // finally visible
177     opacityKeyframe3->SetCurve(Curves::FRICTION);
178     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
179     opacityAnimation->AddKeyframe(opacityKeyframe1);
180     opacityAnimation->AddKeyframe(opacityKeyframe2);
181     opacityAnimation->AddKeyframe(opacityKeyframe3);
182     contentInOption_.SetOpacityAnimation(opacityAnimation);
183 
184     // content scale. parameters only have local meaning, no need to define const variables.
185     auto scaleKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f);  // start with invisible
186     auto scaleKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.55f, 0.9f); // 90% scale at 55% of total duration
187     scaleKeyframe2->SetCurve(Curves::FRICTION);
188     auto scaleKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // finally 100% scale
189     scaleKeyframe3->SetCurve(Curves::FRICTION);
190     auto scaleAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
191     scaleAnimation->AddKeyframe(scaleKeyframe1);
192     scaleAnimation->AddKeyframe(scaleKeyframe2);
193     scaleAnimation->AddKeyframe(scaleKeyframe3);
194     contentInOption_.SetTransformFloatAnimation(AnimationType::SCALE, scaleAnimation);
195     contentInOption_.SetDuration(TRANSITION_TV_DURATION);
196 }
197 
CreateTransitionInBackgroundOption()198 void TransitionTvTweenOption::CreateTransitionInBackgroundOption()
199 {
200     // background opacity. parameters only have local meaning, no need to define const variables.
201     auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f); // start with invisible
202     auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.5f, 0.0f); // invisible at 50% of total duration
203     opacityKeyframe2->SetCurve(Curves::FRICTION);
204     auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(0.95f, 1.0f); // visible at 95% of total duration
205     opacityKeyframe3->SetCurve(Curves::FRICTION);
206     auto opacityKeyframe4 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // finally visible
207     opacityKeyframe4->SetCurve(Curves::FRICTION);
208     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
209     opacityAnimation->AddKeyframe(opacityKeyframe1);
210     opacityAnimation->AddKeyframe(opacityKeyframe2);
211     opacityAnimation->AddKeyframe(opacityKeyframe3);
212     opacityAnimation->AddKeyframe(opacityKeyframe4);
213     backgroundInOption_.SetOpacityAnimation(opacityAnimation);
214 
215     // background scale. parameters only have local meaning, no need to define const variables.
216     auto scaleKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f); // start with invisible
217     auto scaleKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.5f, 1.1f); // 110% scale at 50% of total duration
218     scaleKeyframe2->SetCurve(Curves::FRICTION);
219     auto scaleKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(0.95f, 1.0f); // 100% scale at 95% of total duration
220     scaleKeyframe3->SetCurve(Curves::FRICTION);
221     auto scaleKeyframe4 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // finally 100% scale
222     scaleKeyframe4->SetCurve(Curves::FRICTION);
223     auto scaleAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
224     scaleAnimation->AddKeyframe(scaleKeyframe1);
225     scaleAnimation->AddKeyframe(scaleKeyframe2);
226     scaleAnimation->AddKeyframe(scaleKeyframe3);
227     scaleAnimation->AddKeyframe(scaleKeyframe4);
228     backgroundInOption_.SetTransformFloatAnimation(AnimationType::SCALE, scaleAnimation);
229 }
230 
CreateTransitionOutOption()231 void TransitionTvTweenOption::CreateTransitionOutOption()
232 {
233     CreateTransitionOutContentOption();
234     CreateTransitionOutBackgroundOption();
235 }
236 
CreateTransitionOutContentOption()237 void TransitionTvTweenOption::CreateTransitionOutContentOption()
238 {
239     CreatTransitionOutOption(contentOutOption_);
240 }
241 
CreateTransitionOutBackgroundOption()242 void TransitionTvTweenOption::CreateTransitionOutBackgroundOption()
243 {
244     CreatTransitionOutOption(backgroundOutOption_);
245 }
246 
CreatTransitionOutOption(TweenOption & option)247 void TransitionTvTweenOption::CreatTransitionOutOption(TweenOption& option)
248 {
249     // out opacity. parameters only have local meaning, no need to define const variables.
250     auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 1.0f); // start with visible
251     auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.1f, 1.0f); // visible at 10% of total duration
252     opacityKeyframe2->SetCurve(Curves::FRICTION);
253     auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(0.55f, 0.0f); // invisible at 55% of total duration
254     opacityKeyframe3->SetCurve(Curves::FRICTION);
255     auto opacityKeyframe4 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 0.0f); // finally invisible
256     opacityKeyframe4->SetCurve(Curves::FRICTION);
257     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
258     opacityAnimation->AddKeyframe(opacityKeyframe1);
259     opacityAnimation->AddKeyframe(opacityKeyframe2);
260     opacityAnimation->AddKeyframe(opacityKeyframe3);
261     opacityAnimation->AddKeyframe(opacityKeyframe4);
262     option.SetOpacityAnimation(opacityAnimation);
263 
264     // out scale. parameters only have local meaning, no need to define const variables.
265     auto scaleKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 1.0f); // 100% scale at start
266     auto scaleKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.1f, 1.0f); // 100% scale at 10% of total duration
267     scaleKeyframe2->SetCurve(Curves::FRICTION);
268     auto scaleKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(0.55f, 1.1f); // 110% scale at 55% of total duration
269     scaleKeyframe3->SetCurve(Curves::FRICTION);
270     auto scaleKeyframe4 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f); // 100% scale at 100% of total duration
271     scaleKeyframe4->SetCurve(Curves::FRICTION);
272     auto scaleAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
273     scaleAnimation->AddKeyframe(scaleKeyframe1);
274     scaleAnimation->AddKeyframe(scaleKeyframe2);
275     scaleAnimation->AddKeyframe(scaleKeyframe3);
276     scaleAnimation->AddKeyframe(scaleKeyframe4);
277     option.SetTransformFloatAnimation(AnimationType::SCALE, scaleAnimation);
278     option.SetDuration(TRANSITION_TV_DURATION);
279 }
280 
CreateTransitionTweenOption(DeviceType deviceType,TransitionEvent event,bool isRightToLeft,const RRect & rrect,const WeakPtr<PipelineContext> & context)281 RefPtr<TransitionTweenOption> TransitionTweenOptionFactory::CreateTransitionTweenOption(
282     DeviceType deviceType, TransitionEvent event, bool isRightToLeft, const RRect& rrect,
283     const WeakPtr<PipelineContext>& context)
284 {
285     switch (deviceType) {
286         case DeviceType::PHONE:
287             if (rrect.GetRect().IsValid()) {
288                 return AceType::MakeRefPtr<TransitionPhoneTweenOption>(event, isRightToLeft, rrect, context);
289             }
290             return AceType::MakeRefPtr<TransitionPhoneTweenOption>(event, isRightToLeft, context);
291         case DeviceType::TV:
292             return AceType::MakeRefPtr<TransitionTvTweenOption>(isRightToLeft, context);
293         case DeviceType::WATCH:
294             return AceType::MakeRefPtr<TransitionWatchTweenOption>(event, isRightToLeft, context);
295         default:
296             LOGE("unknown transition type: %{public}d, use default type", deviceType);
297             return AceType::MakeRefPtr<TransitionPhoneTweenOption>(event, isRightToLeft, context);
298     }
299 }
300 
CreateSharedTweenOption(SharedTransitionEffectType type,TweenOption & option)301 void TransitionTweenOptionFactory::CreateSharedTweenOption(SharedTransitionEffectType type, TweenOption& option)
302 {
303     if (type == SharedTransitionEffectType::SHARED_EFFECT_STATIC) {
304         CreateSharedStaticOption(option);
305     } else {
306         LOGW("Unsupported Shared transition effect type: %{public}d", type);
307     }
308 }
309 
TransitionPhoneTweenOption(TransitionEvent event,bool isRightToLeft,const WeakPtr<PipelineContext> & context)310 TransitionPhoneTweenOption::TransitionPhoneTweenOption(
311     TransitionEvent event, bool isRightToLeft, const WeakPtr<PipelineContext>& context)
312     : TransitionTweenOption(isRightToLeft, context)
313 {
314     if (windowModal_ == WindowModal::DIALOG_MODAL) {
315         CreateDialogModalTransitionInOption(event);
316         CreateDialogModalTransitionOutOption(event);
317     } else {
318         CreateTransitionInOption(event);
319         CreateTransitionOutOption(event);
320     }
321     CreateSharedInOption(isRightToLeft_, deviceViewScale_, deviceWidth_, sharedTransitionInOption_);
322     CreateSharedOutOption(sharedTransitionOutOption_);
323     // extra options for phone
324     auto widthAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(deviceWidth_, deviceWidth_, Curves::FRICTION);
325     sharedTransitionOutOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, widthAnimation);
326 
327     auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
328         DimensionOffset(Offset()), DimensionOffset(Offset()), Curves::LINEAR);
329     sharedTransitionOutOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
330 
331     auto colorAnimation = AceType::MakeRefPtr<CurveAnimation<Color>>(
332         Color::FromRGBO(0, 0, 0, 0.0), Color::FromRGBO(0, 0, 0, 0.0), Curves::FRICTION);
333     sharedFrontDecorationOption_.SetColorAnimation(colorAnimation);
334     sharedFrontDecorationOption_.SetIsBackground(false);
335 }
336 
TransitionPhoneTweenOption(TransitionEvent event,bool isRightToLeft,const RRect & rrect,const WeakPtr<PipelineContext> & context)337 TransitionPhoneTweenOption::TransitionPhoneTweenOption(
338     TransitionEvent event, bool isRightToLeft, const RRect& rrect, const WeakPtr<PipelineContext>& context)
339     : TransitionTweenOption(isRightToLeft, context)
340 {
341     CreateCardTransitionInOption(event, rrect);
342     CreateCardTransitionOutOption(event);
343 
344     CreateSharedInOption(isRightToLeft_, deviceViewScale_, deviceWidth_, sharedTransitionInOption_);
345     CreateSharedOutOption(sharedTransitionOutOption_);
346     // extra options for phone
347     auto widthAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(deviceWidth_, deviceWidth_, Curves::FRICTION);
348     sharedTransitionOutOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, widthAnimation);
349 
350     auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
351         DimensionOffset(Offset()), DimensionOffset(Offset()), Curves::LINEAR);
352     sharedTransitionOutOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
353 
354     auto colorAnimation = AceType::MakeRefPtr<CurveAnimation<Color>>(
355         Color::FromRGBO(0, 0, 0, 0.0), Color::FromRGBO(0, 0, 0, 0.0), Curves::FRICTION);
356     sharedFrontDecorationOption_.SetColorAnimation(colorAnimation);
357     sharedFrontDecorationOption_.SetIsBackground(false);
358 }
359 
CreateDialogModalTransitionInOption(TransitionEvent event)360 void TransitionPhoneTweenOption::CreateDialogModalTransitionInOption(TransitionEvent event)
361 {
362     RefPtr<CurveAnimation<DimensionOffset>> translateAnimation;
363     if (isRightToLeft_) {
364         translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
365             DimensionOffset(Dimension(-deviceWidth_, DimensionUnit::PX), Dimension()),
366             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
367     } else {
368         translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
369             DimensionOffset(Dimension(deviceWidth_, DimensionUnit::PX), Dimension()),
370             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
371     }
372     contentInOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
373     contentInOption_.SetDuration(TRANSITION_PHONE_DURATION);
374 }
375 
CreateTransitionInOption(TransitionEvent event)376 void TransitionPhoneTweenOption::CreateTransitionInOption(TransitionEvent event)
377 {
378     if (isRightToLeft_) {
379         auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
380             DimensionOffset(Dimension(-deviceWidth_ * TRANSITION_FACTOR_IN, DimensionUnit::PX), Dimension()),
381             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
382         auto widthAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(
383             deviceWidth_ * TRANSITION_FACTOR_IN, deviceWidth_, Curves::FRICTION);
384         contentInOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, widthAnimation);
385         contentInOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
386     } else {
387         auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
388             DimensionOffset(Dimension(deviceWidth_ * TRANSITION_FACTOR_IN, DimensionUnit::PX), Dimension()),
389             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
390         auto offsetXAnimation =
391             AceType::MakeRefPtr<CurveAnimation<float>>(deviceWidth_ * TRANSITION_FACTOR_IN, 0.0f, Curves::FRICTION);
392         auto widthAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(deviceWidth_, deviceWidth_, Curves::LINEAR);
393         contentInOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, widthAnimation);
394         contentInOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_OFFSET_X, offsetXAnimation);
395         contentInOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
396     }
397     if (event == TransitionEvent::POP_START) {
398         contentInOption_.SetCurve(Curves::FAST_OUT_SLOW_IN);
399     }
400     contentInOption_.SetDuration(TRANSITION_PHONE_DURATION);
401 }
402 
CreateDialogModalTransitionOutOption(TransitionEvent event)403 void TransitionPhoneTweenOption::CreateDialogModalTransitionOutOption(TransitionEvent event)
404 {
405     RefPtr<CurveAnimation<DimensionOffset>> translateAnimation;
406     if (isRightToLeft_) {
407         translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(DimensionOffset(Offset()),
408             DimensionOffset(Offset(deviceWidth_, 0)), Curves::FRICTION);
409     } else {
410         translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(DimensionOffset(Offset()),
411             DimensionOffset(Offset(-deviceWidth_, 0)), Curves::FRICTION);
412     }
413     auto opacityAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(1.0f, 1.0f, Curves::LINEAR);
414     contentOutOption_.SetOpacityAnimation(opacityAnimation);
415     contentOutOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
416 }
417 
CreateTransitionOutOption(TransitionEvent event)418 void TransitionPhoneTweenOption::CreateTransitionOutOption(TransitionEvent event)
419 {
420     if (isRightToLeft_) {
421         auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(DimensionOffset(Offset()),
422             DimensionOffset(Offset(deviceWidth_ * TRANSITION_FACTOR_OUT, 0)), Curves::FRICTION);
423         auto offsetXAnimation =
424             AceType::MakeRefPtr<CurveAnimation<float>>(0.0f, deviceWidth_ * TRANSITION_FACTOR, Curves::FRICTION);
425         contentOutOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_OFFSET_X, offsetXAnimation);
426         contentOutOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
427     } else {
428         auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(DimensionOffset(Offset()),
429             DimensionOffset(Offset(-deviceWidth_ * TRANSITION_FACTOR_OUT, 0)), Curves::FRICTION);
430         auto widthAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(
431             deviceWidth_, deviceWidth_ * TRANSITION_FACTOR_OUT, Curves::FRICTION);
432         contentOutOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, widthAnimation);
433         contentOutOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
434     }
435     auto opacityAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(1.0f, 1.0f, Curves::LINEAR);
436     contentOutOption_.SetOpacityAnimation(opacityAnimation);
437 
438     auto colorAnimation = AceType::MakeRefPtr<CurveAnimation<Color>>(
439         Color::FromRGBO(0, 0, 0, 0.0), Color::FromRGBO(0, 0, 0, BLACK_OPACITY), Curves::FRICTION);
440     frontDecorationOption_.SetColorAnimation(colorAnimation);
441     frontDecorationOption_.SetIsBackground(false);
442 
443     if (event == TransitionEvent::POP_START) {
444         contentOutOption_.SetCurve(Curves::FAST_OUT_SLOW_IN);
445         frontDecorationOption_.SetCurve(Curves::FAST_OUT_SLOW_IN);
446     }
447 }
448 
TransitionWatchTweenOption(TransitionEvent event,bool isRightToLeft,const WeakPtr<PipelineContext> & context)449 TransitionWatchTweenOption::TransitionWatchTweenOption(
450     TransitionEvent event, bool isRightToLeft, const WeakPtr<PipelineContext>& context)
451     : TransitionTweenOption(isRightToLeft, context)
452 {
453     CreateTransitionInOption(event);
454     CreateTransitionOutOption(event);
455     CreateSharedInOption(isRightToLeft_, deviceViewScale_, deviceWidth_, sharedTransitionInOption_);
456     CreateSharedOutOption(sharedTransitionOutOption_);
457 }
458 
CreateTransitionInOption(TransitionEvent event)459 void TransitionWatchTweenOption::CreateTransitionInOption(TransitionEvent event)
460 {
461     RefPtr<CurveAnimation<DimensionOffset>> translateAnimation;
462     if (isRightToLeft_) {
463         translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
464             DimensionOffset(Dimension(-deviceWidth_, DimensionUnit::PX), Dimension()),
465             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
466     } else {
467         translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(
468             DimensionOffset(Dimension(deviceWidth_, DimensionUnit::PX), Dimension()),
469             DimensionOffset(Dimension(), Dimension()), Curves::FRICTION);
470     }
471     contentInOption_.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
472     contentInOption_.SetDuration(TRANSITION_WATCH_DURATION);
473 
474     if (event == TransitionEvent::POP_START) {
475         contentInOption_.SetCurve(Curves::SMOOTH);
476     }
477 }
478 
CreateTransitionOutOption(TransitionEvent event)479 void TransitionWatchTweenOption::CreateTransitionOutOption(TransitionEvent event)
480 {
481     if (isRightToLeft_) {
482         auto offsetXAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(0.0f, deviceWidth_, Curves::FRICTION);
483         contentOutOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_OFFSET_X, offsetXAnimation);
484     } else {
485         auto widthAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(deviceWidth_, 0.0f, Curves::FRICTION);
486         contentOutOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_WIDTH, widthAnimation);
487     }
488     auto opacityAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(1.0f, 1.0f, Curves::FRICTION);
489     contentOutOption_.SetOpacityAnimation(opacityAnimation);
490 
491     if (event == TransitionEvent::POP_START) {
492         contentOutOption_.SetCurve(Curves::SMOOTH);
493     }
494 }
495 
CreateCardTransitionOutOption(TransitionEvent event)496 void TransitionPhoneTweenOption::CreateCardTransitionOutOption(TransitionEvent event)
497 {
498     contentOutOption_.SetDuration(TRANSITION_PHONE_DURATION);
499     // blackening treatment
500     if (event == TransitionEvent::POP_START) {
501         auto colorAnimation = AceType::MakeRefPtr<CurveAnimation<Color>>(Color::FromRGBO(0, 0, 0, 0.2),
502             Color::FromRGBO(0, 0, 0, 0.0), Curves::FRICTION);
503         frontDecorationOption_.SetColorAnimation(colorAnimation);
504     } else {
505         auto colorAnimation = AceType::MakeRefPtr<KeyframeAnimation<Color>>();
506         auto colorKeyframe1 = AceType::MakeRefPtr<Keyframe<Color>>(0.0f, Color::FromRGBO(0, 0, 0, 0.0));
507         auto colorKeyframe2 = AceType::MakeRefPtr<Keyframe<Color>>(0.571f, Color::FromRGBO(0, 0, 0, 0.2));
508         auto colorKeyframe3 = AceType::MakeRefPtr<Keyframe<Color>>(1.0f, Color::FromRGBO(0, 0, 0, 0.2));
509         colorKeyframe2->SetCurve(Curves::SHARP);
510         colorAnimation->AddKeyframe(colorKeyframe1);
511         colorAnimation->AddKeyframe(colorKeyframe2);
512         colorAnimation->AddKeyframe(colorKeyframe3);
513         frontDecorationOption_.SetColorAnimation(colorAnimation);
514     }
515     frontDecorationOption_.SetIsBackground(false);
516 }
517 
CreateCardTransitionInOption(TransitionEvent event,const RRect & rrect)518 void TransitionPhoneTweenOption::CreateCardTransitionInOption(TransitionEvent event, const RRect& rrect)
519 {
520     const Offset& position = rrect.GetRect().GetOffset();
521     const Size& size = rrect.GetRect().GetSize();
522     contentInOption_.SetTransformOrigin(Dimension(), Dimension());
523     if (event == TransitionEvent::POP_START) {
524         auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(DimensionOffset(Offset()),
525             DimensionOffset(position), Curves::FRICTION);
526         auto heightAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(deviceHeight_,
527             size.Height() * deviceWidth_ / size.Width(), Curves::FRICTION);
528         auto scaleAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(1.0f, size.Width() / deviceWidth_,
529             Curves::FRICTION);
530         contentInOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_HEIGHT, heightAnimation);
531         contentInOption_.SetTranslateAnimations(AnimationType::TRANSLATE, translateAnimation);
532         contentInOption_.SetTransformFloatAnimation(AnimationType::SCALE, scaleAnimation);
533     } else {
534         auto translateAnimation = AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(DimensionOffset(position),
535             DimensionOffset(Offset()), Curves::FRICTION);
536         auto heightAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(size.Height() * deviceWidth_ / size.Width(),
537             deviceHeight_, Curves::FRICTION);
538         auto scaleAnimation = AceType::MakeRefPtr<CurveAnimation<float>>(size.Width() / deviceWidth_, 1.0f,
539             Curves::FRICTION);
540         contentInOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_HEIGHT, heightAnimation);
541         contentInOption_.SetTranslateAnimations(AnimationType::TRANSLATE, translateAnimation);
542         contentInOption_.SetTransformFloatAnimation(AnimationType::SCALE, scaleAnimation);
543     }
544     CreateCornerAnimationInOption(event, rrect);
545     CreateCardOpacityAnimationInOption(event);
546     contentInOption_.SetDuration(TRANSITION_PHONE_DURATION);
547 }
548 
CreateCornerAnimationInOption(TransitionEvent event,const RRect & rrect)549 void TransitionPhoneTweenOption::CreateCornerAnimationInOption(TransitionEvent event, const RRect& rrect)
550 {
551     auto cornerRadiusAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
552     auto cornerRadius = rrect.GetCorner().topLeftRadius.GetX().Value() * deviceWidth_ / rrect.Width();
553     if (event == TransitionEvent::POP_START) {
554         auto cornerKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, TRANSITION_DEFAULT_CORNER_RADIUS);
555         auto cornerKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.428f, cornerRadius);
556         auto cornerKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, cornerRadius);
557         cornerKeyframe2->SetCurve(Curves::FRICTION);
558         cornerRadiusAnimation->AddKeyframe(cornerKeyframe1);
559         cornerRadiusAnimation->AddKeyframe(cornerKeyframe2);
560         cornerRadiusAnimation->AddKeyframe(cornerKeyframe3);
561     } else {
562         auto cornerKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, cornerRadius);
563         auto cornerKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.571f, cornerRadius);
564         auto cornerKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, TRANSITION_DEFAULT_CORNER_RADIUS);
565         cornerKeyframe3->SetCurve(Curves::FRICTION);
566         cornerRadiusAnimation->AddKeyframe(cornerKeyframe1);
567         cornerRadiusAnimation->AddKeyframe(cornerKeyframe2);
568         cornerRadiusAnimation->AddKeyframe(cornerKeyframe3);
569     }
570     contentInOption_.SetPropertyAnimationFloat(PropertyAnimatableType::PROPERTY_BORDER_RADIUS, cornerRadiusAnimation);
571 }
572 
CreateCardOpacityAnimationInOption(TransitionEvent event)573 void TransitionPhoneTweenOption::CreateCardOpacityAnimationInOption(TransitionEvent event)
574 {
575     auto opacityAnimation = AceType::MakeRefPtr<KeyframeAnimation<float>>();
576     if (event == TransitionEvent::POP_START) {
577         auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 1.0f);
578         auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.571f, 1.0f);
579         auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 0.0f);
580         opacityKeyframe3->SetCurve(Curves::SHARP);
581         opacityAnimation->AddKeyframe(opacityKeyframe1);
582         opacityAnimation->AddKeyframe(opacityKeyframe2);
583         opacityAnimation->AddKeyframe(opacityKeyframe3);
584     } else {
585         auto opacityKeyframe1 = AceType::MakeRefPtr<Keyframe<float>>(0.0f, 0.0f);
586         auto opacityKeyframe2 = AceType::MakeRefPtr<Keyframe<float>>(0.286f, 1.0f);
587         auto opacityKeyframe3 = AceType::MakeRefPtr<Keyframe<float>>(1.0f, 1.0f);
588         opacityKeyframe2->SetCurve(Curves::SHARP);
589         opacityAnimation->AddKeyframe(opacityKeyframe1);
590         opacityAnimation->AddKeyframe(opacityKeyframe2);
591         opacityAnimation->AddKeyframe(opacityKeyframe3);
592     }
593     contentInOption_.SetOpacityAnimation(opacityAnimation);
594 }
595 
CreateSlideEffectAnimation(TweenOption & tweenOption,SlideEffect effect,PageTransitionType type,TransitionDirection direction)596 void TransitionDeclarativeTweenOption::CreateSlideEffectAnimation(
597     TweenOption& tweenOption, SlideEffect effect, PageTransitionType type, TransitionDirection direction)
598 {
599     bool exitFlag = false;
600     if (type == PageTransitionType::EXIT || type == PageTransitionType::EXIT_POP ||
601         type == PageTransitionType::EXIT_PUSH) {
602         exitFlag = true;
603     }
604 
605     if (effect == SlideEffect::LEFT) {
606         auto init = DimensionOffset(Dimension(-deviceWidth_, DimensionUnit::PX), Dimension());
607         auto target = DimensionOffset(Dimension(), Dimension());
608         if (exitFlag) {
609             std::swap(init, target);
610         }
611         auto translateAnimation =
612             AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(init, target, tweenOption.GetCurve());
613         tweenOption.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
614     } else if (effect == SlideEffect::RIGHT) {
615         auto init = DimensionOffset(Dimension(deviceWidth_, DimensionUnit::PX), Dimension());
616         auto target = DimensionOffset(Dimension(), Dimension());
617         if (exitFlag) {
618             std::swap(init, target);
619         }
620         auto translateAnimation =
621             AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(init, target, tweenOption.GetCurve());
622         tweenOption.SetTranslateAnimations(AnimationType::TRANSLATE_X, translateAnimation);
623     } else if (effect == SlideEffect::TOP) {
624         auto init = DimensionOffset(Dimension(), Dimension(-deviceHeight_, DimensionUnit::PX));
625         auto target = DimensionOffset(Dimension(), Dimension());
626         if (exitFlag) {
627             std::swap(init, target);
628         }
629         auto translateAnimation =
630             AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(init, target, tweenOption.GetCurve());
631         tweenOption.SetTranslateAnimations(AnimationType::TRANSLATE_Y, translateAnimation);
632     } else if (effect == SlideEffect::BOTTOM) {
633         auto init = DimensionOffset(Dimension(), Dimension(deviceHeight_, DimensionUnit::PX));
634         auto target = DimensionOffset(Dimension(), Dimension());
635         if (exitFlag) {
636             std::swap(init, target);
637         }
638         auto translateAnimation =
639             AceType::MakeRefPtr<CurveAnimation<DimensionOffset>>(init, target, tweenOption.GetCurve());
640         tweenOption.SetTranslateAnimations(AnimationType::TRANSLATE_Y, translateAnimation);
641     }
642 }
643 
644 } // namespace OHOS::Ace
645