• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_CURVE_H
18 
19 #include <functional>
20 
21 #include "base/memory/ace_type.h"
22 #include "base/utils/macros.h"
23 #include "base/utils/utils.h"
24 
25 namespace OHOS::Ace {
26 class NativeCurveHelper;
27 
28 constexpr double SQUARE = 2.0;
29 
30 // The running time of the curve needs to be normalized to the interval of 0.0 to 1.0;
31 // Relatively, the corresponding value of the curve also needs to be normalized to the interval of 0.0 to 1.0;
32 class ACE_FORCE_EXPORT Curve : public AceType {
33     DECLARE_ACE_TYPE(Curve, AceType);
34 
35 public:
36     Curve() = default;
37     ~Curve() override = default;
38 
39     // Returns the value at specific time.
40     // Notice: The value of time must be between 0.0 and 1.0 since the curve uses normalized timestamp.
Move(float time)41     float Move(float time)
42     {
43         // time always between 0.0 and 1.0
44         return MoveInternal(time);
45     }
46 
47     // Each subclass needs to override this method to implement motion in the 0.0 to 1.0 time range.
48     virtual float MoveInternal(float time) = 0;
ToString()49     virtual const std::string ToString()
50     {
51         return "";
52     }
53 };
54 
55 // The reverse curve is used to convert the direction of motion.
56 // It uses the 1.0->0.0 motion of the child curve to achieve the reverse purpose.
57 class ReverseCurve final : public Curve {
58     DECLARE_ACE_TYPE(ReverseCurve, Curve);
59 
60 public:
ReverseCurve(const RefPtr<Curve> & curve)61     explicit ReverseCurve(const RefPtr<Curve>& curve) : curve_(curve) {}
62     ~ReverseCurve() override = default;
63 
MoveInternal(float time)64     float MoveInternal(float time) final
65     {
66         if (!curve_) {
67             return 0.0f;
68         }
69 
70         if (time > 1.0f || time < 0.0f) {
71             return curve_->MoveInternal(0.0f);
72         }
73         return curve_->MoveInternal(1.0f - time);
74     }
75 
76 private:
77     const RefPtr<Curve> curve_;
78 };
79 
80 class ComplementaryCurve final : public Curve {
81     DECLARE_ACE_TYPE(ComplementaryCurve, Curve);
82 
83 public:
ComplementaryCurve(const RefPtr<Curve> & curve)84     explicit ComplementaryCurve(const RefPtr<Curve>& curve) : curve_(curve) {}
85     ~ComplementaryCurve() override = default;
86 
MoveInternal(float time)87     float MoveInternal(float time) final
88     {
89         if (!curve_) {
90             return 0.0f;
91         }
92 
93         if (time > 1.0f || time < 0.0f) {
94             return curve_->MoveInternal(0.0f);
95         }
96         return 1.0f - curve_->MoveInternal(time);
97     }
98 
99 private:
100     const RefPtr<Curve> curve_;
101 };
102 
103 class DecelerationCurve final : public Curve {
104     DECLARE_ACE_TYPE(DecelerationCurve, Curve);
105 
106 public:
MoveInternal(float time)107     float MoveInternal(float time) override
108     {
109         return 1.0f - std::pow(1.0f - time, SQUARE);
110     }
111 };
112 
113 class LinearCurve final : public Curve {
114     DECLARE_ACE_TYPE(LinearCurve, Curve);
115 
116 public:
MoveInternal(float time)117     float MoveInternal(float time) override
118     {
119         if (time < fractionMin || time > fractionMax) {
120             LOGE("LinearCurve MoveInternal: time is less than 0 or larger than 1, return 1");
121             return fractionMax;
122         }
123         return time;
124     }
125 
ToString()126     const std::string ToString() override
127     {
128         std::string curveString("linear");
129         return curveString;
130     }
131 
132 private:
133     float fractionMin = 0.0f;
134     float fractionMax = 1.0f;
135 };
136 
137 class SineCurve final : public Curve {
138     DECLARE_ACE_TYPE(SineCurve, Curve);
139 
140 public:
MoveInternal(float time)141     float MoveInternal(float time) override
142     {
143         static constexpr float PI = 3.14f;
144         return std::sin(PI * time / 2.0f); // half period
145     }
146 };
147 
148 class ElasticsCurve final : public Curve {
149     DECLARE_ACE_TYPE(ElasticsCurve, Curve);
150 
151 public:
ElasticsCurve(float tension)152     explicit ElasticsCurve(float tension) : tension_(tension) {}
153     ~ElasticsCurve() override = default;
MoveInternal(float time)154     float MoveInternal(float time) override
155     {
156         float para = time - 1.0f;
157         return para * para * ((tension_ + 1.0f) * para + tension_) + 1.0f;
158     }
159 
160 private:
161     float tension_ = 2.0f; // Default Elastics tension.
162 };
163 
164 enum class StepsCurvePosition {
165     START,
166     END,
167 };
168 
169 class StepsCurve : public Curve {
170     DECLARE_ACE_TYPE(StepsCurve, Curve);
171 
172 public:
173     explicit StepsCurve(int32_t steps, StepsCurvePosition position = StepsCurvePosition::START)
174         : steps_(steps <= 0 ? 1 : steps), position_(position)
175     {}
176     ~StepsCurve() override = default;
177 
MoveInternal(float time)178     float MoveInternal(float time) override
179     {
180         if (time < fractionMin || time > fractionMax) {
181             LOGE("StepsCurve MoveInternal: time is less than 0 or larger than 1, return 1");
182             return fractionMax;
183         }
184         auto currentStep = static_cast<int32_t>(time * steps_);
185         if (position_ == StepsCurvePosition::START && currentStep < steps_) {
186             currentStep++;
187         }
188         return static_cast<float>(currentStep) / steps_;
189     }
ToString()190     const std::string ToString() override
191     {
192         std::string curveString("steps");
193         std::string comma(",");
194         curveString.append(std::string("(") + std::to_string(steps_) + comma);
195         if (position_ == StepsCurvePosition::START) {
196             curveString.append(std::string("start"));
197         } else {
198             curveString.append(std::string("end"));
199         }
200         curveString.append(std::string(")"));
201         return curveString;
202     }
203 
204 private:
205     int32_t steps_;
206     const StepsCurvePosition position_;
207     float fractionMin = 0.0f;
208     float fractionMax = 1.0f;
209 
210     friend class NativeCurveHelper;
211 };
212 
213 class CustomCurve final : public Curve {
214     DECLARE_ACE_TYPE(CustomCurve, Curve);
215 
216 public:
CustomCurve(const std::function<float (float)> & func)217     explicit CustomCurve(const std::function<float(float)>& func) : interpolateFunc_(func) {}
218     ~CustomCurve() override = default;
MoveInternal(float time)219     float MoveInternal(float time) override
220     {
221         return interpolateFunc_ ? interpolateFunc_(time) : 1.0f;
222     }
ToString()223     const std::string ToString() override
224     {
225         return "customCallback";
226     }
227 
228 private:
229     std::function<float(float)> interpolateFunc_;
230 
231     friend class NativeCurveHelper;
232 };
233 
234 class ResponsiveSpringMotion final : public Curve {
235     DECLARE_ACE_TYPE(ResponsiveSpringMotion, Curve);
236 
237 public:
238     ResponsiveSpringMotion(float response, float dampingRatio, float blendDuration = 0.0f)
response_(response)239         : response_(response), dampingRatio_(dampingRatio), blendDuration_(blendDuration)
240     {}
241     ~ResponsiveSpringMotion() override = default;
242     // this MoveInterval function is not the real implementation of the function.
243     // The curve should use the curve in rosen.
MoveInternal(float time)244     float MoveInternal(float time) override
245     {
246         return 0.0f;
247     }
ToString()248     const std::string ToString() override
249     {
250         std::string curveString("responsive-spring-motion");
251         std::string comma(",");
252         curveString.append(std::string("(") + std::to_string(response_) + comma + std::to_string(dampingRatio_) +
253                            comma + std::to_string(blendDuration_) + std::string(")"));
254         return curveString;
255     }
GetResponse()256     float GetResponse() const
257     {
258         return response_;
259     }
GetDampingRatio()260     float GetDampingRatio() const
261     {
262         return dampingRatio_;
263     }
GetBlendDuration()264     float GetBlendDuration() const
265     {
266         return blendDuration_;
267     }
268     static constexpr float DEFAULT_SPRING_MOTION_RESPONSE = 0.55f;
269     static constexpr float DEFAULT_SPRING_MOTION_DAMPING_RATIO = 0.825f;
270     static constexpr float DEFAULT_SPRING_MOTION_BLEND_DURATION = 0.0f;
271     static constexpr float DEFAULT_RESPONSIVE_SPRING_MOTION_RESPONSE = 0.15f;
272     static constexpr float DEFAULT_RESPONSIVE_SPRING_MOTION_DAMPING_RATIO = 0.86f;
273     static constexpr float DEFAULT_RESPONSIVE_SPRING_MOTION_BLEND_DURATION = 0.25f;
274 
275 private:
276     float response_;
277     float dampingRatio_;
278     float blendDuration_;
279 };
280 
281 class InterpolatingSpring final : public Curve {
282     DECLARE_ACE_TYPE(InterpolatingSpring, Curve);
283 
284 public:
InterpolatingSpring(float velocity,float mass,float stiffness,float damping)285     InterpolatingSpring(float velocity, float mass, float stiffness, float damping)
286         : velocity_(velocity), mass_(mass), stiffness_(stiffness), damping_(damping)
287     {}
288     ~InterpolatingSpring() override = default;
289     // this MoveInterval function is not the real implementation of the function.
290     // The curve should use the curve in rosen.
MoveInternal(float time)291     float MoveInternal(float time) override
292     {
293         return 0.0f;
294     }
ToString()295     const std::string ToString() override
296     {
297         std::string curveString("interpolating-spring");
298         std::string comma(",");
299         curveString.append(std::string("(") + std::to_string(velocity_) + comma + std::to_string(mass_) + comma +
300                            std::to_string(stiffness_) + comma + std::to_string(damping_) + std::string(")"));
301         return curveString;
302     }
303 
GetVelocity()304     float GetVelocity() const
305     {
306         return velocity_;
307     }
308 
UpdateVelocity(float velocity)309     void UpdateVelocity(float velocity)
310     {
311         velocity_ = velocity;
312     }
313 
GetMass()314     float GetMass() const
315     {
316         return mass_;
317     }
318 
GetStiffness()319     float GetStiffness() const
320     {
321         return stiffness_;
322     }
323 
GetDamping()324     float GetDamping() const
325     {
326         return damping_;
327     }
328 
329     static constexpr float DEFAULT_INTERPOLATING_SPRING_MASS = 1.0f;
330     static constexpr float DEFAULT_INTERPOLATING_SPRING_VELOCITY = 0.0f;
331 
332 private:
333     float velocity_ = 0.0f;
334     float mass_ = 0.0f;
335     float stiffness_ = 0.0f;
336     float damping_ = 0.0f;
337 };
338 
339 } // namespace OHOS::Ace
340 
341 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_CURVE_H
342