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_CURVE_ANIMATION_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_CURVE_ANIMATION_H
18 
19 #include "core/animation/animation.h"
20 #include "core/animation/curve.h"
21 #include "core/animation/curves.h"
22 #include "core/animation/evaluator.h"
23 
24 namespace OHOS::Ace {
25 
26 template<typename T>
27 class ACE_FORCE_EXPORT CurveAnimation : public Animation<T> {
28 public:
CurveAnimation(const T & begin,const T & end,const RefPtr<Curve> & curve)29     CurveAnimation(const T& begin, const T& end, const RefPtr<Curve>& curve)
30         : begin_(begin), end_(end), currentValue_(begin)
31     {
32         if (curve) {
33             curve_ = curve;
34         } else {
35             LOGW("curve is empty when construct animation, use EASE as default.");
36             curve_ = Curves::EASE;
37         }
38         reverseCurve_ = curve_;
39     }
40 
41     ~CurveAnimation() override = default;
42 
GetValue()43     const T& GetValue() const override
44     {
45         return currentValue_;
46     }
47 
SetCurve(const RefPtr<Curve> & curve)48     void SetCurve(const RefPtr<Curve>& curve) override
49     {
50         if (!curve) {
51             LOGE("set curve failed. curve is null.");
52             return;
53         }
54         curve_ = curve;
55         reverseCurve_ = curve;
56     }
57 
SetReverseCurve(const RefPtr<Curve> & reverseCurve)58     void SetReverseCurve(const RefPtr<Curve>& reverseCurve)
59     {
60         if (!reverseCurve) {
61             LOGE("set reverse curve failed. reverse curve is null.");
62             return;
63         }
64         reverseCurve_ = reverseCurve;
65     }
66 
SetEvaluator(const RefPtr<Evaluator<T>> & evaluator)67     void SetEvaluator(const RefPtr<Evaluator<T>>& evaluator)
68     {
69         if (evaluator) {
70             isSupportedRunningAsync_ = false;
71             evaluator_ = evaluator;
72         }
73     }
74 
IsSupportedRunningAsynchronously()75     bool IsSupportedRunningAsynchronously() override
76     {
77         return isSupportedRunningAsync_;
78     }
79 
80     bool RunAsync(const WeakPtr<Scheduler>& weakScheduler, const AnimationOption& option,
81         const std::function<void()> prepareCallback = nullptr,
82         const std::function<void()> finishCallback = nullptr) override
83     {
84         if (!isSupportedRunningAsync_) {
85             LOGE("can not run animation asynchronously with nonlinear evaluator.");
86             return false;
87         }
88 
89         return Interpolator::RunAsync(weakScheduler, option, prepareCallback, finishCallback);
90     }
91 
GetCurve()92     RefPtr<Curve> GetCurve() override
93     {
94         return curve_ != nullptr ? curve_ : AceType::DynamicCast<Curve>(Curves::EASE_IN_OUT);
95     }
96 
97 private:
98     // Use the normalized time [0.0, 1.0] to get the current data value.
99     // Map the value of the curve motion to the real data range.
Calculate(float time,const RefPtr<Curve> & curve)100     void Calculate(float time, const RefPtr<Curve>& curve)
101     {
102         if (NearZero(time)) {
103             currentValue_ = begin_;
104             return;
105         }
106         if (NearEqual(time, 1.0)) {
107             currentValue_ = end_;
108             return;
109         }
110         currentValue_ = evaluator_->Evaluate(begin_, end_, curve->Move(time));
111     }
112 
OnNormalizedTimestampChanged(float normalized,bool reverse)113     void OnNormalizedTimestampChanged(float normalized, bool reverse) override
114     {
115         if (normalized < NORMALIZED_DURATION_MIN || normalized > NORMALIZED_DURATION_MAX) {
116             LOGE("normalized time check failed. normalized: %{public}f", normalized);
117             return;
118         }
119         Calculate(normalized, reverse ? reverseCurve_ : curve_);
120         ValueListenable<T>::NotifyListener(currentValue_);
121     }
122 
123     T begin_;
124     T end_;
125     T currentValue_;
126     bool isSupportedRunningAsync_ { true };
127     RefPtr<Curve> curve_;
128     RefPtr<Curve> reverseCurve_;
129     RefPtr<Evaluator<T>> evaluator_ = AceType::MakeRefPtr<LinearEvaluator<T>>();
130 };
131 
132 } // namespace OHOS::Ace
133 
134 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_CURVE_ANIMATION_H
135