• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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/scroll/scroll_fade_effect.h"
17 
18 namespace OHOS::Ace {
19 
InitialEdgeEffect()20 void ScrollFadeEffect::InitialEdgeEffect()
21 {
22     ResetFadeEffect(fadeColor_);
23 }
24 
ResetFadeEffect(const Color & color)25 void ScrollFadeEffect::ResetFadeEffect(const Color& color)
26 {
27     fadeColor_ = color;
28     if (!fadePainter_) {
29         fadePainter_ = ScrollFadePainter::CreatePainter();
30     }
31 
32     if (!fadeController_) {
33         auto scroll = scroll_.Upgrade();
34         fadeController_ = AceType::MakeRefPtr<ScrollFadeController>(scroll ? scroll->GetContext() : nullptr);
35         fadeController_->SetCallback([weakFade = AceType::WeakClaim(this)](double opacity, double scale) {
36             auto fade = weakFade.Upgrade();
37             if (fade) {
38                 fade->SetOpacityAndScale(opacity, scale);
39             }
40         });
41     }
42 }
43 
CalculateOverScroll(double oldPosition,bool isReachMax)44 double ScrollFadeEffect::CalculateOverScroll(double oldPosition, bool isReachMax)
45 {
46     if (!currentPositionCallback_ || !leadingCallback_ || !trailingCallback_) {
47         LOGD("position callback is null");
48         return 0.0;
49     }
50 
51     double newPosition = -currentPositionCallback_();
52     double minExtent = -trailingCallback_();
53     double maxExtent = -leadingCallback_();
54 
55     // under scroll
56     if (newPosition < oldPosition && oldPosition <= minExtent) {
57         return newPosition - oldPosition;
58     }
59 
60     // over scroll
61     if (newPosition > oldPosition && oldPosition >= maxExtent) {
62         return newPosition - oldPosition;
63     }
64 
65     // crash the top
66     if (newPosition < minExtent && oldPosition > minExtent) {
67         LOGD("crash the top");
68         return newPosition;
69     }
70 
71     // crash the bottom
72     if (newPosition > maxExtent && maxExtent > oldPosition && isReachMax) {
73         LOGD("crash the bottom");
74         return newPosition - maxExtent;
75     }
76 
77     return 0.0;
78 }
79 
SetPaintDirection(Axis axis,double overScroll)80 void ScrollFadeEffect::SetPaintDirection(Axis axis, double overScroll)
81 {
82     if (NearZero(overScroll) || !fadePainter_) {
83         return;
84     }
85     auto const isVertical = axis == Axis::VERTICAL;
86     if (isVertical && overScroll < 0.0) {
87         fadePainter_->SetDirection(OverScrollDirection::UP);
88     } else if (isVertical && overScroll > 0.0) {
89         fadePainter_->SetDirection(OverScrollDirection::DOWN);
90     } else if (overScroll < 0.0) {
91         fadePainter_->SetDirection(OverScrollDirection::LEFT);
92     } else {
93         fadePainter_->SetDirection(OverScrollDirection::RIGHT);
94     }
95 }
96 
Paint(RenderContext & context,const Size & viewPort,const Offset & offset)97 void ScrollFadeEffect::Paint(
98     RenderContext& context, const Size& viewPort, const Offset& offset)
99 {
100     if (fadePainter_) {
101         fadePainter_->SetColor(fadeColor_);
102         fadePainter_->PaintSide(context, viewPort, offset);
103     }
104 }
105 
HandleOverScroll(Axis axis,double overScroll,const Size & viewPort)106 void ScrollFadeEffect::HandleOverScroll(Axis axis, double overScroll, const Size& viewPort)
107 {
108     if (NearZero(overScroll)) {
109         return;
110     }
111 
112     SetPaintDirection(axis, overScroll);
113 
114     if (!fadeController_) {
115         fadeController_ = AceType::MakeRefPtr<ScrollFadeController>(scroll_.Upgrade()->GetContext());
116         fadeController_->SetCallback([weakFade = AceType::WeakClaim(this)](double opacity, double scale) {
117             auto fade = weakFade.Upgrade();
118             if (fade) {
119                 fade->SetOpacityAndScale(opacity, scale);
120             }
121         });
122     }
123 
124     if (fadeController_ && scrollable_) {
125         double dragVelocity = scrollable_->GetCurrentVelocity();
126         if (!NearZero(dragVelocity)) {
127             fadeController_->ProcessAbsorb(std::abs(dragVelocity));
128         } else {
129             axis == Axis::VERTICAL
130             ? fadeController_->ProcessPull(std::abs(overScroll), viewPort.Height(), viewPort.Width())
131             : fadeController_->ProcessPull(std::abs(overScroll), viewPort.Width(), viewPort.Height());
132         }
133     }
134 }
135 
SetOpacityAndScale(double opacity,double scale)136 void ScrollFadeEffect::SetOpacityAndScale(double opacity, double scale)
137 {
138     if (fadePainter_) {
139         fadePainter_->SetOpacity(opacity);
140         fadePainter_->SetScaleFactor(scale);
141 
142         auto scroll = scroll_.Upgrade();
143         if (scroll) {
144             scroll->MarkNeedRender();
145         }
146     }
147 }
148 
149 } // namespace OHOS::Ace