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