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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATABLE_BASE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATABLE_BASE_H
18 
19 #include "core/animation/animator.h"
20 #include "core/animation/curve_animation.h"
21 #include "core/components/common/properties/animation_option.h"
22 #include "core/event/ace_event_helper.h"
23 
24 namespace OHOS::Ace {
25 
26 // base class for animatable object
27 template<class T>
28 class AnimatableBase : public T {
29 public:
30     using RenderNodeAnimationCallback = std::function<void()>;
31 
32     AnimatableBase() = default;
33     virtual ~AnimatableBase() = default;
34     virtual void MoveTo(const T& endValue) = 0;
35 
AnimateTo(const T & beginValue,const T & endValue)36     void AnimateTo(const T& beginValue, const T& endValue)
37     {
38         if (endValue == endValue_) {
39             return;
40         }
41         endValue_ = endValue;
42         if (!animationOption_.IsValid()) {
43             MoveTo(endValue);
44             return;
45         }
46         ResetController();
47         if (!animationController_) {
48             animationController_ = CREATE_ANIMATOR(context_);
49         }
50         // create animation
51         const auto& animation = CreateAnimation(beginValue, endValue);
52         if (animation) {
53             animationController_->AddInterpolator(animation);
54         }
55         // apply animation options
56         ApplyAnimationOptions();
57     }
58 
SetEvaluator(const RefPtr<Evaluator<T>> & evaluator)59     void SetEvaluator(const RefPtr<Evaluator<T>>& evaluator)
60     {
61         evaluator_ = evaluator;
62     }
63 
SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)64     void SetContextAndCallback(const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback)
65     {
66         context_ = context;
67         animationCallback_ = callback;
68     }
69 
SetAnimationStopCallback(RenderNodeAnimationCallback && callback)70     void SetAnimationStopCallback(RenderNodeAnimationCallback&& callback)
71     {
72         stopCallback_ = std::move(callback);
73     }
74 
GetAnimationOption()75     const AnimationOption& GetAnimationOption() const
76     {
77         return animationOption_;
78     }
79 
SetAnimationOption(const AnimationOption & option)80     void SetAnimationOption(const AnimationOption& option)
81     {
82         animationOption_ = option;
83     }
84 
GetAnimationStatus()85     Animator::Status GetAnimationStatus() const
86     {
87         if (!animationController_) {
88             return Animator::Status::IDLE;
89         }
90         return animationController_->GetStatus();
91     }
92 
93 protected:
OnAnimationCallback(const T & value)94     virtual void OnAnimationCallback(const T& value)
95     {
96         if (animationCallback_) {
97             animationCallback_();
98         }
99     }
100 
ResetController()101     void ResetController()
102     {
103         if (animationController_) {
104             if (!animationController_->IsStopped()) {
105                 animationController_->Stop();
106             }
107             animationController_->ClearInterpolators();
108             animationController_->ClearAllListeners();
109             animationController_.Reset();
110         }
111     }
112 
CreateAnimation(const T & begin,const T & end)113     RefPtr<Animation<T>> CreateAnimation(const T& begin, const T& end)
114     {
115         RefPtr<CurveAnimation<T>> animation =
116             AceType::MakeRefPtr<CurveAnimation<T>>(begin, end, animationOption_.GetCurve());
117         animation->AddListener(std::bind(&AnimatableBase::OnAnimationCallback, this, std::placeholders::_1));
118         if (evaluator_) {
119             animation->SetEvaluator(evaluator_);
120         }
121         return animation;
122     }
123 
ApplyAnimationOptions()124     void ApplyAnimationOptions()
125     {
126         auto onFinishEvent = animationOption_.GetOnFinishEvent();
127         if (onFinishEvent) {
128             animationController_->AddStopListener([onFinishEvent, weakContext = context_] {
129                 auto context = weakContext.Upgrade();
130                 if (context) {
131                     context->PostAsyncEvent(onFinishEvent, "ArkUIAnimationFinishEvent");
132                 } else {
133                     LOGE("the context is null");
134                 }
135             });
136         }
137         if (stopCallback_) {
138             animationController_->AddStopListener(stopCallback_);
139         }
140 
141         animationController_->SetDuration(animationOption_.GetDuration());
142         animationController_->SetStartDelay(animationOption_.GetDelay());
143         animationController_->SetIteration(animationOption_.GetIteration());
144         animationController_->SetTempo(animationOption_.GetTempo());
145         animationController_->SetAnimationDirection(animationOption_.GetAnimationDirection());
146         animationController_->SetFillMode(FillMode::FORWARDS);
147         animationController_->SetAllowRunningAsynchronously(animationOption_.GetAllowRunningAsynchronously());
148         animationController_->Play();
149     }
150 
151 protected:
152     AnimationOption animationOption_;
153     RefPtr<Animator> animationController_;
154     WeakPtr<PipelineContext> context_;
155     RenderNodeAnimationCallback animationCallback_;
156     RenderNodeAnimationCallback stopCallback_;
157     RefPtr<Evaluator<T>> evaluator_;
158     T endValue_ {};
159 };
160 
161 } // namespace OHOS::Ace
162 
163 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_ANIMATABLE_BASE_H
164