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