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
34 constexpr float BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY = 0.4f;
35 constexpr float CENTER_BEZIER_CURVE_MASS = 0.0f;
36 constexpr float CENTER_BEZIER_CURVE_STIFFNESS = 1.0f;
37 constexpr float CENTER_BEZIER_CURVE_DAMPING = 1.0f;
38 constexpr uint32_t ITEM_HALF_WIDTH = 0;
39 constexpr uint32_t ITEM_HALF_HEIGHT = 1;
40 constexpr uint32_t SELECTED_ITEM_HALF_WIDTH = 2;
41 constexpr uint32_t SELECTED_ITEM_HALF_HEIGHT = 3;
42 constexpr float TOUCH_BOTTOM_CURVE_VELOCITY = 0.1f;
43 constexpr float TOUCH_BOTTOM_CURVE_MASS = 0.2f;
44 constexpr float TOUCH_BOTTOM_CURVE_STIFFNESS = 0.48f;
45 constexpr float TOUCH_BOTTOM_CURVE_DAMPING = 1.0f;
46 constexpr float TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE = 1.225f;
47 constexpr float TOUCH_BOTTOM_BACKGROUND_HEIGHT_MULTIPLE = 0.8f;
48 constexpr float TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE = 0.0125f;
49 constexpr int32_t DEFAULT_TOUCH_BOTTOM_ANIMATION_DURATION = 200;
50 constexpr int32_t DEFAULT_OPACITY_ANIMATION_DURATION = 100;
51 constexpr float LOOP_TRANSLATE_DURATION_PERCENT = 0.5f;
52 constexpr float LOOP_OPACITY_DURATION_PERCENT = 0.25f;
53 constexpr uint8_t TARGET_ALPHA = 255;
54 constexpr int32_t BLACK_POINT_DURATION = 400;
55 constexpr float DEFAULT_MINIMUM_AMPLITUDE_PX = 1.0f;
56 } // namespace
57
onDraw(DrawingContext & context)58 void DotIndicatorModifier::onDraw(DrawingContext& context)
59 {
60 if (isOverlong_) {
61 isOverlong_ = false;
62 return;
63 }
64
65 ContentProperty contentProperty;
66 contentProperty.backgroundColor = backgroundColor_->Get().ToColor();
67 contentProperty.vectorBlackPointCenterX = vectorBlackPointCenterX_->Get();
68 contentProperty.longPointLeftCenterX = longPointLeftCenterX_->Get();
69 contentProperty.longPointRightCenterX = longPointRightCenterX_->Get();
70 contentProperty.normalToHoverPointDilateRatio = normalToHoverPointDilateRatio_->Get();
71 contentProperty.hoverToNormalPointDilateRatio = hoverToNormalPointDilateRatio_->Get();
72 contentProperty.longPointDilateRatio = longPointDilateRatio_->Get();
73 contentProperty.indicatorPadding = indicatorPadding_->Get();
74 contentProperty.indicatorMargin = indicatorMargin_->Get();
75 contentProperty.itemHalfSizes = itemHalfSizes_->Get();
76 PaintBackground(context, contentProperty);
77 PaintContent(context, contentProperty);
78 }
79
PaintBackground(DrawingContext & context,const ContentProperty & contentProperty)80 void DotIndicatorModifier::PaintBackground(DrawingContext& context, const ContentProperty& contentProperty)
81 {
82 CHECK_NULL_VOID(contentProperty.backgroundColor.GetAlpha());
83 auto itemWidth = contentProperty.itemHalfSizes[ITEM_HALF_WIDTH] * 2;
84 auto itemHeight = contentProperty.itemHalfSizes[ITEM_HALF_HEIGHT] * 2;
85 auto selectedItemWidth = contentProperty.itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
86 auto selectedItemHeight = contentProperty.itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
87 auto pointNumber = static_cast<float>(contentProperty.vectorBlackPointCenterX.size());
88 float allPointDiameterSum = itemWidth * static_cast<float>(pointNumber + 1);
89 if (isCustomSize_) {
90 allPointDiameterSum = itemWidth * static_cast<float>(pointNumber - 1) + selectedItemWidth;
91 }
92 float allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()) * (pointNumber - 1);
93
94 // Background necessary property
95 float rectWidth =
96 contentProperty.indicatorPadding + allPointDiameterSum + allPointSpaceSum + contentProperty.indicatorPadding;
97 float rectHeight = contentProperty.indicatorPadding + itemHeight + contentProperty.indicatorPadding;
98 if (selectedItemHeight > itemHeight) {
99 rectHeight = contentProperty.indicatorPadding + selectedItemHeight + contentProperty.indicatorPadding;
100 }
101
102 auto widthChangeValue = (backgroundWidthDilateRatio_->Get() - 1.0f) * rectWidth;
103 auto heightChangeValue = (1.0f - backgroundHeightDilateRatio_->Get()) * rectHeight;
104 if (axis_ == Axis::VERTICAL) {
105 std::swap(widthChangeValue, heightChangeValue);
106 }
107 // Property to get the rectangle offset
108 float rectLeft =
109 axis_ == Axis::HORIZONTAL ? contentProperty.indicatorMargin.GetX() : contentProperty.indicatorMargin.GetY();
110 float rectTop =
111 axis_ == Axis::HORIZONTAL ? contentProperty.indicatorMargin.GetY() : contentProperty.indicatorMargin.GetX();
112 // Adapter circle and rect
113 float rectRight = rectLeft + (axis_ == Axis::HORIZONTAL ? rectWidth : rectHeight);
114 float rectBottom = rectTop + (axis_ == Axis::HORIZONTAL ? rectHeight : rectWidth);
115
116 if (axis_ == Axis::HORIZONTAL) {
117 if (touchBottomType_ == TouchBottomType::START) {
118 rectLeft -= widthChangeValue;
119 }
120 if (touchBottomType_ == TouchBottomType::END) {
121 rectRight += widthChangeValue;
122 }
123 rectTop = rectTop + heightChangeValue * 0.5f;
124 rectBottom = rectBottom - heightChangeValue * 0.5f;
125 rectHeight -= heightChangeValue;
126 } else {
127 if (touchBottomType_ == TouchBottomType::START) {
128 rectTop -= heightChangeValue;
129 }
130 if (touchBottomType_ == TouchBottomType::END) {
131 rectBottom += heightChangeValue;
132 }
133 rectLeft = rectLeft + widthChangeValue * 0.5f;
134 rectRight = rectRight - widthChangeValue * 0.5f;
135 rectWidth -= widthChangeValue;
136 }
137 // Paint background
138 RSCanvas& canvas = context.canvas;
139 RSBrush brush;
140 brush.SetAntiAlias(true);
141 brush.SetColor(ToRSColor(contentProperty.backgroundColor));
142 canvas.AttachBrush(brush);
143 auto radius = axis_ == Axis::HORIZONTAL ? rectHeight : rectWidth;
144 canvas.DrawRoundRect({ { rectLeft, rectTop, rectRight, rectBottom }, radius, radius });
145 canvas.DetachBrush();
146 }
147
GetTouchBottomCenterX(ContentProperty & contentProperty)148 std::pair<float, float> DotIndicatorModifier::GetTouchBottomCenterX(ContentProperty& contentProperty)
149 {
150 float leftCenterX = contentProperty.longPointLeftCenterX;
151 float rightCenterX = contentProperty.longPointRightCenterX;
152
153 if (isCustomSize_ || contentProperty.vectorBlackPointCenterX.empty()) {
154 return { leftCenterX, rightCenterX };
155 }
156 auto totalCount = contentProperty.vectorBlackPointCenterX.size();
157 // 2.0 means get the long point radius
158 float radius = (rightCenterX - leftCenterX) / 2.0f;
159 bool isLeftTouchBottom = (currentIndex_ == static_cast<int32_t>(totalCount) - 1);
160 bool isRightTouchBottom = (currentIndex_ == 0);
161
162 if ((animationState_ == TouchBottomAnimationStage::STAGE_SHRINKT_TO_BLACK_POINT && isLeftTouchBottom) ||
163 (animationState_ == TouchBottomAnimationStage::STAGE_EXPAND_TO_LONG_POINT && isRightTouchBottom)) {
164 leftCenterX = contentProperty.vectorBlackPointCenterX[0] - radius;
165 rightCenterX = contentProperty.vectorBlackPointCenterX[0] + radius;
166 } else if ((animationState_ == TouchBottomAnimationStage::STAGE_EXPAND_TO_LONG_POINT && isLeftTouchBottom) ||
167 (animationState_ == TouchBottomAnimationStage::STAGE_SHRINKT_TO_BLACK_POINT && isRightTouchBottom)) {
168 leftCenterX = contentProperty.vectorBlackPointCenterX[totalCount - 1] - radius;
169 rightCenterX = contentProperty.vectorBlackPointCenterX[totalCount - 1] + radius;
170 }
171
172 return { leftCenterX, rightCenterX };
173 }
174
PaintContent(DrawingContext & context,ContentProperty & contentProperty)175 void DotIndicatorModifier::PaintContent(DrawingContext& context, ContentProperty& contentProperty)
176 {
177 RSCanvas& canvas = context.canvas;
178 OffsetF selectedCenter = {};
179 auto totalCount = contentProperty.vectorBlackPointCenterX.size();
180 if (totalCount == 0 && NearZero(contentProperty.longPointLeftCenterX) &&
181 NearZero(contentProperty.longPointRightCenterX)) {
182 return;
183 }
184
185 for (size_t i = 0; i < totalCount; ++i) {
186 LinearVector<float> itemHalfSizes = GetItemHalfSizes(i, contentProperty);
187 OffsetF center = { contentProperty.vectorBlackPointCenterX[i], centerY_ };
188 if (static_cast<int32_t>(i) != currentIndex_) {
189 PaintUnselectedIndicator(canvas, center, itemHalfSizes, false, LinearColor(unselectedColor_->Get()));
190 } else {
191 selectedCenter = center;
192 PaintUnselectedIndicator(canvas, center, itemHalfSizes, isCustomSize_,
193 LinearColor(unselectedColor_->Get()));
194 }
195 }
196
197 auto [leftCenterX, rightCenterX] = GetTouchBottomCenterX(contentProperty);
198
199 OffsetF leftCenter = { leftCenterX, centerY_ };
200 OffsetF rightCenter = { rightCenterX, centerY_ };
201 OffsetF centerDistance = rightCenter - leftCenter;
202 OffsetF centerDilateDistance = centerDistance * contentProperty.longPointDilateRatio;
203 leftCenter -= (centerDilateDistance - centerDistance) * 0.5;
204 rightCenter += (centerDilateDistance - centerDistance) * 0.5;
205 PaintSelectedIndicator(canvas, leftCenter, rightCenter,
206 contentProperty.itemHalfSizes * contentProperty.longPointDilateRatio);
207
208 bool isLeftTouchBottom = (currentIndex_ == static_cast<int32_t>(totalCount) - 1);
209 bool isRightTouchBottom = (currentIndex_ == 0);
210 bool isTouchBottom = (isLeftTouchBottom || isRightTouchBottom);
211 if (!isTouchBottom || totalCount == 0 || !isTouchBottomLoop_) {
212 return;
213 }
214
215 size_t index = 0;
216 if (isRightTouchBottom) {
217 index = totalCount - 1;
218 }
219 LinearVector<float> itemHalfSizes = GetItemHalfSizes(index, contentProperty);
220 OffsetF center = { contentProperty.vectorBlackPointCenterX[index], centerY_ };
221 PaintUnselectedIndicator(canvas, center, itemHalfSizes, false, touchBottomPointColor_->Get());
222 }
223
GetItemHalfSizes(size_t index,ContentProperty & contentProperty)224 LinearVector<float> DotIndicatorModifier::GetItemHalfSizes(size_t index, ContentProperty& contentProperty)
225 {
226 if (normalToHoverIndex_.has_value() && normalToHoverIndex_ == index) {
227 return contentProperty.itemHalfSizes * contentProperty.normalToHoverPointDilateRatio;
228 }
229 if (hoverToNormalIndex_.has_value() && hoverToNormalIndex_ == index) {
230 return contentProperty.itemHalfSizes * contentProperty.hoverToNormalPointDilateRatio;
231 }
232 return contentProperty.itemHalfSizes;
233 }
234
PaintUnselectedIndicator(RSCanvas & canvas,const OffsetF & center,const LinearVector<float> & itemHalfSizes,bool currentIndexFlag,const LinearColor & indicatorColor)235 void DotIndicatorModifier::PaintUnselectedIndicator(RSCanvas& canvas, const OffsetF& center,
236 const LinearVector<float>& itemHalfSizes, bool currentIndexFlag, const LinearColor& indicatorColor)
237 {
238 RSBrush brush;
239 brush.SetAntiAlias(true);
240 brush.SetColor(ToRSColor(indicatorColor));
241 canvas.AttachBrush(brush);
242 if (!NearEqual(itemHalfSizes[ITEM_HALF_WIDTH], itemHalfSizes[ITEM_HALF_HEIGHT]) || currentIndexFlag ||
243 !isCustomSize_) {
244 float rectItemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * 2;
245 float rectItemHeight = itemHalfSizes[ITEM_HALF_HEIGHT] * 2;
246 float rectLeft =
247 (axis_ == Axis::HORIZONTAL ? center.GetX() - rectItemWidth * 0.5 : center.GetY() - rectItemHeight * 0.5);
248 float rectTop =
249 (axis_ == Axis::HORIZONTAL ? center.GetY() - rectItemHeight * 0.5 : center.GetX() - rectItemWidth * 0.5);
250 float rectRight =
251 (axis_ == Axis::HORIZONTAL ? center.GetX() + rectItemWidth * 0.5 : center.GetY() + rectItemHeight * 0.5);
252 float rectBottom =
253 (axis_ == Axis::HORIZONTAL ? center.GetY() + rectItemHeight * 0.5 : center.GetX() + rectItemWidth * 0.5);
254
255 if (rectItemHeight > rectItemWidth || !isCustomSize_) {
256 canvas.DrawRoundRect({ { rectLeft, rectTop, rectRight, rectBottom }, rectItemWidth, rectItemWidth });
257 } else if (rectItemHeight < rectItemWidth) {
258 canvas.DrawRoundRect({ { rectLeft, rectTop, rectRight, rectBottom }, rectItemHeight, rectItemHeight });
259 } else {
260 float customPointX = axis_ == Axis::HORIZONTAL ? center.GetX() : center.GetY();
261 float customPointY = axis_ == Axis::HORIZONTAL ? center.GetY() : center.GetX();
262 canvas.DrawCircle({ customPointX, customPointY }, rectItemHeight * 0.5);
263 }
264 } else {
265 float pointX = axis_ == Axis::HORIZONTAL ? center.GetX() : center.GetY();
266 float pointY = axis_ == Axis::HORIZONTAL ? center.GetY() : center.GetX();
267 canvas.DrawCircle({ pointX, pointY }, itemHalfSizes[ITEM_HALF_HEIGHT]);
268 }
269 canvas.DetachBrush();
270 }
271
PaintSelectedIndicator(RSCanvas & canvas,const OffsetF & leftCenter,const OffsetF & rightCenter,const LinearVector<float> & itemHalfSizes)272 void DotIndicatorModifier::PaintSelectedIndicator(RSCanvas& canvas, const OffsetF& leftCenter,
273 const OffsetF& rightCenter, const LinearVector<float>& itemHalfSizes)
274 {
275 RSBrush brush;
276 brush.SetAntiAlias(true);
277 brush.SetColor(ToRSColor(selectedColor_->Get()));
278 canvas.AttachBrush(brush);
279
280 float rectLeft = (axis_ == Axis::HORIZONTAL ? leftCenter.GetX() - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]
281 : leftCenter.GetY() - itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]);
282
283 float rectTop = (axis_ == Axis::HORIZONTAL ? leftCenter.GetY() - itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]
284 : leftCenter.GetX() - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]);
285 float rectRight = (axis_ == Axis::HORIZONTAL ? rightCenter.GetX() + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]
286 : rightCenter.GetY() + itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]);
287
288 float rectBottom = (axis_ == Axis::HORIZONTAL ? rightCenter.GetY() + itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT]
289 : rightCenter.GetX() + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH]);
290
291 float rectSelectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
292 float rectSelectedItemHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
293
294 if (rectSelectedItemHeight > rectSelectedItemWidth && !isCustomSize_) {
295 canvas.DrawRoundRect(
296 { { rectLeft, rectTop, rectRight, rectBottom }, rectSelectedItemWidth, rectSelectedItemWidth });
297 } else {
298 canvas.DrawRoundRect(
299 { { rectLeft, rectTop, rectRight, rectBottom }, rectSelectedItemHeight, rectSelectedItemHeight });
300 }
301 canvas.DetachBrush();
302 }
303
PaintMask(DrawingContext & context)304 void DotIndicatorModifier::PaintMask(DrawingContext& context)
305 {
306 RSCanvas& canvas = context.canvas;
307
308 RSBrush brush;
309 brush.SetAntiAlias(true);
310 canvas.Save();
311
312 std::vector<RSColorQuad> colors;
313 colors.push_back(0x00000000);
314 colors.push_back(0xff000000);
315 colors.push_back(0xff000000);
316
317 RSPoint startPt = { offset_.GetX(), offset_.GetY() };
318 RSPoint endPt = { offset_.GetX(), offset_.GetY() };
319 startPt -= axis_ == Axis::HORIZONTAL ? RSPoint(0, (9.0_vp).ConvertToPx()) : RSPoint((9.0_vp).ConvertToPx(), 0);
320 endPt += axis_ == Axis::HORIZONTAL ? RSPoint(0, (15.0_vp).ConvertToPx()) : RSPoint((15.0_vp).ConvertToPx(), 0);
321
322 std::vector<float> pos = { 0.0f, 0.75f, 1.0f };
323
324 brush.SetShaderEffect(RSShaderEffect::CreateLinearGradient(startPt, endPt, colors, pos, RSTileMode::CLAMP));
325 canvas.DrawRect({ startPt.GetX(), startPt.GetY(), endPt.GetX(), endPt.GetY() });
326 }
327
UpdateShrinkPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)328 void DotIndicatorModifier::UpdateShrinkPaintProperty(
329 const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
330 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
331 {
332 indicatorMargin_->Set(margin);
333 indicatorPadding_->Set(static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx()));
334
335 if (longPointLeftAnimEnd_ && longPointRightAnimEnd_) {
336 vectorBlackPointCenterX_->Set(vectorBlackPointCenterX);
337 longPointLeftCenterX_->Set(longPointCenterX.first);
338 longPointRightCenterX_->Set(longPointCenterX.second);
339 }
340
341 itemHalfSizes_->Set(normalItemHalfSizes);
342 normalToHoverPointDilateRatio_->Set(1.0f);
343 hoverToNormalPointDilateRatio_->Set(1.0f);
344 longPointDilateRatio_->Set(1.0f);
345 backgroundWidthDilateRatio_->Set(1.0f);
346 backgroundHeightDilateRatio_->Set(1.0f);
347 }
348
UpdateDilatePaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)349 void DotIndicatorModifier::UpdateDilatePaintProperty(
350 const LinearVector<float>& hoverItemHalfSizes, const LinearVector<float>& vectorBlackPointCenterX,
351 const std::pair<float, float>& longPointCenterX)
352 {
353 indicatorMargin_->Set({ 0, 0 });
354 indicatorPadding_->Set(static_cast<float>(INDICATOR_PADDING_HOVER.ConvertToPx()));
355
356 vectorBlackPointCenterX_->Set(vectorBlackPointCenterX);
357 if (longPointLeftAnimEnd_ && longPointRightAnimEnd_) {
358 longPointLeftCenterX_->Set(longPointCenterX.first);
359 longPointRightCenterX_->Set(longPointCenterX.second);
360 }
361 itemHalfSizes_->Set(hoverItemHalfSizes);
362 backgroundWidthDilateRatio_->Set(1.0f);
363 backgroundHeightDilateRatio_->Set(1.0f);
364 }
365
UpdateBackgroundColor(const Color & backgroundColor)366 void DotIndicatorModifier::UpdateBackgroundColor(const Color& backgroundColor)
367 {
368 backgroundColor_->Set(LinearColor(backgroundColor));
369 }
370
UpdateNormalPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)371 void DotIndicatorModifier::UpdateNormalPaintProperty(
372 const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
373 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
374 {
375 auto swiperTheme = GetSwiperIndicatorTheme();
376 CHECK_NULL_VOID(swiperTheme);
377 auto backgroundColor = indicatorMask_ ?
378 swiperTheme->GetPressedColor() :
379 swiperTheme->GetHoverColor().ChangeOpacity(0);
380 UpdateShrinkPaintProperty(margin, normalItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
381 UpdateBackgroundColor(backgroundColor);
382 }
383
UpdateHoverPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)384 void DotIndicatorModifier::UpdateHoverPaintProperty(
385 const LinearVector<float>& hoverItemHalfSizes,
386 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
387 {
388 auto swiperTheme = GetSwiperIndicatorTheme();
389 CHECK_NULL_VOID(swiperTheme);
390 auto backgroundColor = swiperTheme->GetHoverColor();
391 UpdateDilatePaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
392 UpdateBackgroundColor(backgroundColor);
393 }
394
UpdatePressPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)395 void DotIndicatorModifier::UpdatePressPaintProperty(
396 const LinearVector<float>& hoverItemHalfSizes,
397 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
398 {
399 auto swiperTheme = GetSwiperIndicatorTheme();
400 CHECK_NULL_VOID(swiperTheme);
401 auto backgroundColor = swiperTheme->GetPressedColor();
402 UpdateDilatePaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
403 UpdateBackgroundColor(backgroundColor);
404 }
405
UpdateNormalToHoverPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)406 void DotIndicatorModifier::UpdateNormalToHoverPaintProperty(
407 const LinearVector<float>& hoverItemHalfSizes, const LinearVector<float>& vectorBlackPointCenterX,
408 const std::pair<float, float>& longPointCenterX)
409 {
410 AnimationOption option;
411 option.SetDuration(COMPONENT_DILATE_ANIMATION_DURATION);
412 option.SetCurve(Curves::SHARP);
413 longPointLeftAnimEnd_ = true;
414 longPointRightAnimEnd_ = true;
415 AnimationUtils::Animate(option, [weak = WeakClaim(this), hoverItemHalfSizes, vectorBlackPointCenterX,
416 longPointCenterX]() {
417 auto modifier = weak.Upgrade();
418 CHECK_NULL_VOID(modifier);
419 modifier->UpdateHoverPaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
420 });
421 }
422
UpdateHoverToNormalPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)423 void DotIndicatorModifier::UpdateHoverToNormalPaintProperty(
424 const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
425 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
426 {
427 AnimationOption option;
428 option.SetDuration(COMPONENT_SHRINK_ANIMATION_DURATION);
429 option.SetCurve(Curves::SHARP);
430 longPointLeftAnimEnd_ = true;
431 longPointRightAnimEnd_ = true;
432 AnimationUtils::Animate(option, [weak = WeakClaim(this), margin, normalItemHalfSizes, vectorBlackPointCenterX,
433 longPointCenterX]() {
434 auto modifier = weak.Upgrade();
435 CHECK_NULL_VOID(modifier);
436 modifier->UpdateNormalPaintProperty(margin, normalItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
437 });
438 }
439
UpdateNormalToPressPaintProperty(const LinearVector<float> & hoverItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)440 void DotIndicatorModifier::UpdateNormalToPressPaintProperty(
441 const LinearVector<float>& hoverItemHalfSizes, const LinearVector<float>& vectorBlackPointCenterX,
442 const std::pair<float, float>& longPointCenterX)
443 {
444 AnimationOption option;
445 option.SetDuration(COMPONENT_DILATE_ANIMATION_DURATION);
446 option.SetCurve(Curves::SHARP);
447 longPointLeftAnimEnd_ = true;
448 longPointRightAnimEnd_ = true;
449 AnimationUtils::Animate(option, [weak = WeakClaim(this), hoverItemHalfSizes, vectorBlackPointCenterX,
450 longPointCenterX]() {
451 auto modifier = weak.Upgrade();
452 CHECK_NULL_VOID(modifier);
453 modifier->UpdatePressPaintProperty(hoverItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
454 });
455 }
456
UpdatePressToNormalPaintProperty(const OffsetF & margin,const LinearVector<float> & normalItemHalfSizes,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)457 void DotIndicatorModifier::UpdatePressToNormalPaintProperty(
458 const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
459 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
460 {
461 AnimationOption option;
462 option.SetDuration(COMPONENT_SHRINK_ANIMATION_DURATION);
463 option.SetCurve(Curves::SHARP);
464 AnimationUtils::Animate(option, [weak = WeakClaim(this), margin, normalItemHalfSizes, vectorBlackPointCenterX,
465 longPointCenterX]() {
466 auto modifier = weak.Upgrade();
467 CHECK_NULL_VOID(modifier);
468 modifier->UpdateNormalPaintProperty(margin, normalItemHalfSizes, vectorBlackPointCenterX, longPointCenterX);
469 });
470 }
471
UpdateHoverAndPressConversionPaintProperty()472 void DotIndicatorModifier::UpdateHoverAndPressConversionPaintProperty()
473 {
474 auto swiperTheme = GetSwiperIndicatorTheme();
475 CHECK_NULL_VOID(swiperTheme);
476 Color backgroundColor = isPressed_ ? swiperTheme->GetPressedColor() : swiperTheme->GetHoverColor();
477 AnimationOption option;
478 option.SetDuration(MOUSE_PRESS_ANIMATION_DURATION);
479 option.SetCurve(Curves::SHARP);
480 AnimationUtils::Animate(option, [weak = WeakClaim(this), backgroundColor]() {
481 auto modifier = weak.Upgrade();
482 CHECK_NULL_VOID(modifier);
483 modifier->UpdateBackgroundColor(backgroundColor);
484 });
485 }
486
UpdateNormalToHoverPointDilateRatio()487 void DotIndicatorModifier::UpdateNormalToHoverPointDilateRatio()
488 {
489 normalToHoverPointDilateRatio_->Set(1.0f);
490 AnimationOption option;
491 option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
492 option.SetCurve(Curves::SHARP);
493 AnimationUtils::Animate(option, [&]() { normalToHoverPointDilateRatio_->Set(INDICATOR_ZOOM_IN_SCALE); });
494 }
495
UpdateHoverToNormalPointDilateRatio()496 void DotIndicatorModifier::UpdateHoverToNormalPointDilateRatio()
497 {
498 hoverToNormalPointDilateRatio_->Set(normalToHoverPointDilateRatio_->Get());
499 AnimationOption option;
500 option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
501 option.SetCurve(Curves::SHARP);
502 AnimationUtils::Animate(option, [&]() { hoverToNormalPointDilateRatio_->Set(1.0f); });
503 }
504
UpdateLongPointDilateRatio()505 void DotIndicatorModifier::UpdateLongPointDilateRatio()
506 {
507 AnimationOption option;
508 option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
509 option.SetCurve(Curves::SHARP);
510 if (longPointIsHover_) {
511 AnimationUtils::Animate(option, [&]() { longPointDilateRatio_->Set(INDICATOR_ZOOM_IN_SCALE); });
512 } else {
513 AnimationUtils::Animate(option, [&]() { longPointDilateRatio_->Set(1.0f); });
514 }
515 }
516
UpdateAllPointCenterXAnimation(GestureState gestureState,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX)517 void DotIndicatorModifier::UpdateAllPointCenterXAnimation(GestureState gestureState,
518 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX)
519 {
520 AnimationOption blackPointOption;
521 blackPointOption.SetDuration(BLACK_POINT_DURATION);
522 blackPointOption.SetCurve(AceType::MakeRefPtr<CubicCurve>(BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY,
523 CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING));
524 AnimationUtils::Animate(blackPointOption, [&]() { vectorBlackPointCenterX_->Set(vectorBlackPointCenterX); });
525
526 // normal page turning
527 AnimationOption optionHead;
528 RefPtr<Curve> curve = headCurve_;
529 optionHead.SetCurve(curve);
530 optionHead.SetDuration(animationDuration_);
531
532 AnimationOption optionTail;
533 // velocity:0, mass:1, stiffness:81, damping:11
534 optionTail.SetCurve(AceType::MakeRefPtr<InterpolatingSpring>(0, 1, 81, 11));
535 optionTail.SetDuration(animationDuration_);
536 AnimationOption optionLeft = optionTail;
537 AnimationOption optionRight = optionHead;
538
539 if (gestureState == GestureState::GESTURE_STATE_RELEASE_LEFT) {
540 optionLeft = optionHead;
541 optionRight = optionTail;
542 }
543
544 if (longPointLeftAnimEnd_ && longPointRightAnimEnd_) {
545 longPointLeftAnimEnd_ = false;
546 longPointRightAnimEnd_ = false;
547 auto weak = WeakClaim(this);
548 AnimationUtils::StartAnimation(optionLeft, [weak, longPointCenterX]() {
549 auto modifier = weak.Upgrade();
550 CHECK_NULL_VOID(modifier);
551 modifier->longPointLeftCenterX_->Set(longPointCenterX.first);
552 }, [weak]() {
553 auto modifier = weak.Upgrade();
554 CHECK_NULL_VOID(modifier);
555 modifier->longPointLeftAnimEnd_ = true;
556 });
557
558 AnimationUtils::StartAnimation(optionRight, [weak, longPointCenterX]() {
559 auto modifier = weak.Upgrade();
560 CHECK_NULL_VOID(modifier);
561 modifier->longPointRightCenterX_->Set(longPointCenterX.second);
562 }, [weak]() {
563 auto modifier = weak.Upgrade();
564 CHECK_NULL_VOID(modifier);
565 modifier->longPointRightAnimEnd_ = true;
566 });
567 }
568 }
569
UpdateTouchBottomAnimation(TouchBottomType touchBottomType,const LinearVector<float> & vectorBlackPointCenterX,const std::pair<float,float> & longPointCenterX,float touchBottomRate)570 void DotIndicatorModifier::UpdateTouchBottomAnimation(TouchBottomType touchBottomType,
571 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX,
572 float touchBottomRate)
573 {
574 AnimationOption option;
575 option.SetDuration(POINT_HOVER_ANIMATION_DURATION);
576 option.SetCurve(AceType::MakeRefPtr<CubicCurve>(TOUCH_BOTTOM_CURVE_VELOCITY, TOUCH_BOTTOM_CURVE_MASS,
577 TOUCH_BOTTOM_CURVE_STIFFNESS, TOUCH_BOTTOM_CURVE_DAMPING));
578
579 auto backgroundWidthDilateRatio = 1.0f;
580 auto backgroundHeightDilateRatio = 1.0f;
581
582 if (touchBottomType != TouchBottomType::NONE) {
583 backgroundWidthDilateRatio = TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE -
584 TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE * vectorBlackPointCenterX_->Get().size();
585 backgroundHeightDilateRatio = TOUCH_BOTTOM_BACKGROUND_HEIGHT_MULTIPLE;
586 backgroundWidthDilateRatio = (backgroundWidthDilateRatio - 1.0f) * touchBottomRate + 1.0f;
587 backgroundHeightDilateRatio = (backgroundHeightDilateRatio - 1.0f) * touchBottomRate + 1.0f;
588 }
589 touchBottomType_ = touchBottomType;
590 AnimationUtils::Animate(option, [weak = WeakClaim(this), backgroundWidthDilateRatio, backgroundHeightDilateRatio,
591 vectorBlackPointCenterX, longPointCenterX]() {
592 auto modifier = weak.Upgrade();
593 CHECK_NULL_VOID(modifier);
594 modifier->backgroundWidthDilateRatio_->Set(backgroundWidthDilateRatio);
595 modifier->backgroundHeightDilateRatio_->Set(backgroundHeightDilateRatio);
596 modifier->vectorBlackPointCenterX_->Set(vectorBlackPointCenterX);
597 if (modifier->longPointLeftAnimEnd_) {
598 modifier->longPointLeftCenterX_->Set(longPointCenterX.first);
599 }
600 if (modifier->longPointRightAnimEnd_) {
601 modifier->longPointRightCenterX_->Set(longPointCenterX.second);
602 }
603 });
604 }
605
PlayBlackPointsAnimation(const LinearVector<float> & vectorBlackPointCenterX)606 void DotIndicatorModifier::PlayBlackPointsAnimation(const LinearVector<float>& vectorBlackPointCenterX)
607 {
608 auto curve = AceType::MakeRefPtr<CubicCurve>(BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY, CENTER_BEZIER_CURVE_MASS,
609 CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING);
610 AnimationOption option;
611 option.SetCurve(curve);
612 option.SetDuration(animationDuration_);
613 AnimationUtils::StartAnimation(option, [&]() { vectorBlackPointCenterX_->Set(vectorBlackPointCenterX); });
614 }
615
PlayOpacityAnimation()616 void DotIndicatorModifier::PlayOpacityAnimation()
617 {
618 AnimationOption optionOpacity;
619 // x0:0.33, y0:0, x1:0.67, y1:1
620 optionOpacity.SetCurve(AceType::MakeRefPtr<CubicCurve>(0.33, 0, 0.67, 1));
621 optionOpacity.SetDuration(GetLoopOpacityDuration());
622 isSelectedColorAnimEnd_ = false;
623 isTouchBottomLoop_ = true;
624 selectedColor_->Set(LinearColor(selectedColor_->Get().BlendOpacity(0.0f)));
625 auto weak = WeakClaim(this);
626 AnimationUtils::StartAnimation(optionOpacity, [weak]() {
627 auto modifier = weak.Upgrade();
628 CHECK_NULL_VOID(modifier);
629 auto color = modifier->selectedColor_->Get();
630 auto targetColor =
631 LinearColor(Color::FromARGB(TARGET_ALPHA, color.GetRed(), color.GetGreen(), color.GetBlue()));
632 modifier->selectedColor_->Set(targetColor);
633 modifier->touchBottomPointColor_->Set(LinearColor(modifier->touchBottomPointColor_->Get().BlendOpacity(0)));
634 }, [weak]() {
635 auto modifier = weak.Upgrade();
636 CHECK_NULL_VOID(modifier);
637 modifier->touchBottomPointColor_->Set(LinearColor(modifier->unselectedColor_->Get()));
638 modifier->isTouchBottomLoop_ = false;
639 modifier->isSelectedColorAnimEnd_ = true;
640 });
641 }
642
GetLoopTranslateDuration() const643 int32_t DotIndicatorModifier::GetLoopTranslateDuration() const
644 {
645 if (InstanceOf<InterpolatingSpring>(headCurve_)) {
646 return DEFAULT_TOUCH_BOTTOM_ANIMATION_DURATION;
647 }
648
649 return static_cast<int32_t>(static_cast<float>(animationDuration_) * LOOP_TRANSLATE_DURATION_PERCENT);
650 }
651
GetLoopOpacityDuration() const652 int32_t DotIndicatorModifier::GetLoopOpacityDuration() const
653 {
654 if (InstanceOf<InterpolatingSpring>(headCurve_)) {
655 return DEFAULT_OPACITY_ANIMATION_DURATION;
656 }
657
658 return static_cast<int32_t>(static_cast<float>(animationDuration_) * LOOP_OPACITY_DURATION_PERCENT);
659 }
660
PlayTouchBottomAnimation(const std::vector<std::pair<float,float>> & longPointCenterX,TouchBottomTypeLoop touchBottomTypeLoop,const LinearVector<float> & vectorBlackPointCenterX)661 void DotIndicatorModifier::PlayTouchBottomAnimation(const std::vector<std::pair<float, float>>& longPointCenterX,
662 TouchBottomTypeLoop touchBottomTypeLoop, const LinearVector<float>& vectorBlackPointCenterX)
663 {
664 if (vectorBlackPointCenterX.empty()) {
665 return;
666 }
667
668 AnimationOption optionBottom;
669 // x0:0.33, y0:0, x1:0.67, y1:1
670 optionBottom.SetCurve(AceType::MakeRefPtr<CubicCurve>(0.33, 0, 0.67, 1));
671 optionBottom.SetDuration(GetLoopTranslateDuration());
672
673 auto weak = WeakClaim(this);
674 FinishCallback bottomFinishCallback = [weak, optionBottom, longPointCenterX, vectorBlackPointCenterX,
675 touchBottomTypeLoop]() {
676 auto modifier = weak.Upgrade();
677 CHECK_NULL_VOID(modifier);
678 modifier->animationState_ = TouchBottomAnimationStage::STAGE_NONE;
679 if (!(modifier->ifNeedFinishCallback_)) {
680 return;
681 }
682 modifier->animationState_ = TouchBottomAnimationStage::STAGE_EXPAND_TO_LONG_POINT;
683 modifier->PlayOpacityAnimation();
684 if (touchBottomTypeLoop == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT) {
685 modifier->longPointLeftCenterX_->Set(vectorBlackPointCenterX[vectorBlackPointCenterX.size() - 1]);
686 modifier->longPointRightCenterX_->Set(vectorBlackPointCenterX[vectorBlackPointCenterX.size() - 1]);
687 } else if (touchBottomTypeLoop == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT) {
688 modifier->longPointLeftCenterX_->Set(vectorBlackPointCenterX[0]);
689 modifier->longPointRightCenterX_->Set(vectorBlackPointCenterX[0]);
690 }
691
692 AnimationUtils::StartAnimation(optionBottom, [weak, longPointCenterX]() {
693 auto modifier = weak.Upgrade();
694 CHECK_NULL_VOID(modifier);
695 modifier->longPointLeftCenterX_->Set(longPointCenterX[1].first);
696 modifier->longPointRightCenterX_->Set(longPointCenterX[1].second);
697 }, [weak]() {
698 auto modifier = weak.Upgrade();
699 CHECK_NULL_VOID(modifier);
700 modifier->longPointLeftAnimEnd_ = true;
701 modifier->longPointRightAnimEnd_ = true;
702 modifier->animationState_ = TouchBottomAnimationStage::STAGE_NONE;
703 });
704 };
705 if (longPointLeftAnimEnd_ && longPointRightAnimEnd_) {
706 longPointLeftAnimEnd_ = false;
707 longPointRightAnimEnd_ = false;
708 ifNeedFinishCallback_ = true;
709 animationState_ = TouchBottomAnimationStage::STAGE_SHRINKT_TO_BLACK_POINT;
710 touchBottomPointColor_->Set(LinearColor(selectedColor_->Get()));
711 AnimationUtils::StartAnimation(optionBottom, [weak, longPointCenterX]() {
712 auto modifier = weak.Upgrade();
713 CHECK_NULL_VOID(modifier);
714 modifier->longPointLeftCenterX_->Set(longPointCenterX[0].first);
715 modifier->longPointRightCenterX_->Set(longPointCenterX[0].second);
716 }, bottomFinishCallback);
717 }
718 }
719
CalculateMinimumAmplitudeRatio(const std::vector<std::pair<float,float>> & longPointCenterX,GestureState gestureState) const720 float DotIndicatorModifier::CalculateMinimumAmplitudeRatio(
721 const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState) const
722 {
723 auto minimumAmplitudeRatio =
724 NearEqual(longPointCenterX[0].first, longPointLeftCenterX_->Get())
725 ? InterpolatingSpring::DEFAULT_INTERPOLATING_SPRING_AMPLITUDE_RATIO
726 : DEFAULT_MINIMUM_AMPLITUDE_PX / std::abs(longPointCenterX[0].first - longPointLeftCenterX_->Get());
727 if (gestureState == GestureState::GESTURE_STATE_RELEASE_LEFT) {
728 minimumAmplitudeRatio =
729 NearEqual(longPointCenterX[0].second, longPointRightCenterX_->Get())
730 ? InterpolatingSpring::DEFAULT_INTERPOLATING_SPRING_AMPLITUDE_RATIO
731 : DEFAULT_MINIMUM_AMPLITUDE_PX / std::abs(longPointCenterX[0].second - longPointRightCenterX_->Get());
732 }
733 return std::max(minimumAmplitudeRatio, InterpolatingSpring::DEFAULT_INTERPOLATING_SPRING_AMPLITUDE_RATIO);
734 }
735
PlayLongPointAnimation(const std::vector<std::pair<float,float>> & longPointCenterX,GestureState gestureState,TouchBottomTypeLoop touchBottomTypeLoop,const LinearVector<float> & vectorBlackPointCenterX,bool isNormal)736 void DotIndicatorModifier::PlayLongPointAnimation(const std::vector<std::pair<float, float>>& longPointCenterX,
737 GestureState gestureState, TouchBottomTypeLoop touchBottomTypeLoop,
738 const LinearVector<float>& vectorBlackPointCenterX, bool isNormal)
739 {
740 if (longPointCenterX.empty()) {
741 return;
742 }
743 // touch bottom
744 if (longPointCenterX.size() > 1) {
745 PlayTouchBottomAnimation(longPointCenterX, touchBottomTypeLoop, vectorBlackPointCenterX);
746 return;
747 }
748 // normal page turning
749 AnimationOption optionHead;
750 RefPtr<Curve> curve = headCurve_;
751 optionHead.SetCurve(curve);
752 optionHead.SetDuration(animationDuration_);
753
754 AnimationOption optionTail;
755 // velocity:0, mass:1, stiffness:81, damping:11
756 auto interpolatingSpring = AceType::MakeRefPtr<InterpolatingSpring>(0, 1, 81, 11);
757 if (isNormal) {
758 interpolatingSpring->UpdateMinimumAmplitudeRatio(
759 CalculateMinimumAmplitudeRatio(longPointCenterX, gestureState));
760 }
761 optionTail.SetCurve(interpolatingSpring);
762 optionTail.SetDuration(animationDuration_);
763 AnimationOption optionLeft = optionTail;
764 AnimationOption optionRight = optionHead;
765
766 if (gestureState == GestureState::GESTURE_STATE_RELEASE_LEFT) {
767 optionLeft = optionHead;
768 optionRight = optionTail;
769 }
770
771 if (longPointLeftAnimEnd_ && longPointRightAnimEnd_) {
772 longPointLeftAnimEnd_ = false;
773 longPointRightAnimEnd_ = false;
774 auto weak = WeakClaim(this);
775 AnimationUtils::StartAnimation(optionLeft, [weak, longPointCenterX]() {
776 auto modifier = weak.Upgrade();
777 CHECK_NULL_VOID(modifier);
778 modifier->longPointLeftCenterX_->Set(longPointCenterX[0].first);
779 }, [weak]() {
780 auto modifier = weak.Upgrade();
781 CHECK_NULL_VOID(modifier);
782 modifier->longPointLeftAnimEnd_ = true;
783 });
784
785 AnimationUtils::StartAnimation(optionRight, [weak, longPointCenterX]() {
786 auto modifier = weak.Upgrade();
787 CHECK_NULL_VOID(modifier);
788 modifier->longPointRightCenterX_->Set(longPointCenterX[0].second);
789 }, [weak]() {
790 auto modifier = weak.Upgrade();
791 CHECK_NULL_VOID(modifier);
792 modifier->longPointRightAnimEnd_ = true;
793 });
794 }
795 }
796
PlayIndicatorAnimation(const LinearVector<float> & vectorBlackPointCenterX,const std::vector<std::pair<float,float>> & longPointCenterX,GestureState gestureState,TouchBottomTypeLoop touchBottomTypeLoop)797 void DotIndicatorModifier::PlayIndicatorAnimation(const LinearVector<float>& vectorBlackPointCenterX,
798 const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState,
799 TouchBottomTypeLoop touchBottomTypeLoop)
800 {
801 StopAnimation();
802 isTouchBottomLoop_ = false;
803 animationState_ = TouchBottomAnimationStage::STAGE_NONE;
804 PlayBlackPointsAnimation(vectorBlackPointCenterX);
805 PlayLongPointAnimation(longPointCenterX, gestureState, touchBottomTypeLoop, vectorBlackPointCenterX);
806 }
807
StopAnimation(bool ifImmediately)808 void DotIndicatorModifier::StopAnimation(bool ifImmediately)
809 {
810 if (ifImmediately) {
811 AnimationOption option;
812 option.SetDuration(0);
813 option.SetCurve(Curves::LINEAR);
814 AnimationUtils::StartAnimation(option, [weak = WeakClaim(this)]() {
815 auto modifier = weak.Upgrade();
816 CHECK_NULL_VOID(modifier);
817 modifier->longPointLeftCenterX_->Set(modifier->longPointLeftCenterX_->Get());
818 modifier->longPointRightCenterX_->Set(modifier->longPointRightCenterX_->Get());
819 });
820 }
821 AnimationOption option;
822 option.SetDuration(0);
823 option.SetCurve(Curves::LINEAR);
824 AnimationUtils::StartAnimation(option, [weak = WeakClaim(this)]() {
825 auto modifier = weak.Upgrade();
826 CHECK_NULL_VOID(modifier);
827 modifier->vectorBlackPointCenterX_->Set(modifier->vectorBlackPointCenterX_->Get());
828 });
829 longPointLeftAnimEnd_ = true;
830 longPointRightAnimEnd_ = true;
831 ifNeedFinishCallback_ = false;
832 }
833 } // namespace OHOS::Ace::NG
834