1 /*
2 * Copyright (c) 2021-2022 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/side_bar/side_bar_animation_controller.h"
17
18 #include "core/components/side_bar/render_side_bar_container.h"
19
20 namespace OHOS::Ace {
21
22 namespace {
23
24 constexpr int32_t SLIDE_TRANSLATE_DURATION = 400;
25 constexpr double RATIO_NEGATIVE = -1.0;
26 constexpr double RATIO_ZERO = 0;
27
UpdateSideBarPosition(const WeakPtr<SideBarAnimationController> & weak,double value)28 void UpdateSideBarPosition(const WeakPtr<SideBarAnimationController>& weak, double value)
29 {
30 auto animationController = weak.Upgrade();
31 if (!animationController) {
32 return;
33 }
34
35 auto sidebar = animationController->GetRenderSideBarContainer().Upgrade();
36 if (!sidebar) {
37 return;
38 }
39
40 auto renderSideBarContainer = AceType::DynamicCast<RenderSideBarContainer>(sidebar);
41 if (!renderSideBarContainer) {
42 return;
43 }
44 auto curValue = value * renderSideBarContainer->GetSidebarWidth();
45 renderSideBarContainer->UpdateElementPosition(curValue);
46 }
47
48 }
49
SideBarAnimation(const WeakPtr<PipelineContext> & context,double start,double end,int delay,int duration,const RefPtr<Curve> & curve,AnimationCallback && callback)50 SideBarAnimation::SideBarAnimation(const WeakPtr<PipelineContext>& context, double start,
51 double end, int delay,
52 int duration, const RefPtr<Curve>& curve,
53 AnimationCallback&& callback)
54 : start_(start), end_(end), delay_(delay), duration_(duration)
55 {
56 curve_ = curve;
57 callback_ = callback;
58 context_ = context;
59 animation_ = AceType::MakeRefPtr<CurveAnimation<double>>(start_, end_, curve_);
60 animation_->AddListener(Animation<double>::ValueCallback(callback_));
61 controller_ = CREATE_ANIMATOR(context_);
62 controller_->SetDuration(duration_);
63 controller_->SetStartDelay(delay_);
64 }
65
Play()66 void SideBarAnimation::Play()
67 {
68 if (!controller_ || !animation_) {
69 return;
70 }
71 controller_->ClearInterpolators();
72 controller_->AddInterpolator(animation_);
73 controller_->Play();
74 }
75
Stop()76 void SideBarAnimation::Stop()
77 {
78 if (controller_) {
79 controller_->Finish();
80 }
81 }
82
StopAnimation()83 void SideBarAnimationController::StopAnimation()
84 {
85 StopRightToLeftAnimation();
86 StopLeftToRightAnimation();
87 }
88
PlaySideBarContainerToAnimation(SideStatus status)89 void SideBarAnimationController::PlaySideBarContainerToAnimation(SideStatus status)
90 {
91 if (!isAnimationCreated_) {
92 CreateAnimation();
93 }
94
95 StopRightToLeftAnimation();
96 if (rightToLeftAnimation_) {
97 rightToLeftAnimation_->ClearStopListenerCallback();
98 }
99
100 StopLeftToRightAnimation();
101 if (leftToRightAnimation_) {
102 leftToRightAnimation_->ClearStopListenerCallback();
103 }
104 bool isSideBarStart = sidebarpositon_ == SideBarPosition::START;
105 if (status == SideStatus::HIDDEN) {
106 if (isSideBarStart) {
107 if (rightToLeftAnimation_ && stopCallback_) {
108 rightToLeftAnimation_->AddStopListenerCallback(stopCallback_);
109 PlayRightToLeftAnimation();
110 }
111 } else {
112 if (leftToRightAnimation_ && stopCallback_) {
113 leftToRightAnimation_->AddStopListenerCallback(stopCallback_);
114 PlayLeftToRightAnimation();
115 }
116 }
117 } else {
118 if (isSideBarStart) {
119 if (leftToRightAnimation_ && stopCallback_) {
120 leftToRightAnimation_->AddStopListenerCallback(stopCallback_);
121 PlayLeftToRightAnimation();
122 }
123 } else {
124 if (rightToLeftAnimation_ && stopCallback_) {
125 rightToLeftAnimation_->AddStopListenerCallback(stopCallback_);
126 PlayRightToLeftAnimation();
127 }
128 }
129 }
130 }
131
CreateAnimation()132 void SideBarAnimationController::CreateAnimation()
133 {
134 auto weak = AceType::WeakClaim(this);
135
136 leftToRightAnimation_ = AceType::MakeRefPtr<SideBarAnimation>(context_, RATIO_NEGATIVE,
137 RATIO_ZERO, 0, SLIDE_TRANSLATE_DURATION, Curves::FRICTION, [weak](double value) {
138 UpdateSideBarPosition(weak, value);
139 });
140
141 rightToLeftAnimation_ = AceType::MakeRefPtr<SideBarAnimation>(context_, RATIO_ZERO,
142 RATIO_NEGATIVE, 0, SLIDE_TRANSLATE_DURATION, Curves::FRICTION, [weak](double value) {
143 UpdateSideBarPosition(weak, value);
144 });
145
146 isAnimationCreated_ = true;
147 }
148
PlayRightToLeftAnimation()149 void SideBarAnimationController::PlayRightToLeftAnimation()
150 {
151 if (rightToLeftAnimation_) {
152 rightToLeftAnimation_->Play();
153 }
154 }
155
StopRightToLeftAnimation()156 void SideBarAnimationController::StopRightToLeftAnimation()
157 {
158 if (rightToLeftAnimation_) {
159 rightToLeftAnimation_->Stop();
160 }
161 }
162
PlayLeftToRightAnimation()163 void SideBarAnimationController::PlayLeftToRightAnimation()
164 {
165 if (leftToRightAnimation_) {
166 leftToRightAnimation_->Play();
167 }
168 }
169
StopLeftToRightAnimation()170 void SideBarAnimationController::StopLeftToRightAnimation()
171 {
172 if (leftToRightAnimation_) {
173 leftToRightAnimation_->Stop();
174 }
175 }
176
177 } // namespace OHOS::Ace
178