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