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_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 23 namespace OHOS::Ace { 24 class NativeCurveHelper; 25 26 constexpr double SQUARE = 2.0; 27 28 // The running time of the curve needs to be normalized to the interval of 0.0 to 1.0; 29 // Relatively, the corresponding value of the curve also needs to be normalized to the interval of 0.0 to 1.0; 30 class Curve : public AceType { 31 DECLARE_ACE_TYPE(Curve, AceType); 32 33 public: 34 Curve() = default; 35 ~Curve() override = default; 36 37 // Returns the value at specific time. 38 // Notice: The value of time must be between 0.0 and 1.0 since the curve uses normalized timestamp. Move(float time)39 float Move(float time) 40 { 41 // time always between 0.0 and 1.0 42 return MoveInternal(time); 43 } 44 45 // Each subclass needs to override this method to implement motion in the 0.0 to 1.0 time range. 46 virtual float MoveInternal(float time) = 0; ToString()47 virtual const std::string ToString() 48 { 49 return ""; 50 } 51 }; 52 53 // The reverse curve is used to convert the direction of motion. 54 // It uses the 1.0->0.0 motion of the child curve to achieve the reverse purpose. 55 class ReverseCurve final : public Curve { 56 DECLARE_ACE_TYPE(ReverseCurve, Curve); 57 58 public: ReverseCurve(const RefPtr<Curve> & curve)59 explicit ReverseCurve(const RefPtr<Curve>& curve) : curve_(curve) {} 60 ~ReverseCurve() override = default; 61 MoveInternal(float time)62 float MoveInternal(float time) final 63 { 64 if (!curve_) { 65 return 0.0f; 66 } 67 68 if (time > 1.0f || time < 0.0f) { 69 return curve_->MoveInternal(0.0f); 70 } 71 return curve_->MoveInternal(1.0f - time); 72 } 73 74 private: 75 const RefPtr<Curve> curve_; 76 }; 77 78 class ComplementaryCurve final : public Curve { 79 DECLARE_ACE_TYPE(ComplementaryCurve, Curve); 80 81 public: ComplementaryCurve(const RefPtr<Curve> & curve)82 explicit ComplementaryCurve(const RefPtr<Curve>& curve) : curve_(curve) {} 83 ~ComplementaryCurve() override = default; 84 MoveInternal(float time)85 float MoveInternal(float time) final 86 { 87 if (!curve_) { 88 return 0.0f; 89 } 90 91 if (time > 1.0f || time < 0.0f) { 92 return curve_->MoveInternal(0.0f); 93 } 94 return 1.0f - curve_->MoveInternal(time); 95 } 96 97 private: 98 const RefPtr<Curve> curve_; 99 }; 100 101 class DecelerationCurve final : public Curve { 102 DECLARE_ACE_TYPE(DecelerationCurve, Curve); 103 104 public: MoveInternal(float time)105 float MoveInternal(float time) override 106 { 107 return 1.0f - std::pow(1.0f - time, SQUARE); 108 } 109 }; 110 111 class LinearCurve final : public Curve { 112 DECLARE_ACE_TYPE(LinearCurve, Curve); 113 114 public: MoveInternal(float time)115 float MoveInternal(float time) override 116 { 117 return time; 118 } 119 }; 120 121 class SineCurve final : public Curve { 122 DECLARE_ACE_TYPE(SineCurve, Curve); 123 124 public: MoveInternal(float time)125 float MoveInternal(float time) override 126 { 127 static constexpr float PI = 3.14f; 128 return std::sin(PI * time / 2.0f); // half period 129 } 130 }; 131 132 class ElasticsCurve final : public Curve { 133 DECLARE_ACE_TYPE(ElasticsCurve, Curve); 134 135 public: ElasticsCurve(float tension)136 explicit ElasticsCurve(float tension) : tension_(tension) {}; 137 ~ElasticsCurve() override = default; MoveInternal(float time)138 float MoveInternal(float time) override 139 { 140 float para = time - 1.0f; 141 return para * para * ((tension_ + 1.0f) * para + tension_) + 1.0f; 142 } 143 144 private: 145 float tension_ = 2.0f; // Default Elastics tension. 146 }; 147 148 enum class StepsCurvePosition { 149 START, 150 END, 151 }; 152 153 class StepsCurve : public Curve { 154 DECLARE_ACE_TYPE(StepsCurve, Curve); 155 156 public: 157 explicit StepsCurve(int32_t steps, StepsCurvePosition position = StepsCurvePosition::START) 158 : steps_(steps <= 0 ? 1 : steps), position_(position) {}; 159 ~StepsCurve() override = default; 160 MoveInternal(float time)161 float MoveInternal(float time) override 162 { 163 auto currentStep = static_cast<int32_t>(time * steps_); 164 if (position_ == StepsCurvePosition::START) { 165 currentStep++; 166 } 167 return static_cast<float>(currentStep) / steps_; 168 } 169 170 private: 171 int32_t steps_; 172 const StepsCurvePosition position_; 173 }; 174 175 class CustomCurve final : public Curve { 176 DECLARE_ACE_TYPE(CustomCurve, Curve); 177 178 public: CustomCurve(const std::function<float (float)> & func)179 explicit CustomCurve(const std::function<float(float)>& func) : interpolateFunc_(func) {} 180 ~CustomCurve() override = default; MoveInternal(float time)181 float MoveInternal(float time) override 182 { 183 float value = interpolateFunc_(time); 184 return std::clamp(value, 0.f, 1.f); 185 } 186 187 private: 188 std::function<float(float)> interpolateFunc_; 189 190 friend class NativeCurveHelper; 191 }; 192 193 } // namespace OHOS::Ace 194 195 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_CURVE_H 196