• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/pattern/swiper_indicator/dot_indicator/dot_indicator_modifier.h"
17 
18 #include "base/utils/utils.h"
19 #include "core/animation/spring_curve.h"
20 #include "core/components_ng/render/animation_utils.h"
21 #include "core/components_ng/render/drawing.h"
22 
23 namespace OHOS::Ace::NG {
24 namespace {
25 constexpr Dimension INDICATOR_ITEM_SPACE = 8.0_vp;
26 constexpr Dimension INDICATOR_PADDING_DEFAULT = 12.0_vp;
27 constexpr Dimension INDICATOR_PADDING_HOVER = 12.0_vp;
28 constexpr float INDICATOR_ZOOM_IN_SCALE = 1.33f;
29 constexpr int32_t POINT_HOVER_ANIMATION_DURATION = 100;
30 constexpr int32_t COMPONENT_DILATE_ANIMATION_DURATION = 250;
31 constexpr int32_t COMPONENT_SHRINK_ANIMATION_DURATION = 300;
32 constexpr int32_t MOUSE_PRESS_ANIMATION_DURATION = 250;
33 constexpr int32_t POINT_ANIMATION_DURATION = 400;
34 
35 constexpr float BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY = 0.4f;
36 constexpr float LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY = 0.2f;
37 constexpr float LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY = 1.0f;
38 constexpr float CENTER_BEZIER_CURVE_MASS = 0.0f;
39 constexpr float CENTER_BEZIER_CURVE_STIFFNESS = 1.0f;
40 constexpr float CENTER_BEZIER_CURVE_DAMPING = 1.0f;
41 constexpr uint32_t ITEM_HALF_WIDTH = 0;
42 constexpr uint32_t ITEM_HALF_HEIGHT = 1;
43 constexpr uint32_t SELECTED_ITEM_HALF_WIDTH = 2;
44 constexpr uint32_t SELECTED_ITEM_HALF_HEIGHT = 3;
45 constexpr float TOUCH_BOTTOM_CURVE_VELOCITY = 0.1f;
46 constexpr float TOUCH_BOTTOM_CURVE_MASS = 0.2f;
47 constexpr float TOUCH_BOTTOM_CURVE_STIFFNESS = 0.48f;
48 constexpr float TOUCH_BOTTOM_CURVE_DAMPING = 1.0f;
49 constexpr float TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE = 1.225f;
50 constexpr float TOUCH_BOTTOM_BACKGROUND_HEIGHT_MULTIPLE = 0.8f;
51 constexpr float TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE = 0.0125f;
52 } // namespace
53 
onDraw(DrawingContext & context)54 void DotIndicatorModifier::onDraw(DrawingContext& context)
55 {
56     ContentProperty contentProperty;
57     contentProperty.backgroundColor = backgroundColor_->Get().ToColor();
58     contentProperty.vectorBlackPointCenterX = vectorBlackPointCenterX_->Get();
59     contentProperty.longPointLeftCenterX = longPointLeftCenterX_->Get();
60     contentProperty.longPointRightCenterX = longPointRightCenterX_->Get();
61     contentProperty.normalToHoverPointDilateRatio = normalToHoverPointDilateRatio_->Get();
62     contentProperty.hoverToNormalPointDilateRatio = hoverToNormalPointDilateRatio_->Get();
63     contentProperty.longPointDilateRatio = longPointDilateRatio_->Get();
64     contentProperty.indicatorPadding = indicatorPadding_->Get();
65     contentProperty.indicatorMargin = indicatorMargin_->Get();
66     contentProperty.itemHalfSizes = itemHalfSizes_->Get();
67     PaintBackground(context, contentProperty);
68     PaintContent(context, contentProperty);
69 }
70 
PaintBackground(DrawingContext & context,const ContentProperty & contentProperty)71 void DotIndicatorModifier::PaintBackground(DrawingContext& context, const ContentProperty& contentProperty)
72 {
73     CHECK_NULL_VOID_NOLOG(contentProperty.backgroundColor.GetAlpha());
74     auto itemWidth = contentProperty.itemHalfSizes[ITEM_HALF_WIDTH] * 2;
75     auto itemHeight = contentProperty.itemHalfSizes[ITEM_HALF_HEIGHT] * 2;
76     auto selectedItemWidth = contentProperty.itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
77     auto selectedItemHeight = contentProperty.itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
78     auto pointNumber = static_cast<float>(contentProperty.vectorBlackPointCenterX.size());
79     float allPointDiameterSum = itemWidth * static_cast<float>(pointNumber + 1);
80     if (isCustomSize_) {
81         allPointDiameterSum = itemWidth * static_cast<float>(pointNumber - 1) + selectedItemWidth;
82     }
83     float allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()) * (pointNumber - 1);
84 
85     // Background necessary property
86     float rectWidth =
87         contentProperty.indicatorPadding + allPointDiameterSum + allPointSpaceSum + contentProperty.indicatorPadding;
88     float rectHeight = contentProperty.indicatorPadding + itemHeight + contentProperty.indicatorPadding;
89     if (selectedItemHeight > itemHeight) {
90         rectHeight = contentProperty.indicatorPadding + selectedItemHeight + contentProperty.indicatorPadding;
91     }
92 
93     auto widthChangeValue = (backgroundWidthDilateRatio_->Get() - 1.0f) * rectWidth;
94     auto heightChangeValue = (1.0f - backgroundHeightDilateRatio_->Get()) * rectHeight;
95     if (axis_ == Axis::VERTICAL) {
96         std::swap(widthChangeValue, heightChangeValue);
97     }
98     // Property to get the rectangle offset
99     float rectLeft =
100         axis_ == Axis::HORIZONTAL ? contentProperty.indicatorMargin.GetX() : contentProperty.indicatorMargin.GetY();
101     float rectTop =
102         axis_ == Axis::HORIZONTAL ? contentProperty.indicatorMargin.GetY() : contentProperty.indicatorMargin.GetX();
103     // Adapter circle and rect
104     float rectRight = rectLeft + (axis_ == Axis::HORIZONTAL ? rectWidth : rectHeight);
105     float rectBottom = rectTop + (axis_ == Axis::HORIZONTAL ? rectHeight : rectWidth);
106 
107     if (axis_ == Axis::HORIZONTAL) {
108         if (touchBottomType_ == TouchBottomType::START) {
109             rectLeft -= widthChangeValue;
110         }
111         if (touchBottomType_ == TouchBottomType::END) {
112             rectRight += widthChangeValue;
113         }
114         rectTop = rectTop + heightChangeValue * 0.5f;
115         rectBottom = rectBottom - heightChangeValue * 0.5f;
116         rectHeight -= heightChangeValue;
117     } else {
118         if (touchBottomType_ == TouchBottomType::START) {
119             rectTop -= heightChangeValue;
120         }
121         if (touchBottomType_ == TouchBottomType::END) {
122             rectBottom += heightChangeValue;
123         }
124         rectLeft = rectLeft + widthChangeValue * 0.5f;
125         rectRight = rectRight - widthChangeValue * 0.5f;
126         rectWidth -= widthChangeValue;
127     }
128     // Paint background
129     RSCanvas canvas = context.canvas;
130     RSBrush brush;
131     brush.SetAntiAlias(true);
132     brush.SetColor(ToRSColor(contentProperty.backgroundColor));
133     canvas.AttachBrush(brush);
134     auto radius = axis_ == Axis::HORIZONTAL ? rectHeight : rectWidth;
135     canvas.DrawRoundRect({ { rectLeft, rectTop, rectRight, rectBottom }, radius, radius });
136 }
137 
PaintContent(DrawingContext & context,ContentProperty & contentProperty)138 void DotIndicatorModifier::PaintContent(DrawingContext& context, ContentProperty& contentProperty)
139 {
140     RSCanvas canvas = context.canvas;
141     OffsetF selectedCenter = {};
142     for (size_t i = 0; i < contentProperty.vectorBlackPointCenterX.size(); ++i) {
143         LinearVector<float> itemHalfSizes = GetItemHalfSizes(i, contentProperty);
144         OffsetF center = { contentProperty.vectorBlackPointCenterX[i], centerY_ };
145         if (i != currentIndex_) {
146             PaintUnselectedIndicator(canvas, center, itemHalfSizes, false);
147         } else {
148             selectedCenter = center;
149             PaintUnselectedIndicator(canvas, center, itemHalfSizes, true);
150         }
151     }
152     OffsetF leftCenter = { contentProperty.longPointLeftCenterX, centerY_ };
153     OffsetF rightCenter = { contentProperty.longPointRightCenterX, centerY_ };
154     OffsetF centerDistance = rightCenter - leftCenter;
155     OffsetF centerDilateDistance = centerDistance * contentProperty.longPointDilateRatio;
156     leftCenter -= (centerDilateDistance - centerDistance) * 0.5;
157     rightCenter += (centerDilateDistance - centerDistance) * 0.5;
158     PaintSelectedIndicator(canvas, selectedCenter, leftCenter, rightCenter,
159         contentProperty.itemHalfSizes * contentProperty.longPointDilateRatio);
160 }
161 
GetItemHalfSizes(size_t index,ContentProperty & contentProperty)162 LinearVector<float> DotIndicatorModifier::GetItemHalfSizes(size_t index, ContentProperty& contentProperty)
163 {
164     if (normalToHoverIndex_.has_value() && normalToHoverIndex_ == index) {
165         return contentProperty.itemHalfSizes * contentProperty.normalToHoverPointDilateRatio;
166     }
167     if (hoverToNormalIndex_.has_value() && hoverToNormalIndex_ == index) {
168         return contentProperty.itemHalfSizes * contentProperty.hoverToNormalPointDilateRatio;
169     }
170     return contentProperty.itemHalfSizes;
171 }
172 
PaintUnselectedIndicator(RSCanvas & canvas,const OffsetF & center,const LinearVector<float> & itemHalfSizes,bool currentIndexFlag)173 void DotIndicatorModifier::PaintUnselectedIndicator(
174     RSCanvas& canvas, const OffsetF& center, const LinearVector<float>& itemHalfSizes, bool currentIndexFlag)
175 {
176     RSBrush brush;
177     brush.SetAntiAlias(true);
178     brush.SetColor(ToRSColor(unselectedColor_->Get()));
179     canvas.AttachBrush(brush);
180     if (!NearEqual(itemHalfSizes[ITEM_HALF_WIDTH], itemHalfSizes[ITEM_HALF_HEIGHT]) ||
181         currentIndexFlag ||!isCustomSize_) {
182         float rectItemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * 2;
183         float rectItemHeight = itemHalfSizes[ITEM_HALF_HEIGHT] * 2;
184         if (currentIndexFlag) {
185             rectItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
186             rectItemHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
187         }
188         float rectLeft =
189             (axis_ == Axis::HORIZONTAL ? center.GetX() - rectItemWidth * 0.5 : center.GetY() - rectItemHeight * 0.5);
190         float rectTop =
191             (axis_ == Axis::HORIZONTAL ? center.GetY() - rectItemHeight * 0.5 : center.GetX() - rectItemWidth * 0.5);
192         float rectRight =
193             (axis_ == Axis::HORIZONTAL ? center.GetX() + rectItemWidth * 0.5 : center.GetY() + rectItemHeight * 0.5);
194         float rectBottom =
195             (axis_ == Axis::HORIZONTAL ? center.GetY() + rectItemHeight * 0.5 : center.GetX() + rectItemWidth * 0.5);
196 
197         if (rectItemHeight > rectItemWidth || !isCustomSize_) {
198             canvas.DrawRoundRect({ { rectLeft, rectTop, rectRight, rectBottom }, rectItemWidth, rectItemWidth });
199         } else if (rectItemHeight < rectItemWidth) {
200             canvas.DrawRoundRect({ { rectLeft, rectTop, rectRight, rectBottom }, rectItemHeight, rectItemHeight });
201         } else {
202             float customPointX = axis_ == Axis::HORIZONTAL ? center.GetX() : center.GetY();
203             float customPointY = axis_ == Axis::HORIZONTAL ? center.GetY() : center.GetX();
204             canvas.DrawCircle({ customPointX, customPointY }, rectItemHeight * 0.5);
205         }
206     } else {
207         float pointX = axis_ == Axis::HORIZONTAL ? center.GetX() : center.GetY();
208         float pointY = axis_ == Axis::HORIZONTAL ? center.GetY() : center.GetX();
209         canvas.DrawCircle({ pointX, pointY }, itemHalfSizes[ITEM_HALF_HEIGHT]);
210     }
211 }
212 
PaintSelectedIndicator(RSCanvas & canvas,const OffsetF & center,const OffsetF & leftCenter,const OffsetF & rightCenter,const LinearVector<float> & itemHalfSizes)213 void DotIndicatorModifier::PaintSelectedIndicator(RSCanvas& canvas, const OffsetF& center, const OffsetF& leftCenter,
214     const OffsetF& rightCenter, const LinearVector<float>& itemHalfSizes)
215 {
216     RSBrush brush;
217     brush.SetAntiAlias(true);
218     brush.SetColor(ToRSColor(selectedColor_->Get()));
219     canvas.AttachBrush(brush);
220 
221     float rectLeft = (axis_ == Axis::HORIZONTAL ? leftCenter.GetX() - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]
222                                                 : leftCenter.GetY() - itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]);
223 
224     float rectTop = (axis_ == Axis::HORIZONTAL ? leftCenter.GetY() - itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]
225                                                : leftCenter.GetX() - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]);
226     float rectRight = (axis_ == Axis::HORIZONTAL ? rightCenter.GetX() + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]
227                                                  : rightCenter.GetY() + itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]);
228 
229     float rectBottom = (axis_ == Axis::HORIZONTAL ? rightCenter.GetY() + itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]
230                                                   : rightCenter.GetX() + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]);
231 
232     float rectSelectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
233     float rectSelectedItemHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
234 
235     if (rectSelectedItemHeight > rectSelectedItemWidth && !isCustomSize_) {
236         canvas.DrawRoundRect(
237             { { rectLeft, rectTop, rectRight, rectBottom }, rectSelectedItemWidth, rectSelectedItemWidth });
238     } else {
239         canvas.DrawRoundRect(
240             { { rectLeft, rectTop, rectRight, rectBottom }, rectSelectedItemHeight, rectSelectedItemHeight });
241     }
242 }
243 
PaintMask(DrawingContext & context)244 void DotIndicatorModifier::PaintMask(DrawingContext& context)
245 {
246     RSCanvas canvas = context.canvas;
247 
248     RSBrush brush;
249     brush.SetAntiAlias(true);
250     canvas.Save();
251 
252     std::vector<RSColorQuad> colors;
253     colors.push_back(0x00000000);
254     colors.push_back(0xff000000);
255     colors.push_back(0xff000000);
256 
257     RSPoint startPt = { offset_.GetX(), offset_.GetY() };
258     RSPoint endPt = { offset_.GetX(), offset_.GetY() };
259     startPt -= axis_ == Axis::HORIZONTAL ? RSPoint(0, (9.0_vp).ConvertToPx()) : RSPoint((9.0_vp).ConvertToPx(), 0);
260     endPt += axis_ == Axis::HORIZONTAL ? RSPoint(0, (15.0_vp).ConvertToPx()) : RSPoint((15.0_vp).ConvertToPx(), 0);
261 
262     std::vector<float> pos = { 0.0f, 0.75f, 1.0f };
263 
264     brush.SetShaderEffect(RSShaderEffect::CreateLinearGradient(startPt, endPt, colors, pos, RSTileMode::CLAMP));
265     canvas.DrawRect({ startPt.GetX(), startPt.GetY(), endPt.GetX(), endPt.GetY() });
266 }
267 
UpdateShrinkPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)268 void DotIndicatorModifier::UpdateShrinkPaintProperty(
269     const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
270     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
271 {
272     indicatorMargin_->Set(margin);
273     indicatorPadding_->Set(static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx()));
274 
275     vectorBlackPointCenterX_->Set(vectorBlackPointCenterX);
276     if (longPointLeftAnimEnd_) {
277         longPointLeftCenterX_->Set(longPointCenterX.first);
278     }
279     if (longPointRightAnimEnd_) {
280         longPointRightCenterX_->Set(longPointCenterX.second);
281     }
282     itemHalfSizes_->Set(normalItemHalfSizes);
283     normalToHoverPointDilateRatio_->Set(1.0f);
284     hoverToNormalPointDilateRatio_->Set(1.0f);
285     longPointDilateRatio_->Set(1.0f);
286     backgroundWidthDilateRatio_->Set(1.0f);
287     backgroundHeightDilateRatio_->Set(1.0f);
288 }
289 
UpdateDilatePaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)290 void DotIndicatorModifier::UpdateDilatePaintProperty(
291     const LinearVector<float>& hoverItemHalfSizes, const LinearVector<float>& vectorBlackPointCenterX,
292     const std::pair<float, float>& longPointCenterX)
293 {
294     indicatorMargin_->Set({ 0, 0 });
295     indicatorPadding_->Set(static_cast<float>(INDICATOR_PADDING_HOVER.ConvertToPx()));
296 
297     vectorBlackPointCenterX_->Set(vectorBlackPointCenterX);
298     if (longPointLeftAnimEnd_) {
299         longPointLeftCenterX_->Set(longPointCenterX.first);
300     }
301     if (longPointRightAnimEnd_) {
302         longPointRightCenterX_->Set(longPointCenterX.second);
303     }
304     itemHalfSizes_->Set(hoverItemHalfSizes);
305     backgroundWidthDilateRatio_->Set(1.0f);
306     backgroundHeightDilateRatio_->Set(1.0f);
307 }
308 
UpdateBackgroundColor(const Color & backgroundColor)309 void DotIndicatorModifier::UpdateBackgroundColor(const Color& backgroundColor)
310 {
311     backgroundColor_->Set(LinearColor(backgroundColor));
312 }
313 
UpdateNormalPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)314 void DotIndicatorModifier::UpdateNormalPaintProperty(
315     const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
316     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
317 {
318     auto swiperTheme = GetSwiperIndicatorTheme();
319     CHECK_NULL_VOID(swiperTheme);
320     auto backgroundColor = indicatorMask_ ?
321         swiperTheme->GetPressedColor() :
322         swiperTheme->GetHoverColor().ChangeOpacity(0);
323     UpdateShrinkPaintProperty(margin, normalItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
324     UpdateBackgroundColor(backgroundColor);
325 }
326 
UpdateHoverPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)327 void DotIndicatorModifier::UpdateHoverPaintProperty(
328     const LinearVector<float>& hoverItemHalfSizes,
329     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
330 {
331     auto swiperTheme = GetSwiperIndicatorTheme();
332     CHECK_NULL_VOID(swiperTheme);
333     auto backgroundColor = swiperTheme->GetHoverColor();
334     UpdateDilatePaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
335     UpdateBackgroundColor(backgroundColor);
336 }
337 
UpdatePressPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)338 void DotIndicatorModifier::UpdatePressPaintProperty(
339     const LinearVector<float>& hoverItemHalfSizes,
340     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
341 {
342     auto swiperTheme = GetSwiperIndicatorTheme();
343     CHECK_NULL_VOID(swiperTheme);
344     auto backgroundColor = swiperTheme->GetPressedColor();
345     UpdateDilatePaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
346     UpdateBackgroundColor(backgroundColor);
347 }
348 
UpdateNormalToHoverPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)349 void DotIndicatorModifier::UpdateNormalToHoverPaintProperty(
350     const LinearVector<float>& hoverItemHalfSizes, const LinearVector<float>& vectorBlackPointCenterX,
351     const std::pair<float, float>& longPointCenterX)
352 {
353     AnimationOption option;
354     option.SetDuration(COMPONENT_DILATE_ANIMATION_DURATION);
355     option.SetCurve(Curves::SHARP);
356     AnimationUtils::Animate(option, [weak = WeakClaim(this), hoverItemHalfSizes, vectorBlackPointCenterX,
357         longPointCenterX]() {
358         auto modifier = weak.Upgrade();
359         CHECK_NULL_VOID(modifier);
360         modifier->UpdateHoverPaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
361     });
362 }
363 
UpdateHoverToNormalPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)364 void DotIndicatorModifier::UpdateHoverToNormalPaintProperty(
365     const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
366     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
367 {
368     AnimationOption option;
369     option.SetDuration(COMPONENT_SHRINK_ANIMATION_DURATION);
370     option.SetCurve(Curves::SHARP);
371     AnimationUtils::Animate(option, [weak = WeakClaim(this), margin, normalItemHalfSizes, vectorBlackPointCenterX,
372         longPointCenterX]() {
373         auto modifier = weak.Upgrade();
374         CHECK_NULL_VOID(modifier);
375         modifier->UpdateNormalPaintProperty(margin, normalItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
376     });
377 }
378 
UpdateNormalToPressPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)379 void DotIndicatorModifier::UpdateNormalToPressPaintProperty(
380     const LinearVector<float>& hoverItemHalfSizes, const LinearVector<float>& vectorBlackPointCenterX,
381     const std::pair<float, float>& longPointCenterX)
382 {
383     AnimationOption option;
384     option.SetDuration(COMPONENT_DILATE_ANIMATION_DURATION);
385     option.SetCurve(Curves::SHARP);
386     AnimationUtils::Animate(option, [weak = WeakClaim(this), hoverItemHalfSizes, vectorBlackPointCenterX,
387         longPointCenterX]() {
388         auto modifier = weak.Upgrade();
389         CHECK_NULL_VOID(modifier);
390         modifier->UpdatePressPaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
391     });
392 }
393 
UpdatePressToNormalPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)394 void DotIndicatorModifier::UpdatePressToNormalPaintProperty(
395     const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
396     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
397 {
398     AnimationOption option;
399     option.SetDuration(COMPONENT_SHRINK_ANIMATION_DURATION);
400     option.SetCurve(Curves::SHARP);
401     AnimationUtils::Animate(option, [weak = WeakClaim(this), margin, normalItemHalfSizes, vectorBlackPointCenterX,
402         longPointCenterX]() {
403         auto modifier = weak.Upgrade();
404         CHECK_NULL_VOID(modifier);
405         modifier->UpdateNormalPaintProperty(margin, normalItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
406     });
407 }
408 
UpdateHoverAndPressConversionPaintProperty()409 void DotIndicatorModifier::UpdateHoverAndPressConversionPaintProperty()
410 {
411     auto swiperTheme = GetSwiperIndicatorTheme();
412     CHECK_NULL_VOID(swiperTheme);
413     Color backgroundColor = isPressed_ ? swiperTheme->GetPressedColor() : swiperTheme->GetHoverColor();
414     AnimationOption option;
415     option.SetDuration(MOUSE_PRESS_ANIMATION_DURATION);
416     option.SetCurve(Curves::SHARP);
417     AnimationUtils::Animate(option, [weak = WeakClaim(this), backgroundColor]() {
418         auto modifier = weak.Upgrade();
419         CHECK_NULL_VOID(modifier);
420         modifier->UpdateBackgroundColor(backgroundColor);
421     });
422 }
423 
UpdateNormalToHoverPointDilateRatio()424 void DotIndicatorModifier::UpdateNormalToHoverPointDilateRatio()
425 {
426     normalToHoverPointDilateRatio_->Set(1.0f);
427     AnimationOption option;
428     option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
429     option.SetCurve(Curves::SHARP);
430     AnimationUtils::Animate(option, [&]() { normalToHoverPointDilateRatio_->Set(INDICATOR_ZOOM_IN_SCALE); });
431 }
432 
UpdateHoverToNormalPointDilateRatio()433 void DotIndicatorModifier::UpdateHoverToNormalPointDilateRatio()
434 {
435     hoverToNormalPointDilateRatio_->Set(normalToHoverPointDilateRatio_->Get());
436     AnimationOption option;
437     option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
438     option.SetCurve(Curves::SHARP);
439     AnimationUtils::Animate(option, [&]() { hoverToNormalPointDilateRatio_->Set(1.0f); });
440 }
441 
UpdateLongPointDilateRatio()442 void DotIndicatorModifier::UpdateLongPointDilateRatio()
443 {
444     AnimationOption option;
445     option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
446     option.SetCurve(Curves::SHARP);
447     if (longPointIsHover_) {
448         AnimationUtils::Animate(option, [&]() { longPointDilateRatio_->Set(INDICATOR_ZOOM_IN_SCALE); });
449     } else {
450         AnimationUtils::Animate(option, [&]() { longPointDilateRatio_->Set(1.0f); });
451     }
452 }
453 
UpdateAllPointCenterXAnimation(bool isForward,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)454 void DotIndicatorModifier::UpdateAllPointCenterXAnimation(
455     bool isForward, const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
456 {
457     AnimationOption blackPointOption;
458     blackPointOption.SetDuration(POINT_ANIMATION_DURATION);
459     blackPointOption.SetCurve(AceType::MakeRefPtr<CubicCurve>(BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY,
460         CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING));
461     AnimationUtils::Animate(blackPointOption, [&]() { vectorBlackPointCenterX_->Set(vectorBlackPointCenterX); });
462 
463     if (longPointLeftAnimEnd_) {
464         AnimationOption longPointLeftOption;
465         longPointLeftAnimEnd_ = false;
466         longPointLeftOption.SetDuration(POINT_ANIMATION_DURATION);
467         longPointLeftOption.SetCurve(AceType::MakeRefPtr<CubicCurve>(
468             isForward ? LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY : LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY,
469             CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING));
470         AnimationUtils::Animate(longPointLeftOption,
471                                 [&]() { longPointLeftCenterX_->Set(longPointCenterX.first); },
472                                 [&]() { longPointLeftAnimEnd_ = true; });
473     }
474 
475     if (longPointRightAnimEnd_) {
476         AnimationOption longPointRightOption;
477         longPointRightAnimEnd_ = false;
478         longPointRightOption.SetDuration(POINT_ANIMATION_DURATION);
479         longPointRightOption.SetCurve(AceType::MakeRefPtr<CubicCurve>(
480             isForward ? LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY : LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY,
481             CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING));
482         AnimationUtils::Animate(longPointRightOption,
483                                 [&]() { longPointRightCenterX_->Set(longPointCenterX.second); },
484                                 [&]() { longPointRightAnimEnd_ = true; });
485     }
486 }
487 
UpdateTouchBottomAnimation(TouchBottomType touchBottomType,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX,float touchBottomRate)488 void DotIndicatorModifier::UpdateTouchBottomAnimation(TouchBottomType touchBottomType,
489     const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX,
490     float touchBottomRate)
491 {
492     AnimationOption option;
493     option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
494     option.SetCurve(AceType::MakeRefPtr<CubicCurve>(TOUCH_BOTTOM_CURVE_VELOCITY, TOUCH_BOTTOM_CURVE_MASS,
495         TOUCH_BOTTOM_CURVE_STIFFNESS, TOUCH_BOTTOM_CURVE_DAMPING));
496 
497     auto backgroundWidthDilateRatio = 1.0f;
498     auto backgroundHeightDilateRatio = 1.0f;
499 
500     if (touchBottomType != TouchBottomType::NONE) {
501         backgroundWidthDilateRatio = TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE -
502                                      TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE * vectorBlackPointCenterX_->Get().size();
503         backgroundHeightDilateRatio = TOUCH_BOTTOM_BACKGROUND_HEIGHT_MULTIPLE;
504         backgroundWidthDilateRatio = (backgroundWidthDilateRatio - 1.0f) * touchBottomRate + 1.0f;
505         backgroundHeightDilateRatio = (backgroundHeightDilateRatio - 1.0f) * touchBottomRate + 1.0f;
506     }
507     touchBottomType_ = touchBottomType;
508     AnimationUtils::Animate(option, [weak = WeakClaim(this), backgroundWidthDilateRatio, backgroundHeightDilateRatio,
509                                         vectorBlackPointCenterX, longPointCenterX]() {
510         auto modifier = weak.Upgrade();
511         CHECK_NULL_VOID(modifier);
512         modifier->backgroundWidthDilateRatio_->Set(backgroundWidthDilateRatio);
513         modifier->backgroundHeightDilateRatio_->Set(backgroundHeightDilateRatio);
514         modifier->vectorBlackPointCenterX_->Set(vectorBlackPointCenterX);
515         if (modifier->longPointLeftAnimEnd_) {
516             modifier->longPointLeftCenterX_->Set(longPointCenterX.first);
517         }
518         if (modifier->longPointRightAnimEnd_) {
519             modifier->longPointRightCenterX_->Set(longPointCenterX.second);
520         }
521     });
522 }
523 } // namespace OHOS::Ace::NG
524