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/layout/layout_property.h"
17 #include "date_time_animation_controller.h"
18
19 namespace OHOS::Ace::NG {
20 namespace {
21 constexpr int32_t CHILD_SIZE = 3;
22 constexpr double SEMI_CIRCLE_ANGEL = 180;
23 constexpr double OPACITY_DELAY = 100;
24 constexpr double COLUMN_OPACITY_DELAY = 150;
25 constexpr double OPACITY_DURATION = 150;
26 constexpr double TRIANGLE_DURATION = 300;
27 constexpr double MOVE_DURATION = 500;
28 } // namespace
PlayTitleInAnimation()29 void DateTimeAnimationController::PlayTitleInAnimation()
30 {
31 auto buttonIcon = buttonIcon_.Upgrade();
32 CHECK_NULL_VOID(buttonIcon);
33 auto renderContext = buttonIcon->GetRenderContext();
34 auto context = buttonIcon->GetContextRefPtr();
35 AnimationOption animationOption;
36 animationOption.SetDuration(TRIANGLE_DURATION);
37 animationOption.SetCurve(Curves::SHARP);
38
39 renderContext->UpdateTransformRotate(Vector5F(0, 0, 1, 0, 0));
40 AnimationUtils::Animate(animationOption,
41 [renderContext]() {
42 CHECK_NULL_VOID(renderContext);
43 renderContext->UpdateTransformRotate(Vector5F(0, 0, 1, 0 - SEMI_CIRCLE_ANGEL, 0));
44 }, nullptr, nullptr, context);
45 }
46
PlayTitleOutAnimation()47 void DateTimeAnimationController::PlayTitleOutAnimation()
48 {
49 auto buttonIcon = buttonIcon_.Upgrade();
50 CHECK_NULL_VOID(buttonIcon);
51 auto renderContext = buttonIcon->GetRenderContext();
52 auto context = buttonIcon->GetContextRefPtr();
53 AnimationOption animationOption;
54 animationOption.SetDuration(TRIANGLE_DURATION);
55 animationOption.SetCurve(Curves::SHARP);
56
57 renderContext->UpdateTransformRotate(Vector5F(0, 0, 1, 0 - SEMI_CIRCLE_ANGEL, 0));
58 AnimationUtils::Animate(animationOption,
59 [renderContext]() {
60 CHECK_NULL_VOID(renderContext);
61 renderContext->UpdateTransformRotate(Vector5F(0, 0, 1, 0, 0));
62 }, nullptr, nullptr, context);
63 }
64
PlayMovingInAnimation()65 void DateTimeAnimationController::PlayMovingInAnimation()
66 {
67 auto year = year_.Upgrade();
68 CHECK_NULL_VOID(year);
69 auto month = month_.Upgrade();
70 CHECK_NULL_VOID(month);
71 auto day = day_.Upgrade();
72 CHECK_NULL_VOID(day);
73 auto yearRenderContext = year->GetRenderContext();
74 auto monthRenderContext = month->GetRenderContext();
75 auto dayRenderContext = day->GetRenderContext();
76 auto context = year->GetContextRefPtr();
77 AnimationOption animationOption;
78 animationOption.SetDuration(MOVE_DURATION);
79 animationOption.SetCurve(Curves::FRICTION);
80
81 yearRenderContext->UpdateTransformTranslate({ yearStart_, 0.0f, 0.0f });
82 monthRenderContext->UpdateTransformTranslate({ monthStart_, 0.0f, 0.0f });
83 dayRenderContext->UpdateTransformTranslate({ dayStart_, 0.0f, 0.0f });
84 AnimationUtils::Animate(animationOption,
85 [yearRenderContext, monthRenderContext, dayRenderContext, weak = AceType::WeakClaim(this)]() {
86 auto ref = weak.Upgrade();
87 CHECK_NULL_VOID(ref);
88 CHECK_NULL_VOID(yearRenderContext);
89 CHECK_NULL_VOID(monthRenderContext);
90 CHECK_NULL_VOID(dayRenderContext);
91 yearRenderContext->UpdateTransformTranslate({ ref->yearEnd_, 0.0f, 0.0f });
92 monthRenderContext->UpdateTransformTranslate({ ref->monthEnd_, 0.0f, 0.0f });
93 dayRenderContext->UpdateTransformTranslate({ ref->dayEnd_, 0.0f, 0.0f });
94 }, nullptr, nullptr, context);
95 }
96
PlayMovingOutAnimation()97 void DateTimeAnimationController::PlayMovingOutAnimation()
98 {
99 auto year = year_.Upgrade();
100 CHECK_NULL_VOID(year);
101 auto month = month_.Upgrade();
102 CHECK_NULL_VOID(month);
103 auto day = day_.Upgrade();
104 CHECK_NULL_VOID(day);
105 auto yearRenderContext = year->GetRenderContext();
106 auto monthRenderContext = month->GetRenderContext();
107 auto dayRenderContext = day->GetRenderContext();
108 auto context = year->GetContextRefPtr();
109 AnimationOption animationOption;
110 animationOption.SetDuration(MOVE_DURATION);
111 animationOption.SetCurve(Curves::FRICTION);
112
113 yearRenderContext->UpdateTransformTranslate({ yearEnd_, 0.0f, 0.0f });
114 monthRenderContext->UpdateTransformTranslate({ monthEnd_, 0.0f, 0.0f });
115 dayRenderContext->UpdateTransformTranslate({ dayEnd_, 0.0f, 0.0f });
116 AnimationUtils::Animate(animationOption,
117 [yearRenderContext, monthRenderContext, dayRenderContext, weak = AceType::WeakClaim(this)]() {
118 auto ref = weak.Upgrade();
119 CHECK_NULL_VOID(ref);
120 CHECK_NULL_VOID(yearRenderContext);
121 CHECK_NULL_VOID(monthRenderContext);
122 CHECK_NULL_VOID(dayRenderContext);
123 yearRenderContext->UpdateTransformTranslate({ ref->yearStart_, 0.0f, 0.0f });
124 monthRenderContext->UpdateTransformTranslate({ ref->monthStart_, 0.0f, 0.0f });
125 dayRenderContext->UpdateTransformTranslate({ ref->dayStart_, 0.0f, 0.0f });
126 }, nullptr, nullptr, context);
127 }
128
PlayOldColumnOpacityInAnimation()129 void DateTimeAnimationController::PlayOldColumnOpacityInAnimation()
130 {
131 auto monthDays = monthDays_.Upgrade();
132 CHECK_NULL_VOID(monthDays);
133 auto timePicker = timePicker_.Upgrade();
134 CHECK_NULL_VOID(timePicker);
135 auto monthDaysRender = monthDays->GetRenderContext();
136 auto timePickerRender = timePicker->GetRenderContext();
137 CHECK_NULL_VOID(monthDaysRender);
138 CHECK_NULL_VOID(timePickerRender);
139 auto datePicker = datePicker_.Upgrade();
140 if (datePicker) {
141 auto layoutProperty = datePicker->GetLayoutProperty<LayoutProperty>();
142 if (layoutProperty) {
143 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
144 }
145 }
146 AnimationOption animationOption;
147 animationOption.SetDuration(OPACITY_DURATION);
148 animationOption.SetCurve(Curves::LINEAR);
149 animationOption.SetOnFinishEvent([weak = AceType::WeakClaim(this)] {
150 auto ref = weak.Upgrade();
151 CHECK_NULL_VOID(ref);
152 if (ref->isOutAnimationPlaying_) {
153 ref->isInAnimationPlaying_ = false;
154 return;
155 }
156 auto monthDaysNode = ref->monthDays_.Upgrade();
157 CHECK_NULL_VOID(monthDaysNode);
158 auto layoutProperty = monthDaysNode->GetLayoutProperty<LayoutProperty>();
159 CHECK_NULL_VOID(layoutProperty);
160 layoutProperty->UpdateVisibility(VisibleType::GONE);
161
162 auto timePickerNode = ref->timePicker_.Upgrade();
163 CHECK_NULL_VOID(timePickerNode);
164 layoutProperty = timePickerNode->GetLayoutProperty<LayoutProperty>();
165 CHECK_NULL_VOID(layoutProperty);
166 layoutProperty->UpdateVisibility(VisibleType::GONE);
167 ref->isInAnimationPlaying_ = false;
168 });
169 monthDaysRender->UpdateOpacity(1);
170 timePickerRender->UpdateOpacity(1);
171 oldColumnOpacityInAnimation_ = AnimationUtils::StartAnimation(animationOption,
172 [monthDaysRender, timePickerRender]() {
173 CHECK_NULL_VOID(monthDaysRender);
174 CHECK_NULL_VOID(timePickerRender);
175 monthDaysRender->UpdateOpacity(0);
176 timePickerRender->UpdateOpacity(0);
177 }, animationOption.GetOnFinishEvent());
178 }
179
PlayNewColumnOpacityInAnimation()180 void DateTimeAnimationController::PlayNewColumnOpacityInAnimation()
181 {
182 auto month = month_.Upgrade();
183 CHECK_NULL_VOID(month);
184 auto day = day_.Upgrade();
185 CHECK_NULL_VOID(day);
186 auto monthRender = month->GetRenderContext();
187 auto dayRender = day->GetRenderContext();
188 auto context = month->GetContextRefPtr();
189 CHECK_NULL_VOID(monthRender);
190 CHECK_NULL_VOID(dayRender);
191
192 AnimationOption animationOption;
193 animationOption.SetDuration(OPACITY_DURATION);
194 animationOption.SetCurve(Curves::LINEAR);
195
196 monthRender->UpdateOpacity(0);
197 dayRender->UpdateOpacity(0);
198 AnimationUtils::Animate(animationOption,
199 [monthRender, dayRender]() {
200 CHECK_NULL_VOID(monthRender);
201 CHECK_NULL_VOID(dayRender);
202 monthRender->UpdateOpacity(1);
203 dayRender->UpdateOpacity(1);
204 }, nullptr, nullptr, context);
205 }
206
PlayYearColumnOpacityInAnimation()207 void DateTimeAnimationController::PlayYearColumnOpacityInAnimation()
208 {
209 auto year = year_.Upgrade();
210 CHECK_NULL_VOID(year);
211 auto yearRender = year->GetRenderContext();
212 CHECK_NULL_VOID(yearRender);
213
214 AnimationOption animationOption;
215 animationOption.SetDelay(OPACITY_DELAY);
216 animationOption.SetDuration(OPACITY_DURATION);
217 animationOption.SetCurve(Curves::LINEAR);
218
219 yearRender->OpacityAnimation(animationOption, 0.0f, 1.0f);
220 }
221
PlayButtonOpacityInAnimation()222 void DateTimeAnimationController::PlayButtonOpacityInAnimation()
223 {
224 auto buttonRow = buttonRow_.Upgrade();
225 CHECK_NULL_VOID(buttonRow);
226 auto buttonRender = buttonRow->GetRenderContext();
227 CHECK_NULL_VOID(buttonRender);
228
229 AnimationOption animationOption;
230 animationOption.SetDelay(OPACITY_DELAY);
231 animationOption.SetDuration(OPACITY_DURATION);
232 animationOption.SetCurve(Curves::LINEAR);
233 animationOption.SetOnFinishEvent([weak = AceType::WeakClaim(this)] {
234 auto ref = weak.Upgrade();
235 CHECK_NULL_VOID(ref);
236 auto buttonNode = ref->buttonRow_.Upgrade();
237 CHECK_NULL_VOID(buttonNode);
238 auto layoutProperty = buttonNode->GetLayoutProperty<LayoutProperty>();
239 CHECK_NULL_VOID(layoutProperty);
240 if (!ref->isDatePickerButtonHade_) {
241 layoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
242 }
243 auto focusHub = buttonNode->GetFocusHub();
244 CHECK_NULL_VOID(focusHub);
245 focusHub->SetShow(false);
246 });
247 if (!isDatePickerButtonHade_) {
248 buttonRender->OpacityAnimation(animationOption, 1.0f, 0.0f);
249 }
250 }
251
PlayOldColumnOpacityOutAnimation()252 void DateTimeAnimationController::PlayOldColumnOpacityOutAnimation()
253 {
254 auto monthDays = monthDays_.Upgrade();
255 CHECK_NULL_VOID(monthDays);
256 auto monthDaysRender = monthDays->GetRenderContext();
257 auto timePicker = timePicker_.Upgrade();
258 CHECK_NULL_VOID(timePicker);
259 auto timePickerRender = timePicker->GetRenderContext();
260
261 auto layoutProperty = monthDays->GetLayoutProperty<LayoutProperty>();
262 CHECK_NULL_VOID(layoutProperty);
263 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
264 layoutProperty = timePicker->GetLayoutProperty<LayoutProperty>();
265 CHECK_NULL_VOID(layoutProperty);
266 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
267
268 AnimationOption animationOption;
269 animationOption.SetDelay(COLUMN_OPACITY_DELAY);
270 animationOption.SetDuration(OPACITY_DURATION);
271 animationOption.SetCurve(Curves::LINEAR);
272 animationOption.SetOnFinishEvent([weak = AceType::WeakClaim(this)] {
273 auto ref = weak.Upgrade();
274 CHECK_NULL_VOID(ref);
275 if (ref->isInAnimationPlaying_) {
276 ref->isOutAnimationPlaying_ = false;
277 return;
278 }
279 auto datePickerNode = ref->datePicker_.Upgrade();
280 CHECK_NULL_VOID(datePickerNode);
281 auto layoutProperty = datePickerNode->GetLayoutProperty<LayoutProperty>();
282 CHECK_NULL_VOID(layoutProperty);
283 layoutProperty->UpdateVisibility(VisibleType::GONE);
284 ref->isOutAnimationPlaying_ = false;
285 });
286
287 monthDaysRender->UpdateOpacity(0);
288 timePickerRender->UpdateOpacity(0);
289 oldColumnOpacityOutAnimation_ = AnimationUtils::StartAnimation(animationOption,
290 [monthDaysRender, timePickerRender]() {
291 CHECK_NULL_VOID(monthDaysRender);
292 CHECK_NULL_VOID(timePickerRender);
293 monthDaysRender->UpdateOpacity(1);
294 timePickerRender->UpdateOpacity(1);
295 }, animationOption.GetOnFinishEvent());
296 }
297
PlayNewColumnOpacityOutAnimation()298 void DateTimeAnimationController::PlayNewColumnOpacityOutAnimation()
299 {
300 auto month = month_.Upgrade();
301 CHECK_NULL_VOID(month);
302 auto day = day_.Upgrade();
303 CHECK_NULL_VOID(day);
304 auto monthRender = month->GetRenderContext();
305 auto dayRender = day->GetRenderContext();
306 auto context = month->GetContextRefPtr();
307 CHECK_NULL_VOID(monthRender);
308 CHECK_NULL_VOID(dayRender);
309
310 AnimationOption animationOption;
311 animationOption.SetDelay(OPACITY_DELAY);
312 animationOption.SetDuration(OPACITY_DURATION);
313 animationOption.SetCurve(Curves::LINEAR);
314
315 monthRender->UpdateOpacity(1);
316 dayRender->UpdateOpacity(1);
317 AnimationUtils::Animate(animationOption,
318 [monthRender, dayRender]() {
319 CHECK_NULL_VOID(monthRender);
320 CHECK_NULL_VOID(dayRender);
321 monthRender->UpdateOpacity(0);
322 dayRender->UpdateOpacity(0);
323 }, nullptr, nullptr, context);
324 }
325
PlayYearColumnOpacityOutAnimation()326 void DateTimeAnimationController::PlayYearColumnOpacityOutAnimation()
327 {
328 auto year = year_.Upgrade();
329 CHECK_NULL_VOID(year);
330 auto yearRender = year->GetRenderContext();
331 CHECK_NULL_VOID(yearRender);
332
333 AnimationOption animationOption;
334 animationOption.SetDuration(OPACITY_DURATION);
335 animationOption.SetCurve(Curves::LINEAR);
336
337 yearRender->OpacityAnimation(animationOption, 1.0f, 0.0f);
338 }
339
PlayButtonOpacityOutAnimation()340 void DateTimeAnimationController::PlayButtonOpacityOutAnimation()
341 {
342 auto buttonRow = buttonRow_.Upgrade();
343 CHECK_NULL_VOID(buttonRow);
344 auto buttonRender = buttonRow->GetRenderContext();
345 CHECK_NULL_VOID(buttonRender);
346
347 AnimationOption animationOption;
348 animationOption.SetDelay(OPACITY_DELAY);
349 animationOption.SetDuration(OPACITY_DURATION);
350 animationOption.SetCurve(Curves::LINEAR);
351 animationOption.SetOnFinishEvent([weak = AceType::WeakClaim(this)] {
352 auto ref = weak.Upgrade();
353 CHECK_NULL_VOID(ref);
354 auto buttonNode = ref->buttonRow_.Upgrade();
355 CHECK_NULL_VOID(buttonNode);
356 auto layoutProperty = buttonNode->GetLayoutProperty<LayoutProperty>();
357 CHECK_NULL_VOID(layoutProperty);
358 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
359 auto focusHub = buttonNode->GetFocusHub();
360 CHECK_NULL_VOID(focusHub);
361 focusHub->SetShow(true);
362 });
363 buttonRender->OpacityAnimation(animationOption, 0.0f, 1.0f);
364 }
365
StopOldColumnOpacityInAnimation()366 void DateTimeAnimationController::StopOldColumnOpacityInAnimation()
367 {
368 if (oldColumnOpacityInAnimation_) {
369 AnimationUtils::StopAnimation(oldColumnOpacityInAnimation_);
370 }
371 }
372
StopOldColumnOpacityOutAnimation()373 void DateTimeAnimationController::StopOldColumnOpacityOutAnimation()
374 {
375 if (oldColumnOpacityOutAnimation_) {
376 AnimationUtils::StopAnimation(oldColumnOpacityOutAnimation_);
377 }
378 }
379
PlayInAnimation()380 void DateTimeAnimationController::PlayInAnimation()
381 {
382 isInAnimationPlaying_ = true;
383 PlayTitleInAnimation();
384 PlayMovingInAnimation();
385
386 StopOldColumnOpacityOutAnimation();
387 PlayOldColumnOpacityInAnimation();
388 PlayNewColumnOpacityInAnimation();
389 PlayYearColumnOpacityInAnimation();
390 PlayButtonOpacityInAnimation();
391 }
392
PlayOutAnimation()393 void DateTimeAnimationController::PlayOutAnimation()
394 {
395 isOutAnimationPlaying_ = true;
396 PlayTitleOutAnimation();
397 PlayMovingOutAnimation();
398
399 StopOldColumnOpacityInAnimation();
400 PlayOldColumnOpacityOutAnimation();
401 PlayNewColumnOpacityOutAnimation();
402 PlayYearColumnOpacityOutAnimation();
403 PlayButtonOpacityOutAnimation();
404 }
405
406
InitMoveRange()407 void DateTimeAnimationController::InitMoveRange()
408 {
409 yearEnd_ = 0.0;
410 monthEnd_ = 0.0;
411 dayEnd_ = 0.0;
412
413 auto year = year_.Upgrade();
414 CHECK_NULL_VOID(year);
415 auto yearGeometry = year->GetGeometryNode();
416 CHECK_NULL_VOID(yearGeometry);
417 auto month = month_.Upgrade();
418 CHECK_NULL_VOID(month);
419 auto monthGeometry = month->GetGeometryNode();
420 CHECK_NULL_VOID(monthGeometry);
421 yearStart_ = 0;
422 monthStart_ = 0 - yearGeometry->GetFrameSize().Width();
423 dayStart_ = monthStart_ - monthGeometry->GetFrameSize().Width();
424 }
425
426
SetDatePicker(const RefPtr<FrameNode> & value)427 void DateTimeAnimationController::SetDatePicker(const RefPtr<FrameNode>& value)
428 {
429 datePicker_ = value;
430 auto children = value->GetChildren();
431 if (children.size() != CHILD_SIZE) {
432 return;
433 }
434 auto iter = children.begin();
435 auto year = (*iter);
436 CHECK_NULL_VOID(year);
437 iter++;
438 auto month = *iter;
439 CHECK_NULL_VOID(month);
440 iter++;
441 auto day = *iter;
442 CHECK_NULL_VOID(day);
443 year_ = DynamicCast<FrameNode>(year);
444 month_ = DynamicCast<FrameNode>(month);
445 day_ = DynamicCast<FrameNode>(day);
446 }
447
Play(bool isIn)448 void DateTimeAnimationController::Play(bool isIn)
449 {
450 if (!created_) {
451 InitMoveRange();
452 created_ = true;
453 }
454
455 if (isIn) {
456 PlayInAnimation();
457 } else {
458 PlayOutAnimation();
459 }
460 }
461 } // namespace OHOS::Ace
462