1 /* 2 * Copyright (c) 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_FLOAT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_FLOAT_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/pipeline/pipeline_base.h" 23 24 namespace OHOS::Ace { 25 26 /* 27 * AnimatableFloat is a float with AnimationOption and Animator. 28 */ 29 class AnimatableFloat final { 30 public: 31 AnimatableFloat() = default; 32 explicit AnimatableFloat(float value, const AnimationOption& option = AnimationOption()) 33 : value_(value), animationOption_(option) {} 34 ~AnimatableFloat() = default; 35 using RenderNodeAnimationCallback = std::function<void()>; 36 SetContextAndCallback(const WeakPtr<PipelineBase> & context,RenderNodeAnimationCallback && callback)37 void SetContextAndCallback(const WeakPtr<PipelineBase>& context, RenderNodeAnimationCallback&& callback) 38 { 39 context_ = context; 40 animationCallback_ = std::move(callback); 41 } 42 GetValue()43 float GetValue() const 44 { 45 return value_; 46 } 47 SetValue(float value)48 void SetValue(float value) 49 { 50 value_ = value; 51 } 52 GetAnimationOption()53 AnimationOption GetAnimationOption() const 54 { 55 return animationOption_; 56 } 57 SetAnimationOption(const AnimationOption & option)58 void SetAnimationOption(const AnimationOption& option) 59 { 60 animationOption_ = option; 61 } 62 63 bool operator==(const AnimatableFloat& animFloat) const 64 { 65 return NearEqual(value_, animFloat.GetValue()); 66 } 67 68 bool operator!=(const AnimatableFloat& animFloat) const 69 { 70 return !operator==(animFloat); 71 } 72 73 AnimatableFloat& operator=(const AnimatableFloat& newValue) 74 { 75 SetAnimationOption(newValue.GetAnimationOption()); 76 auto pipelineContext = context_.Upgrade(); 77 if (NearEqual(value_, std::numeric_limits<float>::max()) || NearEqual(value_, newValue.GetValue()) 78 || !pipelineContext || !animationCallback_) { 79 SetValue(newValue.GetValue()); 80 return *this; 81 } 82 83 AnimationOption explicitAnim; 84 if (pipelineContext) { 85 explicitAnim = pipelineContext->GetExplicitAnimationOption(); 86 } 87 88 // Animaiton has started already in previous update call. 89 if (NearEqual(animateToEndValue_, newValue.GetValue()) && explicitAnim.IsValid()) { 90 LOGW("Previous animateTo end value is same as new value."); 91 return *this; 92 } 93 94 if (explicitAnim.IsValid()) { 95 SetAnimationOption(explicitAnim); 96 AnimateTo(newValue.GetValue()); 97 } else if (animationOption_.IsValid()) { 98 AnimateTo(newValue.GetValue()); 99 } else { 100 SetValue(newValue.GetValue()); 101 } 102 return *this; 103 } 104 105 private: AnimateTo(float endValue)106 void AnimateTo(float endValue) 107 { 108 animateToEndValue_ = endValue; 109 ResetController(); 110 if (!animationController_) { 111 animationController_ = CREATE_ANIMATOR(context_); 112 } 113 RefPtr<CurveAnimation<float>> animation = AceType::MakeRefPtr<CurveAnimation<float>>( 114 GetValue(), endValue, animationOption_.GetCurve()); 115 animation->AddListener(std::bind(&AnimatableFloat::OnAnimationCallback, this, std::placeholders::_1)); 116 117 animationController_->AddInterpolator(animation); 118 animationController_->SetDuration(animationOption_.GetDuration()); 119 animationController_->SetStartDelay(animationOption_.GetDelay()); 120 animationController_->Play(); 121 } 122 ResetController()123 void ResetController() 124 { 125 if (animationController_) { 126 if (!animationController_->IsStopped()) { 127 animationController_->Stop(); 128 } 129 animationController_->ClearInterpolators(); 130 animationController_.Reset(); 131 } 132 } 133 OnAnimationCallback(float value)134 void OnAnimationCallback(float value) 135 { 136 SetValue(value); 137 if (animationCallback_) { 138 animationCallback_(); 139 } 140 } 141 142 private: 143 float value_ = std::numeric_limits<float>::max(); 144 AnimationOption animationOption_; 145 RefPtr<Animator> animationController_; 146 WeakPtr<PipelineBase> context_; 147 RenderNodeAnimationCallback animationCallback_; 148 float animateToEndValue_ = -1.0f; 149 }; 150 151 } // namespace OHOS::Ace 152 153 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_ANIMATABLE_FLOAT_H 154