• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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