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