1 /* 2 * Copyright (c) 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_BEZIER_VARIABLE_VELOCITY_MOTION_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_BEZIER_VARIABLE_VELOCITY_MOTION_H 18 #include "base/geometry/dimension.h" 19 #include "core/animation/curves.h" 20 #include "core/animation/motion.h" 21 22 namespace OHOS::Ace { 23 24 static constexpr Dimension HOT_ZONE_HEIGHT_VP_DIM = 59.0_vp; 25 static constexpr Dimension HOT_ZONE_WIDTH_VP_DIM = 26.0_vp; 26 using MotionCompleteCallbck = std::function<bool(float)>; 27 constexpr float UNIT_CONVERT = 1000.0f; 28 constexpr float MAX_SPEED = 2400.0f; 29 30 class ACE_EXPORT BezierVariableVelocityMotion : public Motion { 31 DECLARE_ACE_TYPE(BezierVariableVelocityMotion, Motion); 32 33 public: BezierVariableVelocityMotion(float offsetPct,MotionCompleteCallbck && complete)34 BezierVariableVelocityMotion(float offsetPct, MotionCompleteCallbck&& complete) 35 : complete_(complete), offsetPct_(offsetPct) 36 { 37 Reset(offsetPct_, true); 38 } 39 /** 40 * @description: Get the roll distance 41 * @return The scroll distance notified to the listener 42 */ GetCurrentPosition()43 double GetCurrentPosition() override 44 { 45 return Positive(offsetPct_) ? scrollOffset_ : Negative(offsetPct_) ? -scrollOffset_ : 0; 46 } 47 GetCurrentVelocity()48 double GetCurrentVelocity() override 49 { 50 return velocity_; 51 } 52 /** 53 * @description: By adding a callback, it is up to the listener to decide whether to stop the motion 54 * @return True stop 55 */ IsCompleted()56 bool IsCompleted() override 57 { 58 if (complete_) { 59 return complete_(offsetPct_); 60 } 61 return true; 62 } 63 64 /** 65 * @description: The ratio of the hot zone offset to the maximum hot zone offset is used as an input parameter of 66 * bezier, resulting in an output, which is the proportion of velocity. 67 * The farther away you are from the outer edge of the hot zone, the greater the velocity 68 * @param {float} offsetPct 69 * @return Scroll speed 70 */ ComputeVelocity(float offsetPct)71 double ComputeVelocity(float offsetPct) 72 { 73 return Curves::SHARP->MoveInternal(std::abs(offsetPct)) * MAX_SPEED; 74 } 75 GetMotionType()76 std::string GetMotionType() const override 77 { 78 return "bezier variable velocity"; 79 } 80 81 /** 82 * @description: Each subclass of scrollable component should override this method to perform motion in each 83 * timestamp. This function is called in motion's OnTimestampChanged function, where inform the listener of the 84 * distance of rolling 85 * @param {float} offsetTime Time offset, continuously growing, with irregular intervals 86 * @return None 87 */ Move(float offsetTime)88 void Move(float offsetTime) override 89 { 90 scrollOffset_ = velocity_ * (offsetTime - lastOffsetTime_) / UNIT_CONVERT; 91 lastOffsetTime_ = offsetTime; 92 } 93 94 /** 95 * @description: Resets the hot spot offset to change the current speed, ultimately for variable speed scrolling 96 * @param {float} offsetPct Hot Spot Offset percent. The ratio of its maximum offset to the hot zone is used as an 97 * input parameter to bezier 98 * @param {float} reset_time. When the animation starts, it needs to be reset 99 * @return None 100 */ 101 void Reset(float offsetPct, bool reset_time = false) 102 { 103 offsetPct_ = offsetPct; 104 velocity_ = ComputeVelocity(offsetPct_); 105 if (reset_time) { 106 lastOffsetTime_ = 0.0f; 107 } 108 } 109 110 /** 111 * @description: reinitialize BezierVariableVelocityMotion 112 * @param {float} offsetPct 113 * @return {*} 114 */ ReInit(float offsetPct)115 void ReInit(float offsetPct) 116 { 117 Reset(offsetPct, true); 118 } 119 120 private: 121 // Tells the listener how far they need to roll, in px 122 float scrollOffset_ = 0.0f; 123 MotionCompleteCallbck complete_; 124 // It is used to record the current speed, and different speeds can be passed in through the reset function, so that 125 // the speed can be changed 126 float velocity_ = 0.0f; 127 // The hot zone offset corresponds to a fixed velocity one-to-one by the bezier. 128 // It is also possible to implement a generic class with velocity as an input parameter, but this is not necessary 129 // at the moment 130 float offsetPct_ = 0.0f; 131 // Record the last time given by the move function 132 float lastOffsetTime_ = 0.0f; 133 }; 134 } // namespace OHOS::Ace 135 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_ANIMATION_BEZIER_VARIABLE_VELOCITY_MOTION_H