• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/slider/slider_content_modifier.h"
17 
18 #include "core/components_ng/render/drawing_prop_convertor.h"
19 #include "core/components_ng/render/path_painter.h"
20 
21 namespace OHOS::Ace::NG {
22 namespace {
23 constexpr float HALF = 0.5f;
24 constexpr float SPRING_MOTION_RESPONSE = 0.314f;
25 constexpr float SPRING_MOTION_DAMPING_FRACTION = 0.95f;
26 } // namespace
SliderContentModifier(const Parameters & parameters,std::function<void (float)> updateImageCenterX,std::function<void (float)> updateImageCenterY)27 SliderContentModifier::SliderContentModifier(const Parameters& parameters,
28     std::function<void(float)> updateImageCenterX, std::function<void(float)> updateImageCenterY)
29     : updateImageCenterX_(std::move(updateImageCenterX)), updateImageCenterY_(std::move(updateImageCenterY)),
30       boardColor_(AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(Color::TRANSPARENT)))
31 {
32     // animatable property
33     selectStart_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(parameters.selectStart - PointF());
34     selectEnd_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(parameters.selectEnd - PointF());
35     backStart_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(parameters.backStart - PointF());
36     backEnd_ = AceType::MakeRefPtr<AnimatablePropertyOffsetF>(parameters.backEnd - PointF());
37     blockCenterX_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(parameters.circleCenter.GetX());
38     blockCenterY_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(parameters.circleCenter.GetY());
39     trackThickness_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(parameters.trackThickness);
40     trackBackgroundColor_ =
41         AceType::MakeRefPtr<AnimatablePropertyVectorColor>(GradientArithmetic(parameters.trackBackgroundColor));
42     selectGradientColor_ =
43         AceType::MakeRefPtr<AnimatablePropertyVectorColor>(GradientArithmetic(parameters.selectGradientColor));
44     blockColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(parameters.blockColor));
45     trackBorderRadius_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(parameters.trackThickness * HALF);
46     selectedBorderRadius_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(trackBorderRadius_->Get());
47     stepSize_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(1);
48     blockBorderWidth_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0);
49     stepColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor::TRANSPARENT);
50     blockBorderColor_ = AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor(parameters.blockColor));
51     blockSize_ = AceType::MakeRefPtr<AnimatablePropertySizeF>(parameters.blockSize);
52     // non-animatable property
53     stepRatio_ = AceType::MakeRefPtr<PropertyFloat>(parameters.stepRatio);
54     sliderMode_ = AceType::MakeRefPtr<PropertyInt>(static_cast<int>(SliderModelNG::SliderMode::OUTSET));
55     directionAxis_ = AceType::MakeRefPtr<PropertyInt>(static_cast<int>(Axis::HORIZONTAL));
56     isShowStep_ = AceType::MakeRefPtr<PropertyBool>(false);
57     sliderInteractionMode_ =
58         AceType::MakeRefPtr<PropertyInt>(static_cast<int>(SliderModelNG::SliderInteraction::SLIDE_AND_CLICK));
59     minResponse_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
60     blockType_ = AceType::MakeRefPtr<PropertyInt>(static_cast<int>(SliderModelNG::BlockStyleType::DEFAULT));
61     useContentModifier_ = AceType::MakeRefPtr<PropertyBool>(false);
62     isHovered_ = AceType::MakeRefPtr<PropertyBool>(false);
63     isPressed_ = AceType::MakeRefPtr<PropertyBool>(false);
64     isFocused_ = AceType::MakeRefPtr<PropertyBool>(false);
65     // others
66     UpdateData(parameters);
67     UpdateThemeColor();
68 
69     AttachProperty(selectStart_);
70     AttachProperty(selectEnd_);
71     AttachProperty(backStart_);
72     AttachProperty(backEnd_);
73     AttachProperty(blockCenterX_);
74     AttachProperty(blockCenterY_);
75     AttachProperty(trackThickness_);
76     AttachProperty(trackBackgroundColor_);
77     AttachProperty(selectGradientColor_);
78     AttachProperty(blockColor_);
79     AttachProperty(boardColor_);
80     AttachProperty(trackBorderRadius_);
81     AttachProperty(selectedBorderRadius_);
82     AttachProperty(stepSize_);
83     AttachProperty(blockBorderWidth_);
84     AttachProperty(stepColor_);
85     AttachProperty(blockBorderColor_);
86     AttachProperty(blockSize_);
87     AttachProperty(stepRatio_);
88     AttachProperty(sliderMode_);
89     AttachProperty(directionAxis_);
90     AttachProperty(isShowStep_);
91     AttachProperty(sliderInteractionMode_);
92     AttachProperty(minResponse_);
93     AttachProperty(blockType_);
94     AttachProperty(isHovered_);
95     AttachProperty(isPressed_);
96     AttachProperty(isFocused_);
97 
98     InitializeShapeProperty();
99 }
100 
InitializeShapeProperty()101 void SliderContentModifier::InitializeShapeProperty()
102 {
103     shapeWidth_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
104     shapeHeight_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
105     circleRadius_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
106     ellipseRadiusX_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
107     ellipseRadiusY_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
108     rectTopLeftRadiusX_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
109     rectTopLeftRadiusY_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
110     rectTopRightRadiusX_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
111     rectTopRightRadiusY_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
112     rectBottomLeftRadiusX_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
113     rectBottomLeftRadiusY_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
114     rectBottomRightRadiusX_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
115     rectBottomRightRadiusY_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(.0f);
116     AttachProperty(shapeWidth_);
117     AttachProperty(shapeHeight_);
118     AttachProperty(circleRadius_);
119     AttachProperty(ellipseRadiusX_);
120     AttachProperty(ellipseRadiusY_);
121     AttachProperty(rectTopLeftRadiusX_);
122     AttachProperty(rectTopLeftRadiusY_);
123     AttachProperty(rectTopRightRadiusX_);
124     AttachProperty(rectTopRightRadiusY_);
125     AttachProperty(rectBottomLeftRadiusX_);
126     AttachProperty(rectBottomLeftRadiusY_);
127     AttachProperty(rectBottomRightRadiusX_);
128     AttachProperty(rectBottomRightRadiusY_);
129 }
130 
onDraw(DrawingContext & context)131 void SliderContentModifier::onDraw(DrawingContext& context)
132 {
133     if (useContentModifier_->Get()) {
134         return;
135     }
136     DrawBackground(context);
137     DrawStep(context);
138     DrawSelect(context);
139     DrawShadow(context);
140     DrawBlock(context);
141     DrawHoverOrPress(context);
142 }
143 
SetStartEndPointLocation(Axis & direction,RSRect & trackRect,RSPoint & startPoint,RSPoint & endPoint)144 void SetStartEndPointLocation(Axis& direction, RSRect& trackRect, RSPoint& startPoint, RSPoint& endPoint)
145 {
146     if (direction == Axis::HORIZONTAL) {
147         startPoint.SetX(trackRect.GetLeft());
148         startPoint.SetY(trackRect.GetTop());
149         endPoint.SetX(trackRect.GetRight());
150         endPoint.SetY(trackRect.GetTop());
151     } else {
152         startPoint.SetX(trackRect.GetLeft());
153         startPoint.SetY(trackRect.GetTop());
154         endPoint.SetX(trackRect.GetLeft());
155         endPoint.SetY(trackRect.GetBottom());
156     }
157 }
158 
DrawBackground(DrawingContext & context)159 void SliderContentModifier::DrawBackground(DrawingContext& context)
160 {
161     auto& canvas = context.canvas;
162     auto trackBorderRadius = trackBorderRadius_->Get();
163     auto pipeline = PipelineBase::GetCurrentContextSafelyWithCheck();
164     CHECK_NULL_VOID(pipeline);
165     auto theme = pipeline->GetTheme<SliderTheme>();
166     CHECK_NULL_VOID(theme);
167     scaleValue_ = theme->GetFocusedScaleValue();
168     std::vector<GradientColor> gradientColors = GetTrackBackgroundColor();
169     std::vector<RSColorQuad> colors;
170     std::vector<float> pos;
171     for (size_t i = 0; i < gradientColors.size(); i++) {
172         colors.emplace_back(gradientColors[i].GetLinearColor().GetValue());
173         pos.emplace_back(gradientColors[i].GetDimension().Value());
174     }
175     if (sliderMode_->Get() != static_cast<int32_t>(SliderModel::SliderMode::INSET)) {
176         isEnlarge_ = isPressed_->Get() || isHovered_->Get() || isFocused_->Get();
177     }
178     RSRect trackRect = GetTrackRect();
179     auto direction = static_cast<Axis>(directionAxis_->Get());
180     RSPoint startPoint;
181     RSPoint endPoint;
182     SetStartEndPointLocation(direction, trackRect, startPoint, endPoint);
183     RSBrush brush;
184     brush.SetAntiAlias(true);
185     if (reverse_) {
186 #ifndef USE_ROSEN_DRAWING
187         brush.SetShaderEffect(
188             RSShaderEffect::CreateLinearGradient(endPoint, startPoint, colors, pos, RSTileMode::CLAMP));
189 #else
190         brush.SetShaderEffect(
191             RSRecordingShaderEffect::CreateLinearGradient(endPoint, startPoint, colors, pos, RSTileMode::CLAMP));
192 #endif
193     } else {
194 #ifndef USE_ROSEN_DRAWING
195         brush.SetShaderEffect(
196             RSShaderEffect::CreateLinearGradient(startPoint, endPoint, colors, pos, RSTileMode::CLAMP));
197 #else
198         brush.SetShaderEffect(
199             RSRecordingShaderEffect::CreateLinearGradient(startPoint, endPoint, colors, pos, RSTileMode::CLAMP));
200 #endif
201     }
202     canvas.AttachBrush(brush);
203     auto trackRadius = isEnlarge_ ? trackBorderRadius * scaleValue_ : trackBorderRadius;
204     RSRoundRect roundRect(trackRect, trackRadius, trackRadius);
205     canvas.DrawRoundRect(roundRect);
206     canvas.DetachBrush();
207     canvas.Save();
208     canvas.ClipRoundRect(roundRect, RSClipOp::INTERSECT, true);
209 }
210 
AddStepPoint(float startX,float startY,float endX,float endY,RSCanvas & canvas)211 void SliderContentModifier::AddStepPoint(float startX, float startY, float endX, float endY, RSCanvas& canvas)
212 {
213     auto stepRatio = stepRatio_->Get();
214     if (NearEqual(stepRatio, .0f)) {
215         return;
216     }
217 
218     auto stepsLengthX = (endX - startX) * stepRatio;
219     auto stepsLengthY = (endY - startY) * stepRatio;
220     auto stepSize = stepSize_->Get();
221     auto trackThickness = trackThickness_->Get();
222     if (GreatNotEqual(stepSize, trackThickness)) {
223         stepSize = trackThickness;
224     }
225 
226     if (reverse_) {
227         while (GreatOrEqual(endX, startX) && GreatOrEqual(endY, startY)) {
228             canvas.DrawCircle(RSPoint(endX, endY), isEnlarge_ ? stepSize * HALF * scaleValue_ : stepSize * HALF);
229             stepPointVec_.emplace_back(PointF(endX, endY));
230             if (NearEqual(endX, startX) && NearEqual(endY, startY)) {
231                 return;
232             }
233             endX -= stepsLengthX;
234             endY -= stepsLengthY;
235         }
236         if (!NearEqual(endX, startX) || !NearEqual(endY, startY)) {
237             stepPointVec_.emplace_back(PointF(startX, startY));
238         }
239     } else {
240         while (LessOrEqual(startX, endX) && LessOrEqual(startY, endY)) {
241             canvas.DrawCircle(RSPoint(startX, startY), isEnlarge_ ? stepSize * HALF * scaleValue_ : stepSize * HALF);
242             stepPointVec_.emplace_back(PointF(startX, startY));
243             if (NearEqual(startX, endX) && NearEqual(startY, endY)) {
244                 return;
245             }
246             startX += stepsLengthX;
247             startY += stepsLengthY;
248         }
249         if (!NearEqual(startX, endX) || !NearEqual(startY, endY)) {
250             stepPointVec_.emplace_back(PointF(endX, endY));
251         }
252     }
253 }
254 
DrawStep(DrawingContext & context)255 void SliderContentModifier::DrawStep(DrawingContext& context)
256 {
257     if (!isShowStep_->Get()) {
258         return;
259     }
260     auto& canvas = context.canvas;
261     auto stepColor = stepColor_->Get();
262     auto backStart = backStart_->Get();
263     auto backEnd = backEnd_->Get();
264     auto stepRatio = stepRatio_->Get();
265     if (NearEqual(stepRatio, .0f)) {
266         return;
267     }
268     float startX = backStart.GetX();
269     float endX = backEnd.GetX();
270     float startY = backStart.GetY();
271     float endY = backEnd.GetY();
272     if (NearEqual(startX, endX) && NearEqual(startY, endY)) {
273         return;
274     }
275 
276     RSBrush brush;
277     brush.SetAntiAlias(true);
278     brush.SetColor(ToRSColor(stepColor));
279     canvas.AttachBrush(brush);
280     stepPointVec_.clear();
281     AddStepPoint(startX, startY, endX, endY, canvas);
282     canvas.DetachBrush();
283 }
284 
DrawSelect(DrawingContext & context)285 void SliderContentModifier::DrawSelect(DrawingContext& context)
286 {
287     auto& canvas = context.canvas;
288     if (!NearEqual(selectStart_->Get().GetX(), selectEnd_->Get().GetX(), HALF) ||
289         !NearEqual(selectStart_->Get().GetY(), selectEnd_->Get().GetY(), HALF)) {
290         auto selectedBorderRadius = selectedBorderRadius_->Get();
291         auto direction = static_cast<Axis>(directionAxis_->Get());
292         auto blockCenter = GetBlockCenter();
293         auto trackThickness = trackThickness_->Get();
294         auto sliderMode = static_cast<SliderModelNG::SliderMode>(sliderMode_->Get());
295         auto rect = GetTrackRect();
296         auto insetOffset = .0f;
297         if (sliderMode == SliderModelNG::SliderMode::INSET) {
298             insetOffset = std::max(selectedBorderRadius, trackThickness * HALF);
299         }
300         if (!reverse_) {
301             if (direction == Axis::HORIZONTAL) {
302                 rect.SetRight(blockCenter.GetX() + insetOffset);
303             } else {
304                 rect.SetBottom(blockCenter.GetY() + insetOffset);
305             }
306         } else {
307             if (direction == Axis::HORIZONTAL) {
308                 rect.SetLeft(blockCenter.GetX() - insetOffset);
309             } else {
310                 rect.SetTop(blockCenter.GetY() - insetOffset);
311             }
312         }
313 
314         RSBrush brush;
315         DrawSelectColor(brush, rect);
316         canvas.AttachBrush(brush);
317         canvas.DrawRoundRect(RSRoundRect(rect, selectedBorderRadius, selectedBorderRadius));
318         canvas.DetachBrush();
319     }
320     canvas.Restore();
321 }
322 
DrawDefaultBlock(DrawingContext & context)323 void SliderContentModifier::DrawDefaultBlock(DrawingContext& context)
324 {
325     auto& canvas = context.canvas;
326     auto borderWidth = blockBorderWidth_->Get();
327     auto blockSize = blockSize_->Get();
328     auto blockCenter = GetBlockCenter();
329     float blockRadius = std::min(blockSize.Width(), blockSize.Height()) * HALF;
330     float radius = blockRadius;
331     RSBrush brush;
332     brush.SetAntiAlias(true);
333     if (GreatOrEqual(borderWidth * HALF, radius)) {
334         brush.SetColor(ToRSColor(blockBorderColor_->Get()));
335     } else {
336         radius = std::min(blockSize.Width(), blockSize.Height()) * HALF - borderWidth * HALF;
337         brush.SetColor(ToRSColor(blockColor_->Get()));
338     }
339     canvas.AttachBrush(brush);
340     RSPen pen;
341     if (!NearEqual(borderWidth, .0f) && LessNotEqual(borderWidth * HALF, blockRadius)) {
342         pen.SetAntiAlias(true);
343         pen.SetWidth(borderWidth);
344         pen.SetColor(ToRSColor(blockBorderColor_->Get()));
345         canvas.AttachPen(pen);
346     }
347     canvas.DrawCircle(
348         ToRSPoint(PointF(blockCenter.GetX(), blockCenter.GetY())), isEnlarge_ ? radius * scaleValue_ : radius);
349     canvas.DetachBrush();
350     if (!NearEqual(borderWidth, .0f) && LessNotEqual(borderWidth * HALF, blockRadius)) {
351         canvas.DetachPen();
352     }
353 }
354 
DrawHoverOrPress(DrawingContext & context)355 void SliderContentModifier::DrawHoverOrPress(DrawingContext& context)
356 {
357     auto sliderMode = static_cast<SliderModelNG::SliderMode>(sliderMode_->Get());
358     if (static_cast<SliderModelNG::BlockStyleType>(blockType_->Get()) != SliderModelNG::BlockStyleType::DEFAULT ||
359         sliderMode == SliderModelNG::SliderMode::NONE) {
360         return;
361     }
362 
363     auto& canvas = context.canvas;
364     RSPen circleStatePen;
365     circleStatePen.SetAntiAlias(true);
366     // add animate color
367     circleStatePen.SetColor(ToRSColor(boardColor_->Get()));
368     circleStatePen.SetWidth(isEnlarge_ ? hotCircleShadowWidth_ * scaleValue_ : hotCircleShadowWidth_);
369     canvas.AttachPen(circleStatePen);
370     auto blockSize = blockSize_->Get();
371     float diameter = std::min(blockSize.Width(), blockSize.Height());
372     auto penRadius = (diameter + hotCircleShadowWidth_) * HALF;
373     auto blockCenter = GetBlockCenter();
374     canvas.DrawCircle(ToRSPoint(blockCenter), isEnlarge_ ? penRadius * scaleValue_ : penRadius);
375     canvas.DetachPen();
376 }
377 
DrawShadow(DrawingContext & context)378 void SliderContentModifier::DrawShadow(DrawingContext& context)
379 {
380     auto sliderMode = static_cast<SliderModelNG::SliderMode>(sliderMode_->Get());
381     if (static_cast<SliderModelNG::BlockStyleType>(blockType_->Get()) != SliderModelNG::BlockStyleType::DEFAULT ||
382         sliderMode == SliderModelNG::SliderMode::NONE) {
383         return;
384     }
385 
386     if (!mouseHoverFlag_ && !mousePressedFlag_) {
387         auto& canvas = context.canvas;
388         auto blockSize = blockSize_->Get();
389         auto blockCenter = GetBlockCenter();
390         float radius = std::min(blockSize.Width(), blockSize.Height()) * HALF;
391         canvas.Save();
392         RSBrush shadowBrush;
393         shadowBrush.SetAntiAlias(true);
394         shadowBrush.SetColor(ToRSColor(blockShadowColor_));
395         RSFilter filter;
396         filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter(
397             RSBlurType::NORMAL, RSDrawing::ConvertRadiusToSigma(hotCircleShadowWidth_)));
398         shadowBrush.SetFilter(filter);
399 
400         canvas.AttachBrush(shadowBrush);
401         RSPath path;
402         path.AddCircle(ToRSPoint(blockCenter).GetX(), ToRSPoint(blockCenter).GetY(), radius);
403         canvas.DrawPath(path);
404         canvas.DetachBrush();
405         canvas.Restore();
406     }
407 }
408 
SetBoardColor()409 void SliderContentModifier::SetBoardColor()
410 {
411     CHECK_NULL_VOID(boardColor_);
412     auto pipeline = PipelineBase::GetCurrentContext();
413     CHECK_NULL_VOID(pipeline);
414     auto theme = pipeline->GetTheme<SliderTheme>();
415     CHECK_NULL_VOID(theme);
416     Color shadowColor = Color::TRANSPARENT;
417     shadowColor = mouseHoverFlag_ ? theme->GetBlockHoverColor() : shadowColor;
418     shadowColor = mousePressedFlag_ ? theme->GetBlockPressedColor() : shadowColor;
419     auto duration = mousePressedFlag_ ? static_cast<int32_t>(theme->GetPressAnimationDuration())
420                                       : static_cast<int32_t>(theme->GetHoverAnimationDuration());
421     auto curve = mousePressedFlag_ ? Curves::SHARP : Curves::FRICTION;
422     AnimationOption option = AnimationOption();
423     option.SetDuration(duration);
424     option.SetCurve(curve);
425     AnimationUtils::Animate(option, [&]() { boardColor_->Set(LinearColor(shadowColor)); });
426 }
427 
UpdateData(const Parameters & parameters)428 void SliderContentModifier::UpdateData(const Parameters& parameters)
429 {
430     mouseHoverFlag_ = parameters.mouseHoverFlag_;
431     mousePressedFlag_ = parameters.mousePressedFlag_;
432     hotCircleShadowWidth_ = parameters.hotCircleShadowWidth;
433     SetIsHovered(mouseHoverFlag_);
434 }
435 
JudgeNeedAnimate(bool reverse)436 void SliderContentModifier::JudgeNeedAnimate(bool reverse)
437 {
438     // when reverse is changed, slider block position changes do not animated.
439     if (reverse_ != reverse) {
440         SetAnimatorStatus(SliderStatus::DEFAULT);
441         reverse_ = reverse;
442     }
443 }
444 
StopSelectAnimation()445 void SliderContentModifier::StopSelectAnimation()
446 {
447     AnimationOption option = AnimationOption();
448     option.SetCurve(Curves::LINEAR);
449     AnimationUtils::Animate(option, [this]() {
450         selectEnd_->Set(selectEnd_->Get());
451         if (animatorStatus_ == SliderStatus::MOVE) {
452             selectEnd_->Set(targetSelectEnd_);
453         }
454     });
455 }
456 
SetSelectSize(const PointF & start,const PointF & end)457 void SliderContentModifier::SetSelectSize(const PointF& start, const PointF& end)
458 {
459     if (selectStart_) {
460         selectStart_->Set(start - PointF());
461     }
462     CHECK_NULL_VOID(selectEnd_);
463     auto currentEnd = end - PointF();
464     if (targetSelectEnd_ == currentEnd) {
465         return;
466     }
467     if (animatorStatus_ != SliderStatus::DEFAULT && isVisible_) {
468         StopSelectAnimation();
469         AnimationOption option = AnimationOption();
470         auto motion =
471             AceType::MakeRefPtr<ResponsiveSpringMotion>(SPRING_MOTION_RESPONSE, SPRING_MOTION_DAMPING_FRACTION);
472         option.SetCurve(motion);
473         AnimationUtils::Animate(option, [&]() { selectEnd_->Set(end - PointF()); });
474     } else {
475         selectEnd_->Set(end - PointF());
476     }
477     targetSelectEnd_ = end - PointF();
478 }
479 
StopCircleCenterAnimation()480 void SliderContentModifier::StopCircleCenterAnimation()
481 {
482     AnimationOption option = AnimationOption();
483     option.SetCurve(Curves::LINEAR);
484     AnimationUtils::Animate(option, [this]() {
485         if (static_cast<Axis>(directionAxis_->Get()) == Axis::HORIZONTAL) {
486             blockCenterX_->Set(blockCenterX_->Get());
487         } else {
488             blockCenterY_->Set(blockCenterY_->Get());
489         }
490         if (animatorStatus_ == SliderStatus::MOVE) {
491             if (static_cast<Axis>(directionAxis_->Get()) == Axis::HORIZONTAL) {
492                 blockCenterX_->Set(targetCenter_.GetX());
493             } else {
494                 blockCenterY_->Set(targetCenter_.GetY());
495             }
496         }
497     });
498 }
499 
SetCircleCenter(const PointF & center)500 void SliderContentModifier::SetCircleCenter(const PointF& center)
501 {
502     if (center == targetCenter_) {
503         return;
504     }
505 
506     CHECK_NULL_VOID(blockCenterX_);
507     CHECK_NULL_VOID(blockCenterY_);
508     if (animatorStatus_ != SliderStatus::DEFAULT && isVisible_) {
509         StopCircleCenterAnimation();
510         AnimationOption option = AnimationOption();
511         auto motion =
512             AceType::MakeRefPtr<ResponsiveSpringMotion>(SPRING_MOTION_RESPONSE, SPRING_MOTION_DAMPING_FRACTION);
513         option.SetCurve(motion);
514         AnimationUtils::Animate(option, [this, center]() {
515             if (static_cast<Axis>(directionAxis_->Get()) == Axis::HORIZONTAL) {
516                 blockCenterX_->Set(center.GetX());
517             } else {
518                 blockCenterY_->Set(center.GetY());
519             }
520         });
521         if (static_cast<Axis>(directionAxis_->Get()) == Axis::HORIZONTAL) {
522             blockCenterY_->Set(center.GetY());
523         } else {
524             blockCenterX_->Set(center.GetX());
525         }
526     } else {
527         blockCenterX_->Set(center.GetX());
528         blockCenterY_->Set(center.GetY());
529     }
530     targetCenter_ = center;
531 }
532 
GetTrackRect()533 RSRect SliderContentModifier::GetTrackRect()
534 {
535     auto backStart = backStart_->Get();
536     auto backEnd = backEnd_->Get();
537     auto trackThickness = trackThickness_->Get();
538     auto direction = static_cast<Axis>(directionAxis_->Get());
539     auto stepSize = stepSize_->Get();
540     if (GreatNotEqual(stepSize, trackThickness)) {
541         stepSize = trackThickness;
542     }
543     RSRect rect;
544     auto calculatedThickness = isEnlarge_ ? trackThickness * HALF * scaleValue_ : trackThickness * HALF;
545     if (direction == Axis::HORIZONTAL) {
546         if (sliderMode_->Get() == static_cast<int32_t>(SliderModel::SliderMode::OUTSET)) {
547             rect.SetLeft(backStart.GetX() - stepSize * HALF);
548             rect.SetRight(backEnd.GetX() + stepSize * HALF);
549         } else if (sliderMode_->Get() == static_cast<int32_t>(SliderModel::SliderMode::INSET)) {
550             rect.SetLeft(backStart.GetX() - trackThickness * HALF);
551             rect.SetRight(backEnd.GetX() + trackThickness * HALF);
552         } else {
553             rect.SetLeft(backStart.GetX());
554             rect.SetRight(backEnd.GetX());
555         }
556         rect.SetTop(backStart.GetY() - calculatedThickness);
557         rect.SetBottom(backEnd.GetY() + calculatedThickness);
558     } else {
559         rect.SetLeft(backStart.GetX() - calculatedThickness);
560         rect.SetRight(backEnd.GetX() + calculatedThickness);
561         if (sliderMode_->Get() == static_cast<int32_t>(SliderModel::SliderMode::OUTSET)) {
562             rect.SetTop(backStart.GetY() - stepSize * HALF);
563             rect.SetBottom(backEnd.GetY() + stepSize * HALF);
564         } else if (sliderMode_->Get() == static_cast<int32_t>(SliderModel::SliderMode::INSET)) {
565             rect.SetTop(backStart.GetY() - trackThickness * HALF);
566             rect.SetBottom(backEnd.GetY() + trackThickness * HALF);
567         } else {
568             rect.SetTop(backStart.GetY());
569             rect.SetBottom(backEnd.GetY());
570         }
571     }
572     return rect;
573 }
574 
DrawBlock(DrawingContext & context)575 void SliderContentModifier::DrawBlock(DrawingContext& context)
576 {
577     auto sliderMode = static_cast<SliderModelNG::SliderMode>(sliderMode_->Get());
578     if (sliderMode != SliderModelNG::SliderMode::NONE) {
579         auto blockType = static_cast<SliderModelNG::BlockStyleType>(blockType_->Get());
580         if (blockType == SliderModelNG::BlockStyleType::DEFAULT) {
581             DrawDefaultBlock(context);
582         } else if (blockType == SliderModelNG::BlockStyleType::SHAPE) {
583             DrawBlockShape(context);
584         } else if (blockType == SliderModelNG::BlockStyleType::IMAGE) {
585             auto blockCenter = GetBlockCenter();
586             if (updateImageCenterX_) {
587                 updateImageCenterX_(blockCenter.GetX());
588             }
589             if (updateImageCenterY_) {
590                 updateImageCenterY_(blockCenter.GetY());
591             }
592         }
593     }
594 }
595 
DrawBlockShape(DrawingContext & context)596 void SliderContentModifier::DrawBlockShape(DrawingContext& context)
597 {
598     if (shape_ == nullptr) {
599         return;
600     }
601 
602     switch (shape_->GetBasicShapeType()) {
603         case BasicShapeType::CIRCLE: {
604             auto circle = DynamicCast<Circle>(shape_);
605             CHECK_NULL_VOID(circle);
606             DrawBlockShapeCircle(context, circle);
607             break;
608         }
609         case BasicShapeType::ELLIPSE: {
610             auto ellipse = DynamicCast<Ellipse>(shape_);
611             CHECK_NULL_VOID(ellipse);
612             DrawBlockShapeEllipse(context, ellipse);
613             break;
614         }
615         case BasicShapeType::PATH: {
616             auto path = DynamicCast<Path>(shape_);
617             CHECK_NULL_VOID(path);
618             DrawBlockShapePath(context, path);
619             break;
620         }
621         case BasicShapeType::RECT: {
622             auto rect = DynamicCast<ShapeRect>(shape_);
623             CHECK_NULL_VOID(rect);
624             DrawBlockShapeRect(context, rect);
625             break;
626         }
627         default:
628             break;
629     }
630 }
631 
DrawBlockShapeCircle(DrawingContext & context,RefPtr<Circle> & circle)632 void SliderContentModifier::DrawBlockShapeCircle(DrawingContext& context, RefPtr<Circle>& circle)
633 {
634     auto blockSize = blockSize_->Get();
635     auto shapeWidth = shapeWidth_->Get();
636     auto shapeHeight = shapeHeight_->Get();
637     auto blockBorderWidth = blockBorderWidth_->Get();
638     if (NearZero(shapeWidth) || NearZero(shapeHeight)) {
639         return;
640     }
641 
642     auto blockCenter = GetBlockCenter();
643     float scale = std::max(blockSize.Width() / shapeWidth, blockSize.Height() / shapeHeight);
644     if (NearZero(scale)) {
645         return;
646     }
647     float blockBorderWidthUnscale = blockBorderWidth / scale;
648 
649     auto& canvas = context.canvas;
650     canvas.Save();
651     SetBlockClip(context);
652     canvas.Translate(blockCenter.GetX(), blockCenter.GetY());
653     canvas.Scale(scale, scale);
654     canvas.Translate(-blockCenter.GetX(), -blockCenter.GetY());
655 
656     RSPen pen;
657     pen.SetAntiAlias(true);
658     pen.SetWidth(blockBorderWidthUnscale);
659     pen.SetColor(ToRSColor(blockBorderColor_->Get()));
660     canvas.AttachPen(pen);
661     RSBrush brush;
662     brush.SetAntiAlias(true);
663     brush.SetColor(ToRSColor(blockColor_->Get()));
664     canvas.AttachBrush(brush);
665 
666     float radius = std::min(shapeWidth, shapeHeight) * HALF;
667     float drawRadius = radius - blockBorderWidthUnscale * HALF;
668     PointF drawCenter(
669         blockCenter.GetX() - shapeWidth * HALF + radius, blockCenter.GetY() - shapeHeight * HALF + radius);
670     canvas.DrawCircle(ToRSPoint(drawCenter), drawRadius);
671 
672     canvas.DetachBrush();
673     canvas.DetachPen();
674     canvas.Restore();
675 }
676 
DrawBlockShapeEllipse(DrawingContext & context,RefPtr<Ellipse> & ellipse)677 void SliderContentModifier::DrawBlockShapeEllipse(DrawingContext& context, RefPtr<Ellipse>& ellipse)
678 {
679     auto blockSize = blockSize_->Get();
680     auto shapeWidth = shapeWidth_->Get();
681     auto shapeHeight = shapeHeight_->Get();
682     auto blockBorderWidth = blockBorderWidth_->Get();
683     if (NearZero(shapeWidth) || NearZero(shapeHeight)) {
684         return;
685     }
686 
687     auto blockCenter = GetBlockCenter();
688     float scale = std::max(blockSize.Width() / shapeWidth, blockSize.Height() / shapeHeight);
689     if (NearZero(scale)) {
690         return;
691     }
692     float blockBorderWidthUnscale = blockBorderWidth / scale;
693 
694     auto& canvas = context.canvas;
695     canvas.Save();
696     SetBlockClip(context);
697     canvas.Translate(blockCenter.GetX(), blockCenter.GetY());
698     canvas.Scale(scale, scale);
699     canvas.Translate(-blockCenter.GetX(), -blockCenter.GetY());
700 
701     RSPen pen;
702     pen.SetAntiAlias(true);
703     pen.SetWidth(blockBorderWidth);
704     pen.SetColor(ToRSColor(blockBorderColor_->Get()));
705     canvas.AttachPen(pen);
706     RSBrush brush;
707     brush.SetAntiAlias(true);
708     brush.SetColor(ToRSColor(blockColor_->Get()));
709     canvas.AttachBrush(brush);
710 
711     RectF drawRect(blockCenter.GetX() - shapeWidth * HALF + blockBorderWidthUnscale * HALF,
712         blockCenter.GetY() - shapeHeight * HALF + blockBorderWidthUnscale * HALF, shapeWidth - blockBorderWidthUnscale,
713         shapeHeight - blockBorderWidthUnscale);
714     canvas.DrawOval(ToRSRect(drawRect));
715 
716     canvas.DetachBrush();
717     canvas.DetachPen();
718     canvas.Restore();
719 }
720 
DrawBlockShapePath(DrawingContext & context,RefPtr<Path> & path)721 void SliderContentModifier::DrawBlockShapePath(DrawingContext& context, RefPtr<Path>& path)
722 {
723     auto blockSize = blockSize_->Get();
724     auto blockBorderWidth = blockBorderWidth_->Get();
725 
726     auto blockCenter = GetBlockCenter();
727     SizeF shapeSize = PathPainter::GetPathSize(path->GetValue());
728     if (NearZero(shapeSize.Width()) || NearZero(shapeSize.Height())) {
729         return;
730     }
731     float scale = std::max(blockSize.Width() / (shapeSize.Width() + blockBorderWidth),
732         blockSize.Height() / (shapeSize.Height() + blockBorderWidth));
733     if (NearZero(scale)) {
734         return;
735     }
736 
737     auto& canvas = context.canvas;
738     canvas.Save();
739     SetBlockClip(context);
740     canvas.Translate(blockCenter.GetX(), blockCenter.GetY());
741     canvas.Scale(scale, scale);
742     canvas.Translate(-blockCenter.GetX(), -blockCenter.GetY());
743 
744     RSPen pen;
745     pen.SetAntiAlias(true);
746     pen.SetWidth(blockBorderWidth);
747     pen.SetColor(ToRSColor(blockBorderColor_->Get()));
748     canvas.AttachPen(pen);
749     RSBrush brush;
750     brush.SetAntiAlias(true);
751     brush.SetColor(ToRSColor(blockColor_->Get()));
752     canvas.AttachBrush(brush);
753 
754     OffsetF offset(blockCenter.GetX() - shapeSize.Width() * HALF, blockCenter.GetY() - shapeSize.Height() * HALF);
755     PathPainter::DrawPath(canvas, path->GetValue(), offset);
756     canvas.DetachBrush();
757     canvas.DetachPen();
758     canvas.Restore();
759 }
760 
SetShapeRectRadius(RSRoundRect & roundRect,float borderWidth)761 void SliderContentModifier::SetShapeRectRadius(RSRoundRect& roundRect, float borderWidth)
762 {
763     float radiusX = rectTopLeftRadiusX_->Get() - borderWidth * HALF;
764     float radiusY = rectTopLeftRadiusY_->Get() - borderWidth * HALF;
765     roundRect.SetCornerRadius(RSRoundRect::TOP_LEFT_POS, radiusX, radiusY);
766 
767     radiusX = rectTopRightRadiusX_->Get() - borderWidth * HALF;
768     radiusY = rectTopRightRadiusY_->Get() - borderWidth * HALF;
769     roundRect.SetCornerRadius(RSRoundRect::TOP_RIGHT_POS, radiusX, radiusY);
770 
771     radiusX = rectBottomLeftRadiusX_->Get() - borderWidth * HALF;
772     radiusY = rectBottomLeftRadiusY_->Get() - borderWidth * HALF;
773     roundRect.SetCornerRadius(RSRoundRect::BOTTOM_LEFT_POS, radiusX, radiusY);
774 
775     radiusX = rectBottomRightRadiusX_->Get() - borderWidth * HALF;
776     radiusY = rectBottomRightRadiusY_->Get() - borderWidth * HALF;
777     roundRect.SetCornerRadius(RSRoundRect::BOTTOM_RIGHT_POS, radiusX, radiusY);
778 }
779 
DrawBlockShapeRect(DrawingContext & context,RefPtr<ShapeRect> & rect)780 void SliderContentModifier::DrawBlockShapeRect(DrawingContext& context, RefPtr<ShapeRect>& rect)
781 {
782     auto shapeWidth = shapeWidth_->Get();
783     auto shapeHeight = shapeHeight_->Get();
784     if (NearZero(shapeWidth) || NearZero(shapeHeight)) {
785         return;
786     }
787     auto blockSize = blockSize_->Get();
788     float scale = std::max(blockSize.Width() / shapeWidth, blockSize.Height() / shapeHeight);
789     if (NearZero(scale)) {
790         return;
791     }
792     auto blockBorderWidth = blockBorderWidth_->Get();
793     float blockBorderWidthUnscale = blockBorderWidth / scale;
794     auto blockCenter = GetBlockCenter();
795 
796     auto& canvas = context.canvas;
797     canvas.Save();
798     SetBlockClip(context);
799     canvas.Translate(blockCenter.GetX(), blockCenter.GetY());
800     canvas.Scale(scale, scale);
801     canvas.Translate(-blockCenter.GetX(), -blockCenter.GetY());
802 
803     RSPen pen;
804     pen.SetAntiAlias(true);
805     pen.SetWidth(blockBorderWidth_->Get());
806     pen.SetColor(ToRSColor(blockBorderColor_->Get()));
807     canvas.AttachPen(pen);
808     RSBrush brush;
809     brush.SetAntiAlias(true);
810     brush.SetColor(ToRSColor(blockColor_->Get()));
811     canvas.AttachBrush(brush);
812 
813     RSRoundRect roundRect;
814     RSRect rsRect;
815     rsRect.SetLeft(blockCenter.GetX() - shapeWidth * HALF + blockBorderWidthUnscale * HALF);
816     rsRect.SetRight(blockCenter.GetX() + shapeWidth * HALF - blockBorderWidthUnscale);
817     rsRect.SetTop(blockCenter.GetY() - shapeHeight * HALF + blockBorderWidthUnscale * HALF);
818     rsRect.SetBottom(blockCenter.GetY() + shapeHeight * HALF - blockBorderWidthUnscale);
819     roundRect.SetRect(rsRect);
820     SetShapeRectRadius(roundRect, blockBorderWidthUnscale);
821 
822     canvas.DrawRoundRect(roundRect);
823     canvas.DetachBrush();
824     canvas.DetachPen();
825     canvas.Restore();
826 }
827 
SetBlockShape(const RefPtr<BasicShape> & shape)828 void SliderContentModifier::SetBlockShape(const RefPtr<BasicShape>& shape)
829 {
830     shape_ = shape;
831     CHECK_NULL_VOID(shape_);
832     shapeWidth_->Set(shape_->GetWidth().ConvertToPx());
833     shapeHeight_->Set(shape_->GetHeight().ConvertToPx());
834     if (shape->GetBasicShapeType() == BasicShapeType::CIRCLE) {
835         auto circle = DynamicCast<Circle>(shape_);
836         CHECK_NULL_VOID(circle);
837         if (circle->GetRadius().IsValid()) {
838             circleRadius_->Set(circle->GetRadius().ConvertToPx());
839         } else {
840             circleRadius_->Set(std::min(shape_->GetWidth().ConvertToPx(), shape_->GetHeight().ConvertToPx()) * HALF);
841         }
842     } else if (shape->GetBasicShapeType() == BasicShapeType::ELLIPSE) {
843         auto ellipse = DynamicCast<Ellipse>(shape_);
844         CHECK_NULL_VOID(ellipse);
845         if (ellipse->GetRadiusX().IsValid() && ellipse->GetRadiusY().IsValid()) {
846             ellipseRadiusX_->Set(ellipse->GetRadiusX().ConvertToPx());
847             ellipseRadiusY_->Set(ellipse->GetRadiusY().ConvertToPx());
848         } else {
849             ellipseRadiusX_->Set(shape_->GetWidth().ConvertToPx() * HALF);
850             ellipseRadiusY_->Set(shape_->GetHeight().ConvertToPx() * HALF);
851         }
852     } else if (shape->GetBasicShapeType() == BasicShapeType::RECT) {
853         auto rect = DynamicCast<ShapeRect>(shape_);
854         CHECK_NULL_VOID(rect);
855         rectTopLeftRadiusX_->Set(rect->GetTopLeftRadius().GetX().ConvertToPx());
856         rectTopLeftRadiusY_->Set(rect->GetTopLeftRadius().GetY().ConvertToPx());
857         rectTopRightRadiusX_->Set(rect->GetTopRightRadius().GetX().ConvertToPx());
858         rectTopRightRadiusY_->Set(rect->GetTopRightRadius().GetY().ConvertToPx());
859         rectBottomLeftRadiusX_->Set(rect->GetBottomLeftRadius().GetX().ConvertToPx());
860         rectBottomLeftRadiusY_->Set(rect->GetBottomLeftRadius().GetY().ConvertToPx());
861         rectBottomRightRadiusX_->Set(rect->GetBottomRightRadius().GetX().ConvertToPx());
862         rectBottomRightRadiusY_->Set(rect->GetBottomRightRadius().GetY().ConvertToPx());
863     }
864 }
865 
UpdateContentDirtyRect(const SizeF & frameSize)866 void SliderContentModifier::UpdateContentDirtyRect(const SizeF& frameSize)
867 {
868     if (useContentModifier_->Get()) {
869         return;
870     }
871     auto pipeline = PipelineBase::GetCurrentContext();
872     CHECK_NULL_VOID(pipeline);
873     auto theme = pipeline->GetTheme<SliderTheme>();
874     CHECK_NULL_VOID(theme);
875     auto hotShadowWidth = sliderMode_->Get() == static_cast<int32_t>(SliderModel::SliderMode::OUTSET)
876                               ? theme->GetOutsetHotBlockShadowWidth().ConvertToPx()
877                               : theme->GetInsetHotBlockShadowWidth().ConvertToPx();
878     auto circleSize =
879         SizeF(blockSize_->Get().Width() + hotShadowWidth / HALF, blockSize_->Get().Height() + hotShadowWidth / HALF);
880     RectF rect;
881     if (directionAxis_->Get() == static_cast<int32_t>(Axis::HORIZONTAL)) {
882         auto maxWidth = std::max(circleSize.Height(), frameSize.Height()) * HALF;
883         rect.SetOffset(OffsetF(-circleSize.Width(), blockCenterY_->Get() - maxWidth));
884         rect.SetSize(SizeF(circleSize.Width() / HALF + frameSize.Width(), maxWidth / HALF));
885     } else {
886         auto maxWidth = std::max(circleSize.Width(), frameSize.Width()) * HALF;
887         rect.SetOffset(OffsetF(blockCenterX_->Get() - maxWidth, -circleSize.Height()));
888         rect.SetSize(SizeF(maxWidth / HALF, circleSize.Height() / HALF + frameSize.Height()));
889     }
890 
891     SetBoundsRect(rect);
892 }
893 
SetBlockClip(DrawingContext & context)894 void SliderContentModifier::SetBlockClip(DrawingContext& context)
895 {
896     auto& canvas = context.canvas;
897     auto blockCenter = GetBlockCenter();
898     auto blockSize = blockSize_->Get();
899     RectF rect(blockCenter.GetX() - blockSize.Width() * HALF, blockCenter.GetY() - blockSize.Height() * HALF,
900         blockSize.Width(), blockSize.Height());
901     canvas.ClipRect(ToRSRect(rect), RSClipOp::INTERSECT);
902 }
903 
GetTrackBackgroundColor() const904 std::vector<GradientColor> SliderContentModifier::GetTrackBackgroundColor() const
905 {
906     Gradient gradient = SortGradientColorsByOffset(trackBackgroundColor_->Get().GetGradient());
907     std::vector<GradientColor> gradientColors = gradient.GetColors();
908     // Fault protection processing, if gradientColors is empty, set to default colors.
909 
910     if (gradientColors.empty()) {
911         auto pipeline = PipelineBase::GetCurrentContext();
912         CHECK_NULL_RETURN(pipeline, gradientColors);
913         auto theme = pipeline->GetTheme<SliderTheme>();
914         CHECK_NULL_RETURN(theme, gradientColors);
915         gradientColors = SliderModelNG::CreateSolidGradient(theme->GetTrackBgColor()).GetColors();
916     }
917     return gradientColors;
918 }
919 
SortGradientColorsByOffset(const Gradient & gradient) const920 Gradient SliderContentModifier::SortGradientColorsByOffset(const Gradient& gradient) const
921 {
922     auto srcGradientColors = gradient.GetColors();
923     std::sort(
924         srcGradientColors.begin(), srcGradientColors.end(), [](const GradientColor& left, const GradientColor& right) {
925             return left.GetDimension().Value() < right.GetDimension().Value();
926         });
927 
928     Gradient sortedGradient;
929     for (const auto& item : srcGradientColors) {
930         sortedGradient.AddColor(item);
931     }
932 
933     return sortedGradient;
934 }
935 
DrawSelectColor(RSBrush & brush,RSRect & rect)936 void SliderContentModifier::DrawSelectColor(RSBrush& brush, RSRect& rect)
937 {
938     Gradient gradient = SortGradientColorsByOffset(selectGradientColor_->Get().GetGradient());
939     std::vector<GradientColor> gradientColors = gradient.GetColors();
940 
941     if (gradientColors.empty()) {
942         auto pipeline = PipelineBase::GetCurrentContextSafely();
943         CHECK_NULL_VOID(pipeline);
944         auto theme = pipeline->GetTheme<SliderTheme>();
945         CHECK_NULL_VOID(theme);
946         gradientColors = SliderModelNG::CreateSolidGradient(theme->GetTrackSelectedColor()).GetColors();
947     }
948 
949     std::vector<RSColorQuad> colors;
950     std::vector<float> pos;
951     for (size_t i = 0; i < gradientColors.size(); i++) {
952         colors.emplace_back(gradientColors[i].GetLinearColor().GetValue());
953         pos.emplace_back(gradientColors[i].GetDimension().Value());
954     }
955     RSPoint startPoint;
956     RSPoint endPoint;
957     auto direction = static_cast<Axis>(directionAxis_->Get());
958     SetStartEndPointLocation(direction, rect, startPoint, endPoint);
959 
960     brush.SetAntiAlias(true);
961     if (reverse_) {
962 #ifndef USE_ROSEN_DRAWING
963         brush.SetShaderEffect(
964             RSShaderEffect::CreateLinearGradient(endPoint, startPoint, colors, pos, RSTileMode::CLAMP));
965 #else
966         brush.SetShaderEffect(
967             RSRecordingShaderEffect::CreateLinearGradient(endPoint, startPoint, colors, pos, RSTileMode::CLAMP));
968 #endif
969     } else {
970 #ifndef USE_ROSEN_DRAWING
971         brush.SetShaderEffect(
972             RSShaderEffect::CreateLinearGradient(startPoint, endPoint, colors, pos, RSTileMode::CLAMP));
973 #else
974         brush.SetShaderEffect(
975             RSRecordingShaderEffect::CreateLinearGradient(startPoint, endPoint, colors, pos, RSTileMode::CLAMP));
976 #endif
977     }
978 }
979 } // namespace OHOS::Ace::NG
980