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