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 #include "core/animation/spring_motion.h"
17 
18 namespace OHOS::Ace {
19 namespace {
20 
21 constexpr float UNIT_CONVERT = 1000.0f;
22 
23 } // namespace
24 
SpringMotion(double start,double end,double velocity,const RefPtr<SpringProperty> & spring)25 SpringMotion::SpringMotion(double start, double end, double velocity, const RefPtr<SpringProperty>& spring)
26 {
27     Reset(start, end, velocity, spring);
28 }
29 
GetType()30 SpringModelType SpringMotion::GetType()
31 {
32     if (model_ == nullptr) {
33         LOGE("SpringModel is nullptr.");
34         return SpringModelType::CRITICAL_DAMPED;
35     }
36     return model_->GetType();
37 }
38 
GetCurrentPosition()39 double SpringMotion::GetCurrentPosition()
40 {
41     return currentPosition_;
42 }
43 
GetCurrentVelocity()44 double SpringMotion::GetCurrentVelocity()
45 {
46     return currentVelocity_;
47 }
48 
GetEndValue() const49 double SpringMotion::GetEndValue() const
50 {
51     return endPosition_;
52 }
53 
IsCompleted(double value,double velocity) const54 bool SpringMotion::IsCompleted(double value, double velocity) const
55 {
56     return NearZero(value - endPosition_, accuracy_) && NearZero(velocity, velocityAccuracy_);
57 }
58 
IsCompleted()59 bool SpringMotion::IsCompleted()
60 {
61     return IsCompleted(currentPosition_, currentVelocity_);
62 }
63 
SetAccuracy(double accuracy)64 void SpringMotion::SetAccuracy(double accuracy)
65 {
66     accuracy_ = std::abs(accuracy);
67 }
68 
SetVelocityAccuracy(double velocityAccuracy)69 void SpringMotion::SetVelocityAccuracy(double velocityAccuracy)
70 {
71     velocityAccuracy_ = std::abs(velocityAccuracy);
72 }
73 
Reset(double start,double end,double velocity,const RefPtr<SpringProperty> & spring)74 void SpringMotion::Reset(double start, double end, double velocity, const RefPtr<SpringProperty>& spring)
75 {
76     currentPosition_ = start;
77     currentVelocity_ = velocity;
78     endPosition_ = end;
79     model_ = SpringModel::Build(start - end, velocity, spring);
80 }
81 
Move(float offsetTime)82 void SpringMotion::Move(float offsetTime)
83 {
84     if (model_ == nullptr) {
85         LOGE("SpringModel is nullptr.");
86         return;
87     }
88     // change millisecond to second.
89     float offsetTimeInSecond = offsetTime / UNIT_CONVERT;
90     currentPosition_ = endPosition_ + model_->Position(offsetTimeInSecond);
91     currentVelocity_ = model_->Velocity(offsetTimeInSecond);
92     if (IsCompleted()) {
93         currentPosition_ = endPosition_;
94         currentVelocity_ = 0.0;
95     }
96 }
97 
ScrollSpringMotion(double start,double end,double velocity,const RefPtr<SpringProperty> & spring)98 ScrollSpringMotion::ScrollSpringMotion(double start, double end, double velocity, const RefPtr<SpringProperty>& spring)
99     : SpringMotion(start, end, velocity, spring)
100 {}
101 
IsCompleted()102 bool ScrollSpringMotion::IsCompleted()
103 {
104     return NearZero(currentPosition_ - endPosition_, accuracy_);
105 }
106 
GetCurrentPosition()107 double ScrollSpringMotion::GetCurrentPosition()
108 {
109     return currentPosition_;
110 }
111 
Move(float offsetTime)112 void ScrollSpringMotion::Move(float offsetTime)
113 {
114     if (model_ == nullptr) {
115         LOGE("SpringModel is nullptr.");
116         return;
117     }
118     // change millisecond to second.
119     float offsetTimeInSecond = offsetTime / UNIT_CONVERT;
120     currentPosition_ = endPosition_ + model_->Position(offsetTimeInSecond);
121     currentVelocity_ = model_->Velocity(offsetTimeInSecond);
122     if (IsCompleted()) {
123         currentPosition_ = endPosition_;
124         currentVelocity_ = 0.0;
125     }
126 }
127 
GetMotionType() const128 std::string SpringMotion::GetMotionType() const
129 {
130     return "spring";
131 }
132 
133 } // namespace OHOS::Ace