1 /*
2  * Copyright (c) 2022 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_property_animation.h"
17 
18 #include "animation/rs_render_animation.h"
19 #include "modifier/rs_modifier.h"
20 #include "modifier/rs_property.h"
21 #include "ui/rs_node.h"
22 
23 namespace OHOS {
24 namespace Rosen {
25 static constexpr int NUMBER_FOR_HALF = 2;
26 
RSPropertyAnimation(std::shared_ptr<RSPropertyBase> property)27 RSPropertyAnimation::RSPropertyAnimation(std::shared_ptr<RSPropertyBase> property) : property_(property)
28 {
29     InitAdditiveMode();
30 }
31 
SetIsCustom(const bool isCustom)32 void RSPropertyAnimation::SetIsCustom(const bool isCustom)
33 {
34     isCustom_ = isCustom;
35 }
36 
SetAdditive(bool isAdditive)37 void RSPropertyAnimation::SetAdditive(bool isAdditive)
38 {
39     isAdditive_ = isAdditive;
40 }
41 
GetAdditive() const42 bool RSPropertyAnimation::GetAdditive() const
43 {
44     return isAdditive_;
45 }
46 
GetOriginValue() const47 const std::shared_ptr<RSPropertyBase> RSPropertyAnimation::GetOriginValue() const
48 {
49     return originValue_;
50 }
51 
SetPropertyValue(const std::shared_ptr<RSPropertyBase> & value)52 void RSPropertyAnimation::SetPropertyValue(const std::shared_ptr<RSPropertyBase>& value)
53 {
54     if (property_ != nullptr) {
55         property_->SetValue(value);
56     }
57 }
58 
GetPropertyValue() const59 const std::shared_ptr<RSPropertyBase> RSPropertyAnimation::GetPropertyValue() const
60 {
61     if (property_ != nullptr) {
62         return property_->Clone();
63     }
64 
65     return nullptr;
66 }
67 
GetPropertyId() const68 PropertyId RSPropertyAnimation::GetPropertyId() const
69 {
70     if (property_ != nullptr) {
71         return property_->GetId();
72     }
73 
74     return {};
75 }
76 
OnStart()77 void RSPropertyAnimation::OnStart()
78 {
79     if (!hasOriginValue_) {
80         originValue_ = GetPropertyValue();
81         hasOriginValue_ = true;
82     }
83     InitInterpolationValue();
84 }
85 
SetOriginValue(const std::shared_ptr<RSPropertyBase> & originValue)86 void RSPropertyAnimation::SetOriginValue(const std::shared_ptr<RSPropertyBase>& originValue)
87 {
88     if (!hasOriginValue_ && originValue != nullptr) {
89         originValue_ = originValue->Clone();
90         hasOriginValue_ = true;
91     }
92 }
93 
InitInterpolationValue()94 void RSPropertyAnimation::InitInterpolationValue()
95 {
96     if (isDelta_) {
97         startValue_ = originValue_->Clone();
98         endValue_ = originValue_ + byValue_;
99     } else {
100         byValue_ = endValue_ - startValue_;
101     }
102 }
103 
OnUpdateStagingValue(bool isFirstStart)104 void RSPropertyAnimation::OnUpdateStagingValue(bool isFirstStart)
105 {
106     auto startValue = startValue_;
107     auto endValue = endValue_;
108     if (!GetDirection()) {
109         std::swap(startValue, endValue);
110     }
111     auto byValue = endValue - startValue;
112     auto targetValue = endValue;
113     if (isFirstStart) {
114         if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
115             targetValue = startValue;
116         } else {
117             targetValue = endValue;
118         }
119     } else {
120         auto currentValue = GetPropertyValue();
121         if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
122             targetValue = IsReversed() ? currentValue + byValue : currentValue - byValue;
123         } else {
124             targetValue = IsReversed() ? currentValue - byValue : currentValue + byValue;
125         }
126     }
127 
128     SetPropertyValue(targetValue);
129 }
130 
UpdateStagingValueOnInteractiveFinish(RSInteractiveAnimationPosition pos)131 void RSPropertyAnimation::UpdateStagingValueOnInteractiveFinish(RSInteractiveAnimationPosition pos)
132 {
133     auto targetValue = endValue_;
134     if (pos ==RSInteractiveAnimationPosition::START) {
135         targetValue = startValue_;
136     } else if (pos ==RSInteractiveAnimationPosition::END) {
137         targetValue = endValue_;
138     } else if (pos ==RSInteractiveAnimationPosition::CURRENT) {
139         if (IsUiAnimation() && property_ != nullptr) {
140             property_->SetValueFromRender(property_->GetRenderProperty());
141             return;
142         }
143     }
144     SetPropertyValue(targetValue);
145 }
146 
SetPropertyOnAllAnimationFinish()147 void RSPropertyAnimation::SetPropertyOnAllAnimationFinish()
148 {
149     if (property_ != nullptr) {
150         property_->UpdateOnAllAnimationFinish();
151     }
152 }
153 
InitAdditiveMode()154 void RSPropertyAnimation::InitAdditiveMode()
155 {
156     if (property_ == nullptr) {
157         return;
158     }
159 
160     switch (property_->type_) {
161         case RSModifierType::QUATERNION:
162             SetAdditive(false);
163             break;
164         default:
165             break;
166     }
167 }
168 } // namespace Rosen
169 } // namespace OHOS
170