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