• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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