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