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 "animation/rs_animation_fraction.h"
17
18 #include <string>
19
20 #include "common/rs_common_def.h"
21 #include "platform/common/rs_log.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 static constexpr int INFINITE = -1;
27 static constexpr int64_t MS_TO_NS = 1000000;
28 static constexpr int REVERSE_COUNT = 2;
29 } // namespace
RSAnimationFraction()30 RSAnimationFraction::RSAnimationFraction()
31 {
32 currentIsReverseCycle_ = !isForward_;
33 }
34
SetDirectionAfterStart(const ForwardDirection & direction)35 void RSAnimationFraction::SetDirectionAfterStart(const ForwardDirection& direction)
36 {
37 direction_ = direction;
38 }
39
SetLastFrameTime(int64_t lastFrameTime)40 void RSAnimationFraction::SetLastFrameTime(int64_t lastFrameTime)
41 {
42 lastFrameTime_ = lastFrameTime;
43 }
44
GetAnimationFraction(int64_t time,bool & isInstartDelay,bool & isFinished)45 float RSAnimationFraction::GetAnimationFraction(int64_t time, bool& isInstartDelay, bool& isFinished)
46 {
47 int64_t durationNs = duration_ * MS_TO_NS;
48 int64_t startDelayNs = startDelay_ * MS_TO_NS;
49 int64_t deltaTime = time - lastFrameTime_;
50 lastFrameTime_ = time;
51 isInstartDelay = false;
52 if (durationNs <= 0 || (repeatCount_ <= 0 && repeatCount_ != INFINITE)) {
53 isFinished = true;
54 return GetEndFraction();
55 }
56 // 1. Calculates the total running fraction of animation
57 if (direction_ == ForwardDirection::NORMAL) {
58 runningTime_ += static_cast<int64_t>(deltaTime * speed_);
59 } else {
60 runningTime_ -= static_cast<int64_t>(deltaTime * speed_);
61 }
62 if (runningTime_ < startDelayNs) {
63 isFinished = IsFinished();
64 isInstartDelay = isFinished ? false : true;
65 return GetStartFraction();
66 }
67
68 // 2. Calculate the running time of the current cycle animation.
69 int64_t realPlayTime = runningTime_ - startDelayNs - (curRepeatCount_ * durationNs);
70
71 // 3. Update the number of cycles and the corresponding animation fraction.
72 if (direction_ == ForwardDirection::NORMAL) {
73 curRepeatCount_ += realPlayTime / durationNs;
74 } else {
75 while (curRepeatCount_ > 0 && realPlayTime < 0) {
76 curRepeatCount_--;
77 realPlayTime += durationNs;
78 }
79 }
80 playTime_ = realPlayTime % durationNs;
81
82 // 4. update status for auto reverse
83 isFinished = IsFinished();
84 UpdateReverseState(isFinished);
85
86 // 5. get final animation fraction
87 if (isFinished) {
88 return GetEndFraction();
89 }
90 curTimeFraction_ = static_cast<float>(playTime_) / durationNs;
91 curTimeFraction_ = currentIsReverseCycle_ ? (1.0f - curTimeFraction_) : curTimeFraction_;
92 curTimeFraction_ = std::min(std::max(curTimeFraction_, 0.0f), 1.0f);
93 return curTimeFraction_;
94 }
95
IsFinished() const96 bool RSAnimationFraction::IsFinished() const
97 {
98 if (direction_ == ForwardDirection::NORMAL) {
99 if (repeatCount_ == INFINITE) {
100 return false;
101 }
102 int64_t totalDuration = (duration_ * repeatCount_ + startDelay_) * MS_TO_NS;
103 return runningTime_ >= totalDuration;
104 } else {
105 return runningTime_ <= 0;
106 }
107 }
108
GetStartFraction() const109 float RSAnimationFraction::GetStartFraction() const
110 {
111 return isForward_ ? 0.0f : 1.0f;
112 }
113
GetEndFraction() const114 float RSAnimationFraction::GetEndFraction() const
115 {
116 float endFraction = 1.0f;
117 if ((autoReverse_ && repeatCount_ % REVERSE_COUNT == 0) || direction_ == ForwardDirection::REVERSE) {
118 endFraction = 0.0f;
119 }
120 endFraction = isForward_ ? endFraction : 1.0 - endFraction;
121 return endFraction;
122 }
123
UpdateReverseState(bool finish)124 void RSAnimationFraction::UpdateReverseState(bool finish)
125 {
126 if (isForward_) {
127 if (!autoReverse_) {
128 currentIsReverseCycle_ = false;
129 return;
130 }
131 currentIsReverseCycle_ =
132 finish ? (curRepeatCount_ % REVERSE_COUNT == 0) : (curRepeatCount_ % REVERSE_COUNT == 1);
133 } else {
134 if (!autoReverse_) {
135 currentIsReverseCycle_ = true;
136 return;
137 }
138 currentIsReverseCycle_ =
139 finish ? (curRepeatCount_ % REVERSE_COUNT == 1) : (curRepeatCount_ % REVERSE_COUNT == 0);
140 }
141 }
142
UpdateRemainTimeFraction(float fraction,int remainTime)143 void RSAnimationFraction::UpdateRemainTimeFraction(float fraction, int remainTime)
144 {
145 int64_t remainTimeNS = remainTime * MS_TO_NS;
146 int64_t durationNs = duration_ * MS_TO_NS;
147 int64_t startDelayNs = startDelay_ * MS_TO_NS;
148 float curRemianProgress = currentIsReverseCycle_ ? curTimeFraction_ : (1.0f - curTimeFraction_);
149 float ratio = 1.0f;
150 if (remainTime != 0) {
151 ratio = curRemianProgress * durationNs / remainTimeNS;
152 }
153
154 if (runningTime_ > startDelayNs || fabs(fraction) > 1e-6) {
155 if (currentIsReverseCycle_) {
156 runningTime_ =
157 static_cast<int64_t>(durationNs * (1.0f - fraction)) + startDelayNs + curRepeatCount_ * durationNs;
158 } else {
159 runningTime_ = static_cast<int64_t>(durationNs * fraction) + startDelayNs + curRepeatCount_ * durationNs;
160 }
161 }
162
163 speed_ = speed_ * ratio;
164 curTimeFraction_ = fraction;
165 }
166 } // namespace Rosen
167 } // namespace OHOS
168