1 /*
2  * Copyright (c) 2022-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/pattern/loading_progress/loading_progress_modifier.h"
17 #include <algorithm>
18 
19 #include "base/geometry/arc.h"
20 #include "base/geometry/dimension.h"
21 #include "base/memory/ace_type.h"
22 #include "base/utils/utils.h"
23 #include "bridge/common/dom/dom_type.h"
24 #include "core/components/common/properties/animation_option.h"
25 #include "core/components/progress/progress_theme.h"
26 #include "core/components_ng/base/modifier.h"
27 #include "core/components_ng/pattern/loading_progress/loading_progress_utill.h"
28 #include "core/components_ng/pattern/refresh/refresh_animation_state.h"
29 #include "core/components_ng/render/animation_utils.h"
30 #include "core/components_ng/render/drawing_prop_convertor.h"
31 
32 namespace OHOS::Ace::NG {
33 namespace {
34 constexpr float TOTAL_ANGLE = 360.0f;
35 constexpr float ROTATEX = -116.0f;
36 constexpr float ROTATEY = 30.0f;
37 constexpr float ROTATEZ = 22.0f;
38 constexpr float COUNT = 50.0f;
39 constexpr float HALF = 0.5f;
40 constexpr float DOUBLE = 2.0f;
41 constexpr int32_t SKEWY = 3;
42 constexpr int32_t SCALEY = 4;
43 constexpr float RING_ALPHA = 200 / 255.0f;
44 constexpr int32_t RING_ALPHA_DARK = 255;
45 constexpr int32_t RING_ALPHA_DARK_BACKGROUNG = 150;
46 constexpr Color DEFAULT_COLOR_DARK = Color(0x99FFFFFF);
47 constexpr int32_t TOTAL_POINTS_COUNT = 20;
48 constexpr int32_t TAIL_ANIAMTION_DURATION = 400;
49 constexpr int32_t TRANS_DURATION = 100;
50 constexpr float TOTAL_TAIL_LENGTH = 60.0f;
51 constexpr float TAIL_ALPHA_RATIO = 0.82f;
52 constexpr float INITIAL_SIZE_SCALE = 0.825f;
53 constexpr float INITIAL_OPACITY_SCALE = 0.7f;
54 constexpr float COMET_TAIL_ANGLE = 3.0f;
55 constexpr int32_t LOADING_DURATION = 1200;
56 constexpr float FOLLOW_START = 72.0f;
57 constexpr float FOLLOW_SPAN = 10.0f;
58 constexpr float FULL_COUNT = 100.0f;
59 constexpr float STAGE1 = 0.25f;
60 constexpr float STAGE2 = 0.65f;
61 constexpr float STAGE3 = 0.75f;
62 constexpr float STAGE4 = 0.85f;
63 constexpr float STAGE5 = 1.0f;
64 constexpr float OPACITY1 = 0.2f;
65 constexpr float OPACITY2 = 0.7f;
66 constexpr float OPACITY3 = 1.0f;
67 constexpr float SIZE_SCALE1 = 0.65f;
68 constexpr float SIZE_SCALE2 = 0.825f;
69 constexpr float SIZE_SCALE3 = 0.93f;
70 constexpr float MOVE_STEP = 0.06f;
71 constexpr float TRANS_OPACITY_SPAN = 0.3f;
72 constexpr float FULL_OPACITY = 255.0f;
73 constexpr float FAKE_DELTA = 0.01f;
74 constexpr float BASE_SCALE = 0.707f; // std::sqrt(2)/2
75 constexpr float REFRESH_DARK_MODE_RING_BLUR_RADIUS = 0.4f;
76 } // namespace
LoadingProgressModifier(LoadingProgressOwner loadingProgressOwner)77 LoadingProgressModifier::LoadingProgressModifier(LoadingProgressOwner loadingProgressOwner)
78     : enableLoading_(AceType::MakeRefPtr<PropertyBool>(true)),
79       offset_(AceType::MakeRefPtr<PropertyOffsetF>(OffsetF())),
80       contentSize_(AceType::MakeRefPtr<PropertySizeF>(SizeF())),
81       date_(AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0f)),
82       color_(AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor::TRANSPARENT)),
83       centerDeviation_(AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0f)),
84       cometOpacity_(AceType::MakeRefPtr<AnimatablePropertyFloat>(INITIAL_OPACITY_SCALE)),
85       cometSizeScale_(AceType::MakeRefPtr<AnimatablePropertyFloat>(INITIAL_SIZE_SCALE)),
86       cometTailLen_(AceType::MakeRefPtr<AnimatablePropertyFloat>(TOTAL_TAIL_LENGTH)),
87       sizeScale_(AceType::MakeRefPtr<AnimatablePropertyFloat>(1.0f)),
88       useContentModifier_(AceType::MakeRefPtr<PropertyBool>(false)),
89       loadingProgressOwner_(loadingProgressOwner)
90 {
91     AttachProperty(enableLoading_);
92     AttachProperty(offset_);
93     AttachProperty(contentSize_);
94     AttachProperty(date_);
95     AttachProperty(color_);
96     AttachProperty(centerDeviation_);
97     AttachProperty(cometOpacity_);
98     AttachProperty(cometSizeScale_);
99     AttachProperty(cometTailLen_);
100 };
101 
onDraw(DrawingContext & context)102 void LoadingProgressModifier::onDraw(DrawingContext& context)
103 {
104     if (useContentModifier_->Get()) {
105         return;
106     }
107     if (!enableLoading_->Get()) {
108         return;
109     }
110     float date = date_->Get();
111     auto diameter = std::min(contentSize_->Get().Width(), contentSize_->Get().Height());
112     RingParam ringParam;
113     ringParam.strokeWidth = LoadingProgressUtill::GetRingStrokeWidth(diameter) * sizeScale_->Get();
114     ringParam.radius = LoadingProgressUtill::GetRingRadius(diameter) * sizeScale_->Get();
115     ringParam.movement =
116         (ringParam.radius * DOUBLE + ringParam.strokeWidth) * centerDeviation_->Get() * sizeScale_->Get();
117     ringParam.darkRingRadius = LoadingProgressUtill::GetRingDarkRadius(diameter) * sizeScale_->Get();
118     ringParam.darkBackgroundWidth = LoadingProgressUtill::GetRingDarkBackgroundWidth(diameter) * sizeScale_->Get();
119     ringParam.darkBackgroundRadius = LoadingProgressUtill::GetRingDarkBackgroundRadius(diameter) * sizeScale_->Get();
120 
121     CometParam cometParam;
122     cometParam.radius = LoadingProgressUtill::GetCometRadius(diameter) * sizeScale_->Get();
123     cometParam.alphaScale = cometOpacity_->Get();
124     cometParam.sizeScale = cometSizeScale_->Get();
125     cometParam.pointCount = GetCometNumber();
126 
127     auto orbitRadius = LoadingProgressUtill::GetOrbitRadius(diameter) * sizeScale_->Get();
128     if (date > COUNT) {
129         DrawRing(context, ringParam);
130         DrawOrbit(context, cometParam, orbitRadius, date);
131     } else {
132         DrawOrbit(context, cometParam, orbitRadius, date);
133         DrawRing(context, ringParam);
134     }
135 }
136 
DrawRing(DrawingContext & context,const RingParam & ringParam)137 void LoadingProgressModifier::DrawRing(DrawingContext& context, const RingParam& ringParam)
138 {
139     auto& canvas = context.canvas;
140     canvas.Save();
141     RSPen pen;
142     RSFilter filter;
143     auto ringColor = color_->Get();
144     ringColor.BlendOpacity(RING_ALPHA);
145     pen.SetColor(ToRSColor(ringColor));
146     if (SystemProperties::GetColorMode() == ColorMode::DARK) {
147         if (ringColor.GetValue() == DEFAULT_COLOR_DARK.GetValue()) {
148             ringColor = LinearColor::WHITE;
149         }
150         // draw ring background
151         DrawRingBackground(context, ringParam, ringColor);
152 
153         ringColor.BlendOpacity(RING_ALPHA_DARK / FULL_OPACITY);
154         pen.SetColor(ToRSColor(ringColor));
155 
156 #ifndef USE_ROSEN_DRAWING
157         filter.SetImageFilter(RSImageFilter::CreateBlurImageFilter(
158             ringParam.darkRingRadius, ringParam.darkRingRadius, RSTileMode::DECAL, nullptr));
159 #else
160         filter.SetImageFilter(RSRecordingImageFilter::CreateBlurImageFilter(
161             ringParam.darkRingRadius, ringParam.darkRingRadius, RSTileMode::DECAL, nullptr));
162 #endif
163         pen.SetFilter(filter);
164     }
165     if (loadingProgressOwner_ == LoadingProgressOwner::REFRESH && SystemProperties::GetColorMode() == ColorMode::DARK) {
166         filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter(
167             RSBlurType::NORMAL, PipelineBase::GetCurrentDensity() * REFRESH_DARK_MODE_RING_BLUR_RADIUS));
168         pen.SetFilter(filter);
169     }
170     pen.SetWidth(ringParam.strokeWidth);
171     pen.SetAntiAlias(true);
172     canvas.AttachPen(pen);
173     canvas.DrawCircle(
174         { offset_->Get().GetX() + contentSize_->Get().Width() * HALF,
175             offset_->Get().GetY() + contentSize_->Get().Height() * HALF + ringParam.movement },
176         ringParam.radius);
177     canvas.DetachPen();
178     canvas.Restore();
179 }
180 
DrawRingBackground(DrawingContext & context,const RingParam & ringParam,LinearColor & ringColor)181 void LoadingProgressModifier::DrawRingBackground(
182     DrawingContext& context, const RingParam& ringParam, LinearColor& ringColor)
183 {
184     auto& canvas = context.canvas;
185     canvas.Save();
186     RSPen pen;
187 
188     ringColor.BlendOpacity(RING_ALPHA_DARK_BACKGROUNG / FULL_OPACITY);
189     pen.SetColor(ToRSColor(ringColor));
190 
191     RSFilter filter;
192 #ifndef USE_ROSEN_DRAWING
193     filter.SetImageFilter(RSImageFilter::CreateBlurImageFilter(
194         ringParam.darkBackgroundRadius, ringParam.darkBackgroundRadius, RSTileMode::DECAL, nullptr));
195 #else
196     filter.SetImageFilter(RSRecordingImageFilter::CreateBlurImageFilter(
197         ringParam.darkBackgroundRadius, ringParam.darkBackgroundRadius, RSTileMode::DECAL, nullptr));
198 #endif
199     pen.SetFilter(filter);
200     pen.SetWidth(ringParam.darkBackgroundWidth);
201     pen.SetAntiAlias(true);
202     canvas.AttachPen(pen);
203     canvas.DrawCircle({ offset_->Get().GetX() + contentSize_->Get().Width() * HALF,
204                           offset_->Get().GetY() + contentSize_->Get().Height() * HALF + ringParam.movement },
205         ringParam.radius);
206     canvas.DetachPen();
207     canvas.Restore();
208 }
209 
DrawOrbit(DrawingContext & context,const CometParam & cometParam,float orbitRadius,float date)210 void LoadingProgressModifier::DrawOrbit(
211     DrawingContext& context, const CometParam& cometParam, float orbitRadius, float date)
212 {
213     auto pointCounts = cometParam.pointCount;
214     auto& canvas = context.canvas;
215     float width = contentSize_->Get().Width();
216     float height = contentSize_->Get().Height();
217     double angle = TOTAL_ANGLE * date / FULL_COUNT;
218     RSCamera3D camera;
219     RSMatrix matrix;
220     AdjustMatrix(camera, matrix);
221     auto center = RSPoint(offset_->Get().GetX() + width / 2, offset_->Get().GetY() + height / 2);
222     RSBrush brush;
223     brush.SetAntiAlias(true);
224     canvas.Save();
225     canvas.Translate(center.GetX(), center.GetY());
226     std::vector<RSPoint> points;
227     for (uint32_t i = 0; i < pointCounts; i++) {
228         RSPoint point;
229         float cometAngal = GetCurentCometAngle(angle, pointCounts - i, pointCounts);
230         float rad = cometAngal * PI_NUM / (TOTAL_ANGLE * HALF);
231         point.SetX(std::cos(rad) * orbitRadius);
232         point.SetY(-std::sin(rad) * orbitRadius);
233         points.push_back(point);
234     }
235     std::vector<RSPoint> distPoints(points.size());
236     matrix.MapPoints(distPoints, points, points.size());
237     auto cometColor = color_->Get();
238     float colorAlpha = cometColor.GetAlpha() / FULL_OPACITY;
239     if (SystemProperties::GetColorMode() == ColorMode::DARK && cometColor.GetValue() == DEFAULT_COLOR_DARK.GetValue()) {
240         colorAlpha = OPACITY3;
241     }
242     auto baseAlpha = colorAlpha * cometParam.alphaScale;
243     for (uint32_t i = 0; i < distPoints.size(); i++) {
244         RSPoint pointCenter = distPoints[i];
245         if (cometColor.GetValue() == Color::FOREGROUND.GetValue()) {
246             brush.SetColor(ToRSColor(cometColor));
247         } else {
248             float setAlpha = GetCurentCometOpacity(baseAlpha, distPoints.size() - i, distPoints.size());
249             if (NearZero(setAlpha)) {
250                 continue;
251             }
252             brush.SetColor(
253                 ToRSColor(Color::FromRGBO(cometColor.GetRed(), cometColor.GetGreen(), cometColor.GetBlue(), setAlpha)));
254         }
255         canvas.AttachBrush(brush);
256         canvas.DrawCircle(pointCenter, cometParam.radius * cometParam.sizeScale);
257     }
258     canvas.DetachBrush();
259     canvas.Restore();
260 }
261 
AdjustMatrix(RSCamera3D & camera,RSMatrix & matrix)262 void LoadingProgressModifier::AdjustMatrix(RSCamera3D& camera, RSMatrix& matrix)
263 {
264     camera.Save();
265     camera.RotateYDegrees(ROTATEY);
266     camera.RotateXDegrees(ROTATEX);
267     camera.RotateZDegrees(ROTATEZ);
268     camera.ApplyToMatrix(matrix);
269     camera.Restore();
270     auto temp = matrix.Get(SKEWY);
271     matrix.Set(RSMatrix::SKEW_Y, matrix.Get(SCALEY));
272     matrix.Set(RSMatrix::SCALE_Y, temp);
273 }
274 
StartRecycleRingAnimation()275 void LoadingProgressModifier::StartRecycleRingAnimation()
276 {
277     auto context = PipelineBase::GetCurrentContext();
278     CHECK_NULL_VOID(context);
279     auto previousStageCurve = AceType::MakeRefPtr<CubicCurve>(0.0f, 0.0f, 0.67f, 1.0f);
280     AnimationOption option;
281     option.SetDuration(isVisible_ ? LOADING_DURATION : 0);
282     option.SetCurve(previousStageCurve);
283     if (context->IsFormRender()) {
284         option.SetIteration(1);
285     } else {
286         option.SetIteration(-1);
287     }
288     AnimationUtils::OpenImplicitAnimation(option, previousStageCurve, nullptr);
289     auto middleStageCurve = AceType::MakeRefPtr<CubicCurve>(0.33f, 0.0f, 0.67f, 1.0f);
290     AnimationUtils::AddKeyFrame(
291         STAGE1, middleStageCurve, [weakCenterDeviation = AceType::WeakClaim(AceType::RawPtr(centerDeviation_))]() {
292             auto centerDeviation = weakCenterDeviation.Upgrade();
293             CHECK_NULL_VOID(centerDeviation);
294             centerDeviation->Set(-1 * MOVE_STEP);
295         });
296     auto latterStageCurve = AceType::MakeRefPtr<CubicCurve>(0.33f, 0.0f, 1.0f, 1.0f);
297     AnimationUtils::AddKeyFrame(
298         STAGE3, latterStageCurve, [weakCenterDeviation = AceType::WeakClaim(AceType::RawPtr(centerDeviation_))]() {
299             auto centerDeviation = weakCenterDeviation.Upgrade();
300             CHECK_NULL_VOID(centerDeviation);
301             centerDeviation->Set(MOVE_STEP);
302         });
303     AnimationUtils::AddKeyFrame(
304         STAGE5, latterStageCurve, [weakCenterDeviation = AceType::WeakClaim(AceType::RawPtr(centerDeviation_))]() {
305             auto centerDeviation = weakCenterDeviation.Upgrade();
306             CHECK_NULL_VOID(centerDeviation);
307             centerDeviation->Set(0.0f);
308         });
309     AnimationUtils::CloseImplicitAnimation();
310 }
311 
StartRecycleCometAnimation()312 void LoadingProgressModifier::StartRecycleCometAnimation()
313 {
314     auto context = PipelineBase::GetCurrentContext();
315     CHECK_NULL_VOID(context);
316     auto curve = AceType::MakeRefPtr<LinearCurve>();
317     AnimationOption option;
318     option.SetDuration(isVisible_ ? LOADING_DURATION : 0);
319     option.SetCurve(curve);
320     if (context->IsFormRender()) {
321         option.SetIteration(1);
322     } else {
323         option.SetIteration(-1);
324     }
325 
326     cometOpacity_->Set(OPACITY2);
327     cometTailLen_->Set(TOTAL_TAIL_LENGTH);
328     AnimationUtils::OpenImplicitAnimation(option, curve, nullptr);
329     AnimationUtils::AddKeyFrame(STAGE1, curve,
330         [weakCometOpacity = AceType::WeakClaim(AceType::RawPtr(cometOpacity_)),
331             weakCometSizeScale = AceType::WeakClaim(AceType::RawPtr(cometSizeScale_))]() {
332             auto cometOpacity = weakCometOpacity.Upgrade();
333             if (cometOpacity) {
334                 cometOpacity->Set(OPACITY1);
335             }
336             auto cometSizeScale = weakCometSizeScale.Upgrade();
337             if (cometSizeScale) {
338                 cometSizeScale->Set(SIZE_SCALE1);
339             }
340         });
341     AnimationUtils::AddKeyFrame(STAGE2, curve,
342         [weakCometOpacity = AceType::WeakClaim(AceType::RawPtr(cometOpacity_)),
343             weakCometSizeScale = AceType::WeakClaim(AceType::RawPtr(cometSizeScale_))]() {
344             auto cometOpacity = weakCometOpacity.Upgrade();
345             if (cometOpacity) {
346                 cometOpacity->Set(OPACITY3);
347             }
348             auto cometSizeScale = weakCometSizeScale.Upgrade();
349             if (cometSizeScale) {
350                 cometSizeScale->Set(SIZE_SCALE3);
351             }
352         });
353     AnimationUtils::AddKeyFrame(STAGE3, curve,
354         [weakCometOpacity = AceType::WeakClaim(AceType::RawPtr(cometOpacity_)),
355             weakCometSizeScale = AceType::WeakClaim(AceType::RawPtr(cometSizeScale_))]() {
356             auto cometOpacity = weakCometOpacity.Upgrade();
357             if (cometOpacity) {
358                 cometOpacity->Set(OPACITY3);
359             }
360             auto cometSizeScale = weakCometSizeScale.Upgrade();
361             if (cometSizeScale) {
362                 cometSizeScale->Set(1.0f);
363             }
364         });
365     AnimationUtils::AddKeyFrame(STAGE4, curve,
366         [weakCometOpacity = AceType::WeakClaim(AceType::RawPtr(cometOpacity_)),
367             weakCometSizeScale = AceType::WeakClaim(AceType::RawPtr(cometSizeScale_))]() {
368             auto cometOpacity = weakCometOpacity.Upgrade();
369             if (cometOpacity) {
370                 cometOpacity->Set(OPACITY3);
371             }
372             auto cometSizeScale = weakCometSizeScale.Upgrade();
373             if (cometSizeScale) {
374                 cometSizeScale->Set(SIZE_SCALE3);
375             }
376         });
377     AnimationUtils::AddKeyFrame(STAGE5, curve,
378         [weakCometOpacity = AceType::WeakClaim(AceType::RawPtr(cometOpacity_)),
379             weakCometSizeScale = AceType::WeakClaim(AceType::RawPtr(cometSizeScale_))]() {
380             auto cometOpacity = weakCometOpacity.Upgrade();
381             if (cometOpacity) {
382                 cometOpacity->Set(OPACITY2);
383             }
384             auto cometSizeScale = weakCometSizeScale.Upgrade();
385             if (cometSizeScale) {
386                 cometSizeScale->Set(SIZE_SCALE2);
387             }
388         });
389     AnimationUtils::CloseImplicitAnimation();
390 }
391 
StartCometTailAnimation()392 void LoadingProgressModifier::StartCometTailAnimation()
393 {
394     auto curve = AceType::MakeRefPtr<LinearCurve>();
395     AnimationOption option;
396     option.SetDuration(TAIL_ANIAMTION_DURATION);
397     option.SetIteration(1);
398     option.SetCurve(curve);
399     AnimationUtils::Animate(option, [weakCometTailLen = AceType::WeakClaim(AceType::RawPtr(cometTailLen_))]() {
400         auto cometTailLen = weakCometTailLen.Upgrade();
401         CHECK_NULL_VOID(cometTailLen);
402         cometTailLen->Set(TOTAL_TAIL_LENGTH);
403     });
404 }
405 
GetCurentCometOpacity(float baseOpacity,uint32_t index,uint32_t totalNumber)406 float LoadingProgressModifier::GetCurentCometOpacity(float baseOpacity, uint32_t index, uint32_t totalNumber)
407 {
408     return baseOpacity * std::pow(TAIL_ALPHA_RATIO, std::clamp(index, 1u, totalNumber) - 1);
409 }
410 
GetCurentCometAngle(float baseAngle,uint32_t index,uint32_t totalNumber)411 float LoadingProgressModifier::GetCurentCometAngle(float baseAngle, uint32_t index, uint32_t totalNumber)
412 {
413     return std::fmod((baseAngle - (std::clamp(index, 1u, totalNumber) - 1) * COMET_TAIL_ANGLE), TOTAL_ANGLE);
414 }
415 
GetCometNumber()416 uint32_t LoadingProgressModifier::GetCometNumber()
417 {
418     CHECK_NULL_RETURN(cometTailLen_, TOTAL_POINTS_COUNT);
419     return static_cast<uint32_t>(cometTailLen_->Get() / COMET_TAIL_ANGLE);
420 }
421 
StartRecycle()422 void LoadingProgressModifier::StartRecycle()
423 {
424     auto context = PipelineBase::GetCurrentContext();
425     CHECK_NULL_VOID(context);
426     if (isLoading_) {
427         return;
428     }
429     sizeScale_->Set(1.0f);
430     if (date_) {
431         isLoading_ = true;
432         date_->Set(0.0f);
433         AnimationOption option = AnimationOption();
434         RefPtr<Curve> curve = AceType::MakeRefPtr<CubicCurve>(0.25f, 0.30f, 0.50f, 0.14f);
435         option.SetDuration(isVisible_ ? LOADING_DURATION : 0);
436         option.SetDelay(0);
437         option.SetCurve(curve);
438         if (context->IsFormRender()) {
439             option.SetIteration(1);
440         } else {
441             option.SetIteration(-1);
442         }
443         AnimationUtils::Animate(option, [weakDate = AceType::WeakClaim(AceType::RawPtr(date_))]() {
444             auto date = weakDate.Upgrade();
445             CHECK_NULL_VOID(date);
446             date->Set(FULL_COUNT);
447         });
448     }
449     cometOpacity_->Set(INITIAL_OPACITY_SCALE);
450     cometSizeScale_->Set(INITIAL_SIZE_SCALE);
451     // ring up and down shift animation
452     StartRecycleRingAnimation();
453     // comet's circle Color transparency and sizeScale animation
454     StartRecycleCometAnimation();
455 }
456 
StartTransToRecycleAnimation()457 void LoadingProgressModifier::StartTransToRecycleAnimation()
458 {
459     sizeScale_->Set(1.0f);
460     auto curve = AceType::MakeRefPtr<CubicCurve>(0.6f, 0.2f, 1.0f, 1.0f);
461     AnimationOption option;
462     option.SetDuration(TRANS_DURATION);
463     option.SetIteration(1);
464     option.SetCurve(curve);
465     AnimationUtils::Animate(
466         option,
467         [weakDate = AceType::WeakClaim(AceType::RawPtr(date_)),
468             weakCometOpacity = AceType::WeakClaim(AceType::RawPtr(cometOpacity_)),
469             weakCometSizeScale = AceType::WeakClaim(AceType::RawPtr(cometSizeScale_))]() {
470             auto date = weakDate.Upgrade();
471             if (date) {
472                 date->Set(FULL_COUNT);
473             }
474             auto cometOpacity = weakCometOpacity.Upgrade();
475             if (cometOpacity) {
476                 cometOpacity->Set(1.0 - TRANS_OPACITY_SPAN);
477             }
478             auto cometSizeScale = weakCometSizeScale.Upgrade();
479             if (cometSizeScale) {
480                 cometSizeScale->Set(INITIAL_SIZE_SCALE);
481             }
482         },
483         [weak = AceType::WeakClaim(this)]() {
484             auto modify = weak.Upgrade();
485             CHECK_NULL_VOID(modify);
486             modify->StartRecycle();
487         });
488     StartCometTailAnimation();
489 }
490 
ChangeRefreshFollowData(float refreshFollowRatio)491 void LoadingProgressModifier::ChangeRefreshFollowData(float refreshFollowRatio)
492 {
493     auto ratio = CorrectNormalize(refreshFollowRatio);
494     sizeScale_->Set(BASE_SCALE + (1.0 - BASE_SCALE) * ratio);
495     if (isLoading_) {
496         CloseAnimation(FOLLOW_START, COMET_TAIL_ANGLE, 1.0f, 1.0f);
497     }
498     CHECK_NULL_VOID(date_);
499     date_->Set(FOLLOW_START + FOLLOW_SPAN * ratio);
500     cometTailLen_->Set(COMET_TAIL_ANGLE);
501     cometOpacity_->Set(1.0f);
502     cometSizeScale_->Set(1.0f);
503 }
504 
ChangeSizeScaleData(float refreshFadeAwayRatio)505 void LoadingProgressModifier::ChangeSizeScaleData(float refreshFadeAwayRatio)
506 {
507     auto ratio = CorrectNormalize(refreshFadeAwayRatio);
508     sizeScale_->Set(BASE_SCALE + (1.0 - BASE_SCALE) * ratio);
509 }
510 
CloseAnimation(float date,float cometLen,float cometOpacity,float cometScale)511 void LoadingProgressModifier::CloseAnimation(float date, float cometLen, float cometOpacity, float cometScale)
512 {
513     isLoading_ = false;
514     AnimationOption option = AnimationOption();
515     RefPtr<Curve> curve = AceType::MakeRefPtr<LinearCurve>();
516     option.SetDuration(0);
517     option.SetIteration(1);
518     option.SetCurve(curve);
519     date_->Set(date + FAKE_DELTA);
520     cometTailLen_->Set(cometLen + FAKE_DELTA);
521     cometOpacity_->Set(cometOpacity + FAKE_DELTA);
522     cometSizeScale_->Set(cometScale + FAKE_DELTA);
523     centerDeviation_->Set(0.0f + FAKE_DELTA);
524     AnimationUtils::Animate(option, [weak = AceType::WeakClaim(this), date, cometLen, cometOpacity, cometScale]() {
525         auto curObj = weak.Upgrade();
526         CHECK_NULL_VOID(curObj);
527         curObj->date_->Set(date);
528         curObj->cometTailLen_->Set(cometLen);
529         curObj->cometOpacity_->Set(cometOpacity);
530         curObj->cometSizeScale_->Set(cometScale);
531         curObj->centerDeviation_->Set(0.0f);
532     });
533 }
CorrectNormalize(float originData)534 float LoadingProgressModifier::CorrectNormalize(float originData)
535 {
536     auto ratio = originData;
537     if (ratio < 0.0f) {
538         ratio = 0.0f;
539     }
540     if (ratio > 1.0f) {
541         ratio = 1.0f;
542     };
543     return ratio;
544 }
545 } // namespace OHOS::Ace::NG
546