1 /*
2 * Copyright (c) 2021-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/swiper/rosen_render_swiper.h"
17
18 #include "core/pipeline/base/rosen_render_context.h"
19
20 namespace OHOS::Ace {
21 namespace {
22
23 constexpr Dimension INDICATOR_POINT_PADDING_TOP = 9.0_vp;
24 constexpr Dimension INDICATOR_FOCUS_WIDTH = 2.0_vp;
25 constexpr Dimension INDICATOR_FOCUS_OFFSET_X = 1.0_vp;
26 constexpr Dimension INDICATOR_FOCUS_OFFSET_Y = 3.0_vp;
27 constexpr uint32_t GRADIENT_COLOR_SIZE = 3;
28 constexpr int32_t INDICATOR_FOCUS_PADDING_START_SIZE = 2;
29 constexpr uint32_t INDICATOR_FOCUS_COLOR = 0xff0a59f7;
30 constexpr uint32_t INDICATOR_HOVER_COLOR = 0x0c000000;
31
32 } // namespace
33
Update(const RefPtr<Component> & component)34 void RosenRenderSwiper::Update(const RefPtr<Component>& component)
35 {
36 RenderSwiper::Update(component);
37 if (auto rsNode = GetRSNode()) {
38 rsNode->SetClipToFrame(true);
39 }
40 }
41
Paint(RenderContext & context,const Offset & offset)42 void RosenRenderSwiper::Paint(RenderContext& context, const Offset& offset)
43 {
44 RenderNode::PaintChildList(GetPaintChildList(), context, offset);
45
46 if (auto rsNode = static_cast<RosenRenderContext*>(&context)->GetRSNode()) {
47 rsNode->SetPaintOrder(true);
48 }
49
50 if (!indicator_) {
51 return;
52 }
53 // indicator style in tv is different.
54 if (SystemProperties::GetDeviceType() != DeviceType::TV) {
55 DrawIndicator(context, offset);
56 } else {
57 if (indicator_->GetIndicatorMask()) {
58 PaintMask(context, offset);
59 }
60 PaintIndicator(context, offset);
61 }
62
63 if (isPaintedFade_) {
64 PaintFade(context, offset);
65 }
66 }
67
PaintFade(RenderContext & context,const Offset & offset)68 void RosenRenderSwiper::PaintFade(RenderContext& context, const Offset& offset)
69 {
70 const auto renderContext = static_cast<RosenRenderContext*>(&context);
71 if (!renderContext) {
72 return;
73 }
74 auto canvas = renderContext->GetCanvas();
75 if (canvas == nullptr) {
76 return;
77 }
78 canvas->Save();
79 canvas->Translate(offset.GetX(), offset.GetY());
80 PaintShadow(canvas, offset);
81 canvas->Restore();
82 }
83
PaintShadow(RSCanvas * canvas,const Offset & offset)84 void RosenRenderSwiper::PaintShadow(RSCanvas* canvas, const Offset& offset)
85 {
86 static constexpr double FADE_MAX_DISTANCE = 2000.0f;
87 static constexpr double FADE_MAX_TRANSLATE = 40.0f;
88 static constexpr double FADE_MAX_RADIUS = 2.0f;
89 static constexpr double FADE_ALPHA = 0.45f;
90 static constexpr double FADE_SCALE_RATE = 0.2f;
91 bool isVertical = axis_ == Axis::VERTICAL;
92 double height = swiperHeight_;
93 double width = swiperWidth_;
94 double centerX = 0.0;
95 double centerY = 0.0;
96 double fadeTranslate = dragDelta_ * FADE_SCALE_RATE;
97 double radius = 0.0;
98 if (GreatNotEqual(dragDelta_, 0.0)) {
99 fadeTranslate = fadeTranslate > FADE_MAX_TRANSLATE ? FADE_MAX_TRANSLATE : fadeTranslate;
100 if (isVertical) {
101 centerY = -FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
102 if (centerY > (-width * FADE_MAX_RADIUS)) {
103 centerY = -width * FADE_MAX_RADIUS;
104 }
105 centerX = width / 2;
106 } else {
107 centerX = -FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
108 if (centerX > (-FADE_MAX_RADIUS * height)) {
109 centerX = (-FADE_MAX_RADIUS * height);
110 }
111 centerY = height / 2;
112 }
113 radius = sqrt(pow(centerX, 2) + pow(centerY, 2));
114 } else {
115 fadeTranslate = fadeTranslate > -FADE_MAX_TRANSLATE ? fadeTranslate : -FADE_MAX_TRANSLATE;
116 if (isVertical) {
117 centerY = height + FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
118 if (centerY < (height + width * FADE_MAX_RADIUS)) {
119 centerY = height + width * FADE_MAX_RADIUS;
120 }
121 centerX = width / 2;
122 radius = sqrt(pow(centerY - height, 2) + pow(centerX, 2));
123 } else {
124 centerX = width + FADE_MAX_DISTANCE + dragDelta_ / FADE_SCALE_RATE;
125 if (centerX < (width + FADE_MAX_RADIUS * height)) {
126 centerX = width + FADE_MAX_RADIUS * height;
127 }
128 centerY = height / 2;
129 radius = sqrt(pow(centerX - width, 2) + pow(centerY, 2));
130 }
131 }
132
133 Offset center = Offset(centerX, centerY);
134 RSPen pen;
135 pen.SetColor(fadeColor_.GetValue());
136 pen.SetAlphaF(FADE_ALPHA);
137 pen.SetBlendMode(RSBlendMode::SRC_OVER);
138 canvas->AttachPen(pen);
139 if (isVertical) {
140 canvas->DrawCircle(RSPoint(center.GetX(), center.GetY() + fadeTranslate), radius);
141 } else {
142 canvas->DrawCircle(RSPoint(center.GetX() + fadeTranslate, center.GetY()), radius);
143 }
144 canvas->DetachPen();
145 }
146
UpdateIndicator()147 void RosenRenderSwiper::UpdateIndicator()
148 {
149 if (!indicator_) {
150 return;
151 }
152
153 double size = NormalizeToPx(indicator_->GetSize());
154 double selectedSize = NormalizeToPx(indicator_->GetSelectedSize());
155 double width = selectedSize + size * (itemCount_ - 1) +
156 indicator_->GetIndicatorPointPadding().Value() * scale_ * (itemCount_ - 1);
157 double indicatorWidth;
158 double indicatorHeight;
159 if (digitalIndicator_) {
160 LayoutDigitalIndicator();
161 Size digitalIndicatorSize = renderDigitalIndicator_->GetLayoutSize();
162 indicatorWidth = digitalIndicatorSize.Width();
163 indicatorHeight = digitalIndicatorSize.Height();
164 } else if (axis_ == Axis::HORIZONTAL) {
165 indicatorWidth = width;
166 indicatorHeight = selectedSize;
167 } else {
168 indicatorWidth = selectedSize;
169 indicatorHeight = width;
170 }
171
172 Offset position;
173 if (indicator_->GetLeft().Value() != SwiperIndicator::DEFAULT_POSITION) {
174 int32_t left = GetValidEdgeLength(swiperWidth_, indicatorWidth, indicator_->GetLeft());
175 position.SetX(left);
176 } else if (indicator_->GetRight().Value() != SwiperIndicator::DEFAULT_POSITION) {
177 int32_t right = GetValidEdgeLength(swiperWidth_, indicatorWidth, indicator_->GetRight());
178 position.SetX(swiperWidth_ - indicatorWidth - right);
179 } else {
180 if (axis_ == Axis::HORIZONTAL) {
181 position.SetX((swiperWidth_ - indicatorWidth) / 2.0);
182 } else {
183 indicatorWidth += NormalizeToPx(INDICATOR_POINT_PADDING_TOP);
184 position.SetX(swiperWidth_ - indicatorWidth);
185 }
186 }
187
188 if (indicator_->GetTop().Value() != SwiperIndicator::DEFAULT_POSITION) {
189 int32_t top = GetValidEdgeLength(swiperHeight_, indicatorHeight, indicator_->GetTop());
190 position.SetY(top);
191 } else if (indicator_->GetBottom().Value() != SwiperIndicator::DEFAULT_POSITION) {
192 int32_t bottom = GetValidEdgeLength(swiperHeight_, indicatorHeight, indicator_->GetBottom());
193 position.SetY(swiperHeight_ - indicatorHeight - bottom);
194 } else {
195 if (axis_ == Axis::HORIZONTAL) {
196 indicatorHeight += NormalizeToPx(INDICATOR_POINT_PADDING_TOP);
197 position.SetY(swiperHeight_ - indicatorHeight);
198 } else {
199 position.SetY((swiperHeight_ - indicatorHeight) / 2.0);
200 }
201 }
202
203 indicatorPosition_ = position;
204 }
205
LayoutDigitalIndicator()206 void RosenRenderSwiper::LayoutDigitalIndicator()
207 {
208 LayoutParam innerLayout;
209 innerLayout.SetMaxSize(Size(Size::INFINITE_SIZE, Size::INFINITE_SIZE));
210
211 std::string indicatorText =
212 (axis_ == Axis::HORIZONTAL)
213 ? std::to_string(currentIndex_ + 1).append("/").append(std::to_string(itemCount_))
214 : std::to_string(currentIndex_ + 1).append("\n/\n").append(std::to_string(itemCount_));
215 RefPtr<TextComponent> textComponent = AceType::MakeRefPtr<TextComponent>(indicatorText);
216 renderDigitalIndicator_ = AceType::DynamicCast<RenderText>(textComponent->CreateRenderNode());
217 auto textStyle = indicator_->GetDigitalIndicatorTextStyle();
218 textStyle.SetTextAlign(TextAlign::CENTER);
219 textComponent->SetTextStyle(textStyle);
220 renderDigitalIndicator_->Attach(GetContext());
221 renderDigitalIndicator_->Update(textComponent);
222 renderDigitalIndicator_->Layout(innerLayout);
223 }
224
PaintIndicator(RenderContext & context,const Offset & offset)225 void RosenRenderSwiper::PaintIndicator(RenderContext& context, const Offset& offset)
226 {
227 if (digitalIndicator_) {
228 LayoutDigitalIndicator();
229 renderDigitalIndicator_->RenderWithContext(context, indicatorPosition_);
230 return;
231 }
232
233 CanvasDrawIndicator(context, offset);
234 }
235
CanvasDrawIndicator(RenderContext & context,const Offset & offset)236 void RosenRenderSwiper::CanvasDrawIndicator(RenderContext& context, const Offset& offset)
237 {
238 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
239 if (!canvas) {
240 LOGE("Paint canvas is null");
241 return;
242 }
243
244 RSPen pen;
245 pen.SetAntiAlias(true);
246
247 IndicatorProperties indicatorProperties = PrepareIndicatorProperties();
248 Offset center = indicatorPosition_ + indicatorProperties.centerPadding;
249 double targetIndex = currentIndex_;
250 if (needReverse_) {
251 targetIndex = itemCount_ - currentIndex_ - 1;
252 }
253 for (int32_t i = 0; i < itemCount_; i++) {
254 if (i != targetIndex) {
255 center += indicatorProperties.normalPaddingStart;
256 pen.SetColor(indicatorProperties.normalColor);
257 canvas->AttachPen(pen);
258 canvas->DrawCircle(RSPoint(center.GetX() + offset.GetX(), center.GetY() + offset.GetY()),
259 indicatorProperties.normalPointRadius);
260 center += indicatorProperties.normalPaddingEnd;
261 } else {
262 center += indicatorProperties.selectedPaddingStart;
263 pen.SetColor(indicatorProperties.selectedColor);
264 canvas->AttachPen(pen);
265 canvas->DrawCircle(RSPoint(center.GetX() + offset.GetX(), center.GetY() + offset.GetY()),
266 indicatorProperties.selectedPointRadius);
267 center += indicatorProperties.selectedPaddingEnd;
268 }
269 canvas->DetachPen();
270 }
271 }
272
PrepareIndicatorProperties() const273 RosenRenderSwiper::IndicatorProperties RosenRenderSwiper::PrepareIndicatorProperties() const
274 {
275 uint32_t normalColor = indicator_->GetColor().GetValue();
276 uint32_t selectedColor = indicator_->GetSelectedColor().GetValue();
277 double normalPointRadius = NormalizeToPx(indicator_->GetSize()) / 2.0;
278 double selectedPointRadius = NormalizeToPx(indicator_->GetSelectedSize()) / 2.0;
279 double indicatorPointPadding = indicator_->GetIndicatorPointPadding().Value() * scale_;
280 if (axis_ == Axis::HORIZONTAL) {
281 return IndicatorProperties(Offset(normalPointRadius, 0.0),
282 Offset(normalPointRadius + indicatorPointPadding, 0.0), Offset(selectedPointRadius, 0.0),
283 Offset(selectedPointRadius + indicatorPointPadding, 0.0), Offset(0.0, selectedPointRadius), normalColor,
284 selectedColor, normalPointRadius, selectedPointRadius, indicatorPointPadding);
285 } else {
286 return IndicatorProperties(Offset(0.0, normalPointRadius),
287 Offset(0.0, normalPointRadius + indicatorPointPadding), Offset(0.0, selectedPointRadius),
288 Offset(0.0, selectedPointRadius + indicatorPointPadding), Offset(selectedPointRadius, 0.0), normalColor,
289 selectedColor, normalPointRadius, selectedPointRadius, indicatorPointPadding);
290 }
291 }
292
PaintMask(RenderContext & context,const Offset & offset) const293 void RosenRenderSwiper::PaintMask(RenderContext& context, const Offset& offset) const
294 {
295 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
296 if (canvas == nullptr) {
297 LOGE("Paint canvas is null");
298 return;
299 }
300
301 RSPen pen;
302 pen.SetAntiAlias(true);
303 canvas->Save();
304
305 std::vector<GradientColor> gradientColors = std::vector<GradientColor>(GRADIENT_COLOR_SIZE);
306 gradientColors[0].SetColor(Color(0x00000000));
307 gradientColors[1].SetColor(Color(0xff000000));
308 gradientColors[2].SetColor(Color(0xff000000));
309 std::vector<RSPoint> pts = { RSPoint(0.0f, 0.0f), RSPoint(0.0f, 0.0f) };
310 if (axis_ == Axis::HORIZONTAL) {
311 pts.at(0) = RSPoint(static_cast<RSScalar>(offset.GetX()),
312 static_cast<RSScalar>(offset.GetY() + indicatorPosition_.GetY() - NormalizeToPx(9.0_vp)));
313 pts.at(1) = RSPoint(static_cast<RSScalar>(offset.GetX()),
314 static_cast<RSScalar>(offset.GetY() + indicatorPosition_.GetY() + NormalizeToPx(15.0_vp)));
315 } else {
316 pts.at(0) = RSPoint(static_cast<RSScalar>(offset.GetX() + indicatorPosition_.GetX() - NormalizeToPx(9.0_vp)),
317 static_cast<RSScalar>(offset.GetY()));
318 pts.at(1) = RSPoint(static_cast<RSScalar>(offset.GetX() + indicatorPosition_.GetX() + NormalizeToPx(15.0_vp)),
319 static_cast<RSScalar>(offset.GetY()));
320 }
321 std::vector<RSColorQuad> colors = std::vector<RSColorQuad>(GRADIENT_COLOR_SIZE);
322 for (uint32_t i = 0; i < gradientColors.size(); ++i) {
323 const auto& gradientColor = gradientColors[i];
324 colors.at(i) = gradientColor.GetColor().GetValue();
325 }
326 const std::vector<RSScalar> pos = { 0.0f, 0.75f, 1.0f };
327
328 pen.SetShaderEffect(RSShaderEffect::CreateLinearGradient(pts.at(0), pts.at(1), colors, pos, RSTileMode::CLAMP));
329 canvas->AttachPen(pen);
330 if (axis_ == Axis::HORIZONTAL) {
331 canvas->DrawRect(RSRect(offset.GetX(), offset.GetY() + indicatorPosition_.GetY() - NormalizeToPx(9.0_vp),
332 offset.GetX() + GetLayoutSize().Width(),
333 offset.GetY() + indicatorPosition_.GetY() + NormalizeToPx(15.0_vp)));
334 } else {
335 canvas->DrawRect(RSRect(offset.GetX() + indicatorPosition_.GetX() - NormalizeToPx(9.0_vp), offset.GetY(),
336 offset.GetX() + indicatorPosition_.GetX() + NormalizeToPx(15.0_vp),
337 offset.GetY() + GetLayoutSize().Height()));
338 }
339 canvas->DetachPen();
340 }
341
DrawIndicator(RenderContext & context,const Offset & offset)342 void RosenRenderSwiper::DrawIndicator(RenderContext& context, const Offset& offset)
343 {
344 if (digitalIndicator_) {
345 if (swiperIndicatorData_.textBoxRender) {
346 swiperIndicatorData_.textBoxRender->RenderWithContext(context, indicatorPosition_ + offset);
347 }
348 } else {
349 if (swiperIndicatorData_.isPressed) {
350 DrawIndicatorBackground(context, offset);
351 } else if (swiperIndicatorData_.isHovered) {
352 DrawIndicatorHoverBackground(context, offset);
353 }
354
355 if (indicatorIsFocus_) {
356 DrawIndicatorFocus(context, offset);
357 }
358 DrawIndicatorItems(context, offset);
359 }
360 }
361
DrawIndicatorBackground(RenderContext & context,const Offset & offset)362 void RosenRenderSwiper::DrawIndicatorBackground(RenderContext& context, const Offset& offset)
363 {
364 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
365 if (!canvas) {
366 LOGE("Paint canvas is null");
367 return;
368 }
369
370 RSPen pen;
371 pen.SetAntiAlias(true);
372
373 pen.SetColor(swiperIndicatorData_.indicatorPaintData.color.GetValue());
374 pen.SetAlphaF(opacityValue_);
375 Offset position = swiperIndicatorData_.indicatorPaintData.position;
376 double radius = swiperIndicatorData_.indicatorPaintData.radius;
377 RSRoundRect rRect(RSRect(0, 0, static_cast<RSScalar>(swiperIndicatorData_.indicatorPaintData.width),
378 static_cast<RSScalar>(swiperIndicatorData_.indicatorPaintData.height)),
379 radius, radius);
380 rRect.Offset(position.GetX() + offset.GetX(), position.GetY() + offset.GetY());
381 canvas->AttachPen(pen);
382 canvas->DrawRoundRect(rRect);
383 canvas->DetachPen();
384 }
385
DrawIndicatorFocus(RenderContext & context,const Offset & offset)386 void RosenRenderSwiper::DrawIndicatorFocus(RenderContext& context, const Offset& offset)
387 {
388 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
389 if (!canvas) {
390 LOGE("Paint canvas is null");
391 return;
392 }
393
394 Offset position = swiperIndicatorData_.indicatorPaintData.position;
395 double focusWidth = swiperIndicatorData_.indicatorPaintData.width + NormalizeToPx(INDICATOR_FOCUS_OFFSET_X * 2);
396 double focusHeight = swiperIndicatorData_.indicatorPaintData.height + NormalizeToPx(INDICATOR_FOCUS_OFFSET_Y * 2);
397 double focusRadius = focusHeight / 2;
398
399 RSPen pen;
400 pen.SetColor(INDICATOR_FOCUS_COLOR);
401 pen.SetWidth(NormalizeToPx(INDICATOR_FOCUS_WIDTH));
402 pen.SetAntiAlias(true);
403 RSRoundRect rRect(RSRect(0, 0, focusWidth, focusHeight), focusRadius, focusRadius);
404 rRect.Offset(position.GetX() + offset.GetX() + NormalizeToPx(INDICATOR_FOCUS_OFFSET_X),
405 position.GetY() + offset.GetY() - NormalizeToPx(INDICATOR_FOCUS_OFFSET_Y));
406 canvas->AttachPen(pen);
407 canvas->DrawRoundRect(rRect);
408 canvas->DetachPen();
409 }
410
DrawIndicatorHoverBackground(RenderContext & context,const Offset & offset)411 void RosenRenderSwiper::DrawIndicatorHoverBackground(RenderContext& context, const Offset& offset)
412 {
413 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
414 if (!canvas) {
415 LOGE("Paint canvas is null");
416 return;
417 }
418
419 RSPen pen;
420 pen.SetAntiAlias(true);
421
422 pen.SetColor(INDICATOR_HOVER_COLOR);
423
424 Offset position = swiperIndicatorData_.indicatorPaintData.position;
425 double radius = swiperIndicatorData_.indicatorPaintData.radius;
426 RSRoundRect rRect(
427 RSRect(0, 0, swiperIndicatorData_.indicatorPaintData.width, swiperIndicatorData_.indicatorPaintData.height),
428 radius, radius);
429 rRect.Offset(position.GetX() + offset.GetX(), position.GetY() + offset.GetY());
430 canvas->AttachPen(pen);
431 canvas->DrawRoundRect(rRect);
432 canvas->DetachPen();
433 }
434
DrawIndicatorItems(RenderContext & context,const Offset & offset)435 void RosenRenderSwiper::DrawIndicatorItems(RenderContext& context, const Offset& offset)
436 {
437 auto canvas = static_cast<RosenRenderContext*>(&context)->GetCanvas();
438 if (!canvas) {
439 LOGE("Paint canvas is null");
440 return;
441 }
442
443 RSBrush brush;
444 brush.SetAntiAlias(true);
445
446 InitMoveRange();
447 IndicatorOffsetInfo pointInfo;
448 RSRoundRect rRect;
449 GetRRect(rRect, pointInfo.focusStart, pointInfo.focusEnd, offset);
450
451 for (int32_t i = 0; i < itemCount_; i++) {
452 // calculate point offset
453 pointInfo.animationMove.Reset();
454 GetIndicatorPointMoveOffset(i, pointInfo.animationMove);
455 pointInfo.center = swiperIndicatorData_.indicatorItemData[i].center + indicatorPosition_;
456
457 // hide point of indicator
458 if (HideIndicatorPoint(i, pointInfo, offset)) {
459 continue;
460 }
461 // paint point of indicator, and point adsorbent
462 brush.SetColor(indicator_->GetColor().GetValue());
463 canvas->AttachBrush(brush);
464 canvas->DrawCircle(RSPoint(pointInfo.center.GetX() + offset.GetX() - pointInfo.animationMove.GetX(),
465 pointInfo.center.GetY() + offset.GetY() - pointInfo.animationMove.GetY()),
466 swiperIndicatorData_.indicatorItemData[i].radius);
467 canvas->DetachBrush();
468 }
469
470 brush.SetColor(indicator_->GetSelectedColor().GetValue());
471 canvas->AttachBrush(brush);
472 canvas->DrawRoundRect(rRect);
473 canvas->DetachBrush();
474 }
475
GetIndicatorPointMoveOffset(int32_t index,Offset & animationMove)476 void RosenRenderSwiper::GetIndicatorPointMoveOffset(int32_t index, Offset& animationMove)
477 {
478 if (NearZero(indicatorPointOffset_)) {
479 return;
480 }
481
482 if ((index <= moveStartIndex_ && index >= moveEndIndex_) || (index >= moveStartIndex_ && index <= moveEndIndex_)) {
483 double move = indicatorPointOffset_ * swiperIndicatorData_.indicatorItemData[index].radius;
484 if (index != moveStartIndex_ && index != moveEndIndex_) {
485 // the middle points should move distance of diameter
486 move *= 2.0;
487 }
488 if (axis_ == Axis::HORIZONTAL) {
489 animationMove.SetX(move);
490 } else {
491 animationMove.SetY(move);
492 }
493 }
494 }
495
GetRRect(RSRoundRect & rRect,double & startOffset,double & endOffset,const Offset & offset)496 void RosenRenderSwiper::GetRRect(RSRoundRect& rRect, double& startOffset, double& endOffset, const Offset& offset)
497 {
498 // calculate focus move distance
499 double tailOffset =
500 (GetIndicatorSpringStatus() == SpringStatus::FOCUS_SWITCH) ? indicatorSwitchTailOffset_ : indicatorTailOffset_;
501 Offset focusMove;
502 Offset focusStretch;
503 double focusStartPadding =
504 INDICATOR_FOCUS_PADDING_START_SIZE * swiperIndicatorData_.indicatorItemData[moveStartIndex_].radius;
505 double focusMoveLength = swiperIndicatorData_.pointPadding + focusStartPadding;
506 double focusMoveDistance = focusMoveLength * (animationDirect_ > 0 ? tailOffset : indicatorHeadOffset_);
507 double recStretch = focusMoveLength * (indicatorHeadOffset_ - tailOffset) * animationDirect_;
508 (axis_ == Axis::HORIZONTAL) ? focusMove.SetX(focusMoveDistance) : focusMove.SetY(focusMoveDistance);
509 (axis_ == Axis::HORIZONTAL) ? focusStretch.SetX(recStretch) : focusStretch.SetY(recStretch);
510
511 // paint focus of indicator
512 Offset position = swiperIndicatorData_.indicatorItemData[moveStartIndex_].position + indicatorPosition_;
513 double radius = swiperIndicatorData_.indicatorItemData[moveStartIndex_].radius;
514 auto rectWH = RSRect(0, 0, swiperIndicatorData_.indicatorItemData[moveStartIndex_].width + focusStretch.GetX(),
515 swiperIndicatorData_.indicatorItemData[moveStartIndex_].height + focusStretch.GetY());
516 rRect = RSRoundRect(rectWH, radius, radius);
517 rRect.Offset(
518 position.GetX() + offset.GetX() + focusMove.GetX(), position.GetY() + offset.GetY() + focusMove.GetY());
519
520 // rrect range
521 if (axis_ == Axis::HORIZONTAL) {
522 startOffset = position.GetX() + offset.GetX() + focusMove.GetX();
523 endOffset = startOffset + swiperIndicatorData_.indicatorItemData[moveStartIndex_].width + focusStretch.GetX();
524 } else {
525 startOffset = position.GetY() + offset.GetY() + focusMove.GetY();
526 endOffset = startOffset + swiperIndicatorData_.indicatorItemData[moveStartIndex_].height + focusStretch.GetY();
527 }
528 }
529
HideIndicatorPoint(int32_t index,const IndicatorOffsetInfo & pointInfo,const Offset & offset)530 bool RosenRenderSwiper::HideIndicatorPoint(int32_t index, const IndicatorOffsetInfo& pointInfo, const Offset& offset)
531 {
532 if (index == moveStartIndex_ || index == moveEndIndex_) {
533 if (index == moveStartIndex_ && NearZero(indicatorHeadOffset_)) {
534 return true;
535 }
536 double pointStart;
537 double radius = swiperIndicatorData_.indicatorItemData[index].radius;
538 if (axis_ == Axis::HORIZONTAL) {
539 pointStart = pointInfo.center.GetX() + offset.GetX() - pointInfo.animationMove.GetX() - radius;
540 } else {
541 pointStart = pointInfo.center.GetY() + offset.GetY() - pointInfo.animationMove.GetY() - radius;
542 }
543 double pointEnd = pointStart + swiperIndicatorData_.indicatorItemData[index].radius * 2.0;
544 if (pointInfo.focusStart < pointStart && pointInfo.focusEnd > pointEnd) {
545 return true;
546 }
547 if (index == moveEndIndex_ && indicatorHeadOffset_ >= focusStretchMaxTime_ &&
548 ((animationDirect_ > 0 && pointInfo.focusEnd >= pointEnd) ||
549 (animationDirect_ < 0 && pointInfo.focusStart <= pointStart))) {
550 return true;
551 }
552 }
553 return false;
554 }
555
InitMoveRange()556 void RosenRenderSwiper::InitMoveRange()
557 {
558 moveStartIndex_ = currentIndex_;
559 moveEndIndex_ = targetIndex_;
560 if (needReverse_) {
561 moveStartIndex_ = itemCount_ - currentIndex_ - 1;
562 moveEndIndex_ = itemCount_ - targetIndex_ - 1;
563 }
564
565 // 1. drag indicator 2.drag content zone
566 if (isDragStart_) {
567 moveEndIndex_ = moveStartIndex_ + animationDirect_;
568 }
569 }
570
571 } // namespace OHOS::Ace
572