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 layoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
236 auto focusHub = buttonNode->GetFocusHub();
237 CHECK_NULL_VOID(focusHub);
238 focusHub->SetShow(false);
239 });
240 buttonRender->OpacityAnimation(animationOption, 1.0f, 0.0f);
241 }
242
PlayOldColumnOpacityOutAnimation()243 void DateTimeAnimationController::PlayOldColumnOpacityOutAnimation()
244 {
245 auto monthDays = monthDays_.Upgrade();
246 CHECK_NULL_VOID(monthDays);
247 auto monthDaysRender = monthDays->GetRenderContext();
248 auto timePicker = timePicker_.Upgrade();
249 CHECK_NULL_VOID(timePicker);
250 auto timePickerRender = timePicker->GetRenderContext();
251
252 auto layoutProperty = monthDays->GetLayoutProperty<LayoutProperty>();
253 CHECK_NULL_VOID(layoutProperty);
254 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
255 layoutProperty = timePicker->GetLayoutProperty<LayoutProperty>();
256 CHECK_NULL_VOID(layoutProperty);
257 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
258
259 AnimationOption animationOption;
260 animationOption.SetDelay(COLUMN_OPACITY_DELAY);
261 animationOption.SetDuration(OPACITY_DURATION);
262 animationOption.SetCurve(Curves::LINEAR);
263 animationOption.SetOnFinishEvent([weak = AceType::WeakClaim(this)] {
264 auto ref = weak.Upgrade();
265 CHECK_NULL_VOID(ref);
266 if (ref->isInAnimationPlaying_) {
267 ref->isOutAnimationPlaying_ = false;
268 return;
269 }
270 auto datePickerNode = ref->datePicker_.Upgrade();
271 CHECK_NULL_VOID(datePickerNode);
272 auto layoutProperty = datePickerNode->GetLayoutProperty<LayoutProperty>();
273 CHECK_NULL_VOID(layoutProperty);
274 layoutProperty->UpdateVisibility(VisibleType::GONE);
275 ref->isOutAnimationPlaying_ = false;
276 });
277
278 monthDaysRender->UpdateOpacity(0);
279 timePickerRender->UpdateOpacity(0);
280 oldColumnOpacityOutAnimation_ = AnimationUtils::StartAnimation(animationOption,
281 [monthDaysRender, timePickerRender]() {
282 CHECK_NULL_VOID(monthDaysRender);
283 CHECK_NULL_VOID(timePickerRender);
284 monthDaysRender->UpdateOpacity(1);
285 timePickerRender->UpdateOpacity(1);
286 }, animationOption.GetOnFinishEvent());
287 }
288
PlayNewColumnOpacityOutAnimation()289 void DateTimeAnimationController::PlayNewColumnOpacityOutAnimation()
290 {
291 auto month = month_.Upgrade();
292 CHECK_NULL_VOID(month);
293 auto day = day_.Upgrade();
294 CHECK_NULL_VOID(day);
295 auto monthRender = month->GetRenderContext();
296 auto dayRender = day->GetRenderContext();
297 CHECK_NULL_VOID(monthRender);
298 CHECK_NULL_VOID(dayRender);
299
300 AnimationOption animationOption;
301 animationOption.SetDelay(OPACITY_DELAY);
302 animationOption.SetDuration(OPACITY_DURATION);
303 animationOption.SetCurve(Curves::LINEAR);
304
305 monthRender->UpdateOpacity(1);
306 dayRender->UpdateOpacity(1);
307 AnimationUtils::Animate(animationOption,
308 [monthRender, dayRender]() {
309 CHECK_NULL_VOID(monthRender);
310 CHECK_NULL_VOID(dayRender);
311 monthRender->UpdateOpacity(0);
312 dayRender->UpdateOpacity(0);
313 });
314 }
315
PlayYearColumnOpacityOutAnimation()316 void DateTimeAnimationController::PlayYearColumnOpacityOutAnimation()
317 {
318 auto year = year_.Upgrade();
319 CHECK_NULL_VOID(year);
320 auto yearRender = year->GetRenderContext();
321 CHECK_NULL_VOID(yearRender);
322
323 AnimationOption animationOption;
324 animationOption.SetDuration(OPACITY_DURATION);
325 animationOption.SetCurve(Curves::LINEAR);
326
327 yearRender->OpacityAnimation(animationOption, 1.0f, 0.0f);
328 }
329
PlayButtonOpacityOutAnimation()330 void DateTimeAnimationController::PlayButtonOpacityOutAnimation()
331 {
332 auto buttonRow = buttonRow_.Upgrade();
333 CHECK_NULL_VOID(buttonRow);
334 auto buttonRender = buttonRow->GetRenderContext();
335 CHECK_NULL_VOID(buttonRender);
336
337 AnimationOption animationOption;
338 animationOption.SetDelay(OPACITY_DELAY);
339 animationOption.SetDuration(OPACITY_DURATION);
340 animationOption.SetCurve(Curves::LINEAR);
341 animationOption.SetOnFinishEvent([weak = AceType::WeakClaim(this)] {
342 auto ref = weak.Upgrade();
343 CHECK_NULL_VOID(ref);
344 auto buttonNode = ref->buttonRow_.Upgrade();
345 CHECK_NULL_VOID(buttonNode);
346 auto layoutProperty = buttonNode->GetLayoutProperty<LayoutProperty>();
347 CHECK_NULL_VOID(layoutProperty);
348 layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
349 auto focusHub = buttonNode->GetFocusHub();
350 CHECK_NULL_VOID(focusHub);
351 focusHub->SetShow(true);
352 });
353 buttonRender->OpacityAnimation(animationOption, 0.0f, 1.0f);
354 }
355
StopOldColumnOpacityInAnimation()356 void DateTimeAnimationController::StopOldColumnOpacityInAnimation()
357 {
358 if (oldColumnOpacityInAnimation_) {
359 AnimationUtils::StopAnimation(oldColumnOpacityInAnimation_);
360 }
361 }
362
StopOldColumnOpacityOutAnimation()363 void DateTimeAnimationController::StopOldColumnOpacityOutAnimation()
364 {
365 if (oldColumnOpacityOutAnimation_) {
366 AnimationUtils::StopAnimation(oldColumnOpacityOutAnimation_);
367 }
368 }
369
PlayInAnimation()370 void DateTimeAnimationController::PlayInAnimation()
371 {
372 isInAnimationPlaying_ = true;
373 PlayTitleInAnimation();
374 PlayMovingInAnimation();
375
376 StopOldColumnOpacityOutAnimation();
377 PlayOldColumnOpacityInAnimation();
378 PlayNewColumnOpacityInAnimation();
379 PlayYearColumnOpacityInAnimation();
380 PlayButtonOpacityInAnimation();
381 }
382
PlayOutAnimation()383 void DateTimeAnimationController::PlayOutAnimation()
384 {
385 isOutAnimationPlaying_ = true;
386 PlayTitleOutAnimation();
387 PlayMovingOutAnimation();
388
389 StopOldColumnOpacityInAnimation();
390 PlayOldColumnOpacityOutAnimation();
391 PlayNewColumnOpacityOutAnimation();
392 PlayYearColumnOpacityOutAnimation();
393 PlayButtonOpacityOutAnimation();
394 }
395
396
InitMoveRange()397 void DateTimeAnimationController::InitMoveRange()
398 {
399 yearEnd_ = 0.0;
400 monthEnd_ = 0.0;
401 dayEnd_ = 0.0;
402
403 auto year = year_.Upgrade();
404 CHECK_NULL_VOID(year);
405 auto yearGeometry = year->GetGeometryNode();
406 CHECK_NULL_VOID(yearGeometry);
407 auto month = month_.Upgrade();
408 CHECK_NULL_VOID(month);
409 auto monthGeometry = month->GetGeometryNode();
410 CHECK_NULL_VOID(monthGeometry);
411 yearStart_ = 0;
412 monthStart_ = 0 - yearGeometry->GetFrameSize().Width();
413 dayStart_ = monthStart_ - monthGeometry->GetFrameSize().Width();
414 }
415
416
SetDatePicker(const RefPtr<FrameNode> & value)417 void DateTimeAnimationController::SetDatePicker(const RefPtr<FrameNode>& value)
418 {
419 datePicker_ = value;
420 auto children = value->GetChildren();
421 if (children.size() != CHILD_SIZE) {
422 return;
423 }
424 auto iter = children.begin();
425 auto year = (*iter);
426 CHECK_NULL_VOID(year);
427 iter++;
428 auto month = *iter;
429 CHECK_NULL_VOID(month);
430 iter++;
431 auto day = *iter;
432 CHECK_NULL_VOID(day);
433 year_ = DynamicCast<FrameNode>(year);
434 month_ = DynamicCast<FrameNode>(month);
435 day_ = DynamicCast<FrameNode>(day);
436 }
437
Play(bool isIn)438 void DateTimeAnimationController::Play(bool isIn)
439 {
440 if (!created_) {
441 InitMoveRange();
442 created_ = true;
443 }
444
445 if (isIn) {
446 PlayInAnimation();
447 } else {
448 PlayOutAnimation();
449 }
450 }
451 } // namespace OHOS::Ace
452