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