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 "picker_animation_controller.h"
17 
18 namespace OHOS::Ace {
19 
CreateTriangleAnimation()20 void PickerAnimationController::CreateTriangleAnimation()
21 {
22     WeakPtr<PickerAnimationController> weak = AceType::WeakClaim(this);
23     // it is fixed. time start from 0.0ms to 300ms. angle start from 0.0 to -PI which is 3.14
24     inTriangle_ =
25         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, -3.14, 0, 300, Curves::SHARP, [weak](double value) {
26         auto ref = weak.Upgrade();
27         if (!ref) {
28             return;
29         }
30         auto triangle = ref->triangle_.Upgrade();
31         if (!triangle) {
32             return;
33         }
34         triangle->UpdateAngle(value);
35     });
36     // it is fixed. time start from 0.0ms to 300ms. angle start from -PI (3.14) to 0.0
37     outTriangle_ = AceType::MakeRefPtr<PickerAnimation>(pipe_, -3.14, 0.0, 0, 300, Curves::SHARP, [weak](double value) {
38         auto ref = weak.Upgrade();
39         if (!ref) {
40             return;
41         }
42         auto triangle = ref->triangle_.Upgrade();
43         if (!triangle) {
44             return;
45         }
46         triangle->UpdateAngle(value);
47     });
48 }
49 
CreateMovingAnimation()50 void PickerAnimationController::CreateMovingAnimation()
51 {
52     WeakPtr<PickerAnimationController> weak = AceType::WeakClaim(this);
53     inYearMoving_ = // position moving from 0% to 100% (1.0), time from 0ms to 500ms.
54         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 1.0, 0, 500, Curves::FRICTION, [weak](double value) {
55         auto ref = weak.Upgrade();
56         if (!ref) {
57             return;
58         }
59         auto pickerColumn = ref->year_.Upgrade();
60         if (!pickerColumn) {
61             LOGW("year column is null in picker animation.");
62             return;
63         }
64         value = ref->yearStart_ + (ref->yearEnd_ - ref->yearStart_) * value;
65         pickerColumn->UpdateOffset(value);
66     });
67     inMonthMoving_ = // position from 0% to 100% (1.0), time from 0ms to 500ms
68         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 1.0, 0, 500, Curves::FRICTION, [weak](double value) {
69         auto ref = weak.Upgrade();
70         if (!ref) {
71             return;
72         }
73         value = ref->monthStart_ + (ref->monthEnd_ - ref->monthStart_) * value;
74         auto pickerColumn = ref->month_.Upgrade();
75         if (pickerColumn) {
76             pickerColumn->UpdateOffset(value);
77         } else {
78             LOGW("month column is null in picker animation.");
79         }
80         pickerColumn = ref->monthDay_.Upgrade();
81         if (pickerColumn) {
82             pickerColumn->UpdateOffset(value + ref->monthEnd_ - ref->monthStart_);
83         }
84     });
85     inDayMoving_ = // positin from 0% to 100% (1.0), time from 0ms to 500ms.
86         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 1.0, 0, 500, Curves::FRICTION, [weak](double value) {
87         auto ref = weak.Upgrade();
88         if (!ref) {
89             return;
90         }
91         auto pickerColumn = ref->day_.Upgrade();
92         if (!pickerColumn) {
93             LOGW("day column is null in picker animation.");
94             return;
95         }
96         value = ref->dayStart_ + (ref->dayEnd_ - ref->dayStart_) * value;
97         pickerColumn->UpdateOffset(value);
98     });
99 
100     outYearMoving_ = // position from 0% to 100% (1.0), time from 0ms to 500ms.
101         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 1.0, 0, 500, Curves::FRICTION, [weak](double value) {
102         auto ref = weak.Upgrade();
103         if (!ref) {
104             return;
105         }
106         auto pickerColumn = ref->year_.Upgrade();
107         if (!pickerColumn) {
108             return;
109         }
110         value = ref->yearEnd_ + (ref->yearStart_ - ref->yearEnd_) * value;
111         pickerColumn->UpdateOffset(value);
112     });
113     outMonthMoving_ = // posotion from 0% to 100% (1.0), time from 0ms to 500ms
114         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 1.0, 0, 500, Curves::FRICTION, [weak](double value) {
115         auto ref = weak.Upgrade();
116         if (!ref) {
117             return;
118         }
119         value = ref->monthEnd_ + (ref->monthStart_ - ref->monthEnd_) * value;
120         auto pickerColumn = ref->month_.Upgrade();
121         if (pickerColumn) {
122             pickerColumn->UpdateOffset(value);
123         }
124         pickerColumn = ref->monthDay_.Upgrade();
125         if (pickerColumn) {
126             pickerColumn->UpdateOffset(value + ref->monthEnd_ - ref->monthStart_);
127         }
128     });
129     outDayMoving_ = // position from 0% to 100% (1.0), time from 0ms to 500ms.
130         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 1.0, 0, 500, Curves::FRICTION, [weak](double value) {
131         auto ref = weak.Upgrade();
132         if (!ref) {
133             return;
134         }
135         auto pickerColumn = ref->day_.Upgrade();
136         if (!pickerColumn) {
137             return;
138         }
139         value = ref->dayEnd_ + (ref->dayStart_ - ref->dayEnd_) * value;
140         pickerColumn->UpdateOffset(value);
141     });
142 }
143 
CreateInOpacityAnimation()144 void PickerAnimationController::CreateInOpacityAnimation()
145 {
146     WeakPtr<PickerAnimationController> weak = AceType::WeakClaim(this);
147     inOldColumnOpacity_ = // opacity from 255 to 0.0, time from 0ms to 150ms.
148         AceType::MakeRefPtr<PickerAnimation>(pipe_, 255.0, 0.0, 0, 150, Curves::LINEAR, [weak](double value) {
149         auto ref = weak.Upgrade();
150         if (!ref) {
151             return;
152         }
153         auto column = ref->monthDay_.Upgrade();
154         if (column) {
155             column->UpdateColumnOpacity(value);
156         }
157         column = ref->amPm_.Upgrade();
158         if (column) {
159             column->UpdateColumnOpacity(value);
160         }
161         column = ref->hour_.Upgrade();
162         if (column) {
163             column->UpdateColumnOpacity(value);
164         }
165         column = ref->minute_.Upgrade();
166         if (column) {
167             column->UpdateColumnOpacity(value);
168         }
169         column = ref->second_.Upgrade();
170         if (column) {
171             column->UpdateColumnOpacity(value);
172         }
173     });
174     inMonthDayOpacity_ = // opacity from 0.0 to 255, time from 0ms to 150ms.
175         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 255.0, 0, 150, Curves::LINEAR, [weak](double value) {
176         auto ref = weak.Upgrade();
177         if (!ref) {
178             return;
179         }
180         auto column = ref->month_.Upgrade();
181         if (column) {
182             column->UpdateColumnOpacity(value);
183         }
184         column = ref->day_.Upgrade();
185         if (column) {
186             column->UpdateColumnOpacity(value);
187         }
188     });
189     inYearOpacity_ = // opacity from 0.0 to 255, time from 50ms to 150ms.
190         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 255.0, 100, 150, Curves::LINEAR, [weak](double value) {
191         auto ref = weak.Upgrade();
192         if (!ref) {
193             return;
194         }
195         auto column = ref->year_.Upgrade();
196         if (column) {
197             column->UpdateColumnOpacity(value);
198         }
199     });
200     inLunarButtonsOpacity_ = // opacity from 255 to 0, time from 0ms to 150ms.
201         AceType::MakeRefPtr<PickerAnimation>(pipe_, 255.0, 0.0, 0, 150, Curves::LINEAR, [weak](double value) {
202         auto ref = weak.Upgrade();
203         if (!ref) {
204             return;
205         }
206         auto lunar = ref->lunar_.Upgrade();
207         if (lunar) {
208             lunar->UpdateOpacity(static_cast<uint8_t>(value));
209         } else {
210             LOGW("lunar display is null in picker animation.");
211         }
212         auto buttons = ref->buttons_.Upgrade();
213         if (buttons) {
214             buttons->UpdateOpacity(static_cast<uint8_t>(value));
215         } else {
216             LOGW("buttons display is null in picker animation.");
217         }
218     });
219 }
220 
InitColumnOpacity(const RefPtr<RenderPickerColumn> & oldColumn,const RefPtr<RenderPickerColumn> & newColumn)221 void PickerAnimationController::InitColumnOpacity(const RefPtr<RenderPickerColumn>& oldColumn,
222                                                   const RefPtr<RenderPickerColumn>& newColumn)
223 {
224     if (newColumn != oldColumn && newColumn) {
225         newColumn->UpdateColumnOpacity(0.0);
226     }
227 }
228 
CreateOutOpacityAnimation()229 void PickerAnimationController::CreateOutOpacityAnimation()
230 {
231     WeakPtr<PickerAnimationController> weak = AceType::WeakClaim(this);
232     outOldColumnOpacity_ = // opacity from 0 to 255, time from 150ms to 150ms
233         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 255.0, 150, 150, Curves::LINEAR, [weak](double value) {
234         auto ref = weak.Upgrade();
235         if (!ref) {
236             return;
237         }
238         auto column = ref->monthDay_.Upgrade();
239         if (column) {
240             column->UpdateColumnOpacity(value);
241         }
242         column = ref->amPm_.Upgrade();
243         if (column) {
244             column->UpdateColumnOpacity(value);
245         }
246         column = ref->hour_.Upgrade();
247         if (column) {
248             column->UpdateColumnOpacity(value);
249         }
250         column = ref->minute_.Upgrade();
251         if (column) {
252             column->UpdateColumnOpacity(value);
253         }
254         column = ref->second_.Upgrade();
255         if (column) {
256             column->UpdateColumnOpacity(value);
257         }
258     });
259     outMonthDayOpacity_ = // opacity from 255 to 0, time from 100ms to 250ms
260         AceType::MakeRefPtr<PickerAnimation>(pipe_, 255.0, 0.0, 100, 150, Curves::LINEAR, [weak](double value) {
261         auto ref = weak.Upgrade();
262         if (!ref) {
263             return;
264         }
265         auto column = ref->month_.Upgrade();
266         if (column) {
267             column->UpdateColumnOpacity(value);
268         }
269         column = ref->day_.Upgrade();
270         if (column) {
271             column->UpdateColumnOpacity(value);
272         }
273     });
274     outYearOpacity_ = // opacity from 255 to 0, time from 0ms to 150ms
275         AceType::MakeRefPtr<PickerAnimation>(pipe_, 255.0, 0.0, 0, 150, Curves::LINEAR, [weak](double value) {
276         auto ref = weak.Upgrade();
277         if (!ref) {
278             return;
279         }
280         auto column = ref->year_.Upgrade();
281         if (column) {
282             column->UpdateColumnOpacity(value);
283         }
284     });
285     outLunarButtonsOpacity_ = // opacity from 0 to 255, time from 100ms to 250ms
286         AceType::MakeRefPtr<PickerAnimation>(pipe_, 0.0, 255.0, 100, 150, Curves::LINEAR, [weak](double value) {
287         auto ref = weak.Upgrade();
288         if (!ref) {
289             return;
290         }
291         auto lunar = ref->lunar_.Upgrade();
292         if (lunar) {
293             lunar->UpdateOpacity(static_cast<uint8_t>(value));
294         }
295         auto buttons = ref->buttons_.Upgrade();
296         if (buttons) {
297             buttons->UpdateOpacity(static_cast<uint8_t>(value));
298         }
299     });
300 }
301 
CreateAnimation()302 void PickerAnimationController::CreateAnimation()
303 {
304     CreateTriangleAnimation();
305     CreateMovingAnimation();
306     CreateInOpacityAnimation();
307     CreateOutOpacityAnimation();
308 }
309 
PlayInAnimation()310 void PickerAnimationController::PlayInAnimation()
311 {
312     if (inTriangle_) {
313         inTriangle_->Play();
314     }
315     if (inYearMoving_) {
316         inYearMoving_->Play();
317     }
318     if (inMonthMoving_) {
319         inMonthMoving_->Play();
320     }
321     if (inDayMoving_) {
322         inDayMoving_->Play();
323     }
324     if (inOldColumnOpacity_) {
325         inOldColumnOpacity_->Play();
326     }
327     if (inMonthDayOpacity_) {
328         auto month = month_.Upgrade();
329         auto day = day_.Upgrade();
330         if (month) {
331             month->UpdateColumnOpacity(0.0);
332         }
333         if (day) {
334             day->UpdateColumnOpacity(0.0);
335         }
336         inMonthDayOpacity_->Play();
337     }
338     if (inYearOpacity_) {
339         auto year = year_.Upgrade();
340         if (year) {
341             year->UpdateColumnOpacity(0.0);
342         }
343         inYearOpacity_->Play();
344     }
345     if (inLunarButtonsOpacity_) {
346         inLunarButtonsOpacity_->Play();
347     }
348 }
349 
PlayOutAnimation()350 void PickerAnimationController::PlayOutAnimation()
351 {
352     if (outTriangle_) {
353         outTriangle_->Play();
354     }
355     if (outYearMoving_) {
356         outYearMoving_->Play();
357     }
358     if (outMonthMoving_) {
359         outMonthMoving_->Play();
360     }
361     if (outDayMoving_) {
362         outDayMoving_->Play();
363     }
364     if (outOldColumnOpacity_) {
365         outOldColumnOpacity_->Play();
366     }
367     if (outMonthDayOpacity_) {
368         outMonthDayOpacity_->Play();
369     }
370     if (outYearOpacity_) {
371         outYearOpacity_->Play();
372     }
373     if (outLunarButtonsOpacity_) {
374         outLunarButtonsOpacity_->Play();
375     }
376 }
377 
StopInAnimation()378 void PickerAnimationController::StopInAnimation()
379 {
380     if (inTriangle_) {
381         inTriangle_->Stop();
382     }
383     if (inYearMoving_) {
384         inYearMoving_->Stop();
385     }
386     if (inMonthMoving_) {
387         inMonthMoving_->Stop();
388     }
389     if (inDayMoving_) {
390         inDayMoving_->Stop();
391     }
392     if (inOldColumnOpacity_) {
393         inOldColumnOpacity_->Stop();
394     }
395     if (inMonthDayOpacity_) {
396         inMonthDayOpacity_->Stop();
397     }
398     if (inYearOpacity_) {
399         inYearOpacity_->Stop();
400     }
401     if (inLunarButtonsOpacity_) {
402         inLunarButtonsOpacity_->Stop();
403     }
404 }
405 
StopOutAnimation()406 void PickerAnimationController::StopOutAnimation()
407 {
408     if (outTriangle_) {
409         outTriangle_->Stop();
410     }
411     if (outYearMoving_) {
412         outYearMoving_->Stop();
413     }
414     if (outMonthMoving_) {
415         outMonthMoving_->Stop();
416     }
417     if (outDayMoving_) {
418         outDayMoving_->Stop();
419     }
420     if (outOldColumnOpacity_) {
421         outOldColumnOpacity_->Stop();
422     }
423     if (outMonthDayOpacity_) {
424         outMonthDayOpacity_->Stop();
425     }
426     if (outYearOpacity_) {
427         outYearOpacity_->Stop();
428     }
429     if (outLunarButtonsOpacity_) {
430         outLunarButtonsOpacity_->Stop();
431     }
432 }
433 
InitMoveRange()434 void PickerAnimationController::InitMoveRange()
435 {
436     yearEnd_ = 0.0;
437     monthEnd_ = 0.0;
438     dayEnd_ = 0.0;
439 
440     auto year = year_.Upgrade();
441     auto month = month_.Upgrade();
442     auto day = day_.Upgrade();
443     auto monthDay = monthDay_.Upgrade();
444     if (!monthDay) {
445         LOGE("month day column is null.");
446         return;
447     }
448 
449     double position = monthDay->GetInnerColumnGlobalOffset().GetX();
450     if (year) {
451         yearStart_ = position - year->GetInnerColumnGlobalOffset().GetX();
452     }
453     if (month) {
454         monthStart_ = position - month->GetInnerColumnGlobalOffset().GetX();
455     }
456     if (day) {
457         dayStart_ = position - day->GetInnerColumnGlobalOffset().GetX();
458     }
459 }
460 
Play(bool isIn)461 void PickerAnimationController::Play(bool isIn)
462 {
463     if (!created_) {
464         InitMoveRange();
465         CreateAnimation();
466         created_ = true;
467     }
468 
469     if (isIn) {
470         if (outDayMoving_) {
471             outDayMoving_->ClearStopCallback();
472         }
473         StopOutAnimation();
474         PlayInAnimation();
475     } else {
476         StopInAnimation();
477         if (outDayMoving_ && outStopCallback_) {
478             outDayMoving_->AddStopCallback(outStopCallback_);
479         }
480         PlayOutAnimation();
481     }
482 }
483 
484 } // namespace OHOS::Ace
485 
486