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