• 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_path_animation.h"
17 
18 #include "animation/rs_animation_common.h"
19 #include "animation/rs_render_path_animation.h"
20 #include "platform/common/rs_log.h"
21 #include "command/rs_animation_command.h"
22 #include "transaction/rs_transaction_proxy.h"
23 #include "render/rs_path.h"
24 
25 namespace OHOS {
26 namespace Rosen {
RSPathAnimation(const RSAnimatableProperty & property,const std::shared_ptr<RSPath> & animationPath)27 RSPathAnimation::RSPathAnimation(const RSAnimatableProperty& property, const std::shared_ptr<RSPath>& animationPath)
28     : RSPropertyAnimation(property), animationPath_(animationPath)
29 {
30     SetAdditive(false);
31 }
32 
RSPathAnimation(const RSAnimatableProperty & property,const std::string & path,const Vector2f & startValue,const Vector2f & endValue)33 RSPathAnimation::RSPathAnimation(
34     const RSAnimatableProperty& property, const std::string& path, const Vector2f& startValue, const Vector2f& endValue)
35     : RSPathAnimation(property, PreProcessPath(path, startValue, endValue))
36 {}
37 
38 const std::vector<RSAnimatableProperty> RSPathAnimation::PROP_FOR_PATH_ANIM = {
39     RSAnimatableProperty::BOUNDS_POSITION,
40     RSAnimatableProperty::FRAME_POSITION,
41     RSAnimatableProperty::TRANSLATE
42 };
43 
SetTimingCurve(const RSAnimationTimingCurve & timingCurve)44 void RSPathAnimation::SetTimingCurve(const RSAnimationTimingCurve& timingCurve)
45 {
46     timingCurve_ = timingCurve;
47 }
48 
GetTimingCurve() const49 const RSAnimationTimingCurve& RSPathAnimation::GetTimingCurve() const
50 {
51     return timingCurve_;
52 }
53 
SetRotationMode(const RotationMode & rotationMode)54 void RSPathAnimation::SetRotationMode(const RotationMode& rotationMode)
55 {
56     if (IsStarted()) {
57         ROSEN_LOGE("Failed to enable rotate, path animation has started!");
58         return;
59     }
60 
61     rotationMode_ = rotationMode;
62 }
63 
GetRotationMode() const64 RotationMode RSPathAnimation::GetRotationMode() const
65 {
66     return rotationMode_;
67 }
68 
SetBeginFraction(float fraction)69 void RSPathAnimation::SetBeginFraction(float fraction)
70 {
71     if (IsStarted()) {
72         ROSEN_LOGE("Failed to set begin fraction, path animation has started!");
73         return;
74     }
75 
76     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction > endFraction_) {
77         ROSEN_LOGE("Failed to set begin fraction, invalid value:%f", fraction);
78         return;
79     }
80 
81     beginFraction_ = fraction;
82 }
83 
GetBeginFraction() const84 float RSPathAnimation::GetBeginFraction() const
85 {
86     return beginFraction_;
87 }
88 
SetEndFraction(float fraction)89 void RSPathAnimation::SetEndFraction(float fraction)
90 {
91     if (IsStarted()) {
92         ROSEN_LOGE("Failed to set end fraction, path animation has started!");
93         return;
94     }
95 
96     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction < beginFraction_) {
97         ROSEN_LOGE("Failed to set end fraction, invalid value:%f", fraction);
98         return;
99     }
100 
101     endFraction_ = fraction;
102 }
103 
GetEndFraction() const104 float RSPathAnimation::GetEndFraction() const
105 {
106     return endFraction_;
107 }
108 
OnStart()109 void RSPathAnimation::OnStart()
110 {
111     if (!IsAnimatablePathProperty(GetProperty())) {
112         ROSEN_LOGE("Failed to start path animation, property[%d] is not supported!", static_cast<int>(GetProperty()));
113         return;
114     }
115 
116     if (!animationPath_) {
117         ROSEN_LOGE("Failed to start path animation, path is null!");
118         return;
119     }
120 
121     RSPropertyAnimation::OnStart();
122 
123     auto target = GetTarget().lock();
124     if (target == nullptr) {
125         ROSEN_LOGE("Failed to start path animation, target is null!");
126         return;
127     }
128 
129     auto interpolator = timingCurve_.GetInterpolator(GetDuration());
130     auto animation = std::make_shared<RSRenderPathAnimation>(
131         GetId(), GetProperty(), originValue_, target->stagingProperties_.GetRotation(), animationPath_);
132     animation->SetDuration(GetDuration());
133     animation->SetStartDelay(GetStartDelay());
134     animation->SetRepeatCount(GetRepeatCount());
135     animation->SetAutoReverse(GetAutoReverse());
136     animation->SetSpeed(GetSpeed());
137     animation->SetFillMode(GetFillMode());
138     animation->SetDirection(GetDirection());
139     animation->SetInterpolator(interpolator);
140     animation->SetRotationMode(GetRotationMode());
141     animation->SetBeginFraction(GetBeginFraction());
142     animation->SetEndFraction(GetEndFraction());
143     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
144     auto transactionProxy = RSTransactionProxy::GetInstance();
145     if (transactionProxy != nullptr) {
146         transactionProxy->AddCommand(command, target->IsRenderServiceNode());
147         if (target->NeedForcedSendToRemote()) {
148             std::unique_ptr<RSCommand> commandForRemote =
149                 std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
150             transactionProxy->AddCommand(commandForRemote, true);
151         }
152     }
153 }
154 
InitInterpolationValue()155 void RSPathAnimation::InitInterpolationValue()
156 {
157     if (!animationPath_) {
158         ROSEN_LOGE("Failed to update interpolation value, path is null!");
159         return;
160     }
161 
162 #ifdef ROSEN_OHOS
163     animationPath_->GetPosTan(0.0f, startValue_, startTangent_);
164     animationPath_->GetPosTan(animationPath_->GetDistance(), endValue_, endTangent_);
165     byValue_ = endValue_ - startValue_;
166 #endif
167 }
168 
OnUpdateStagingValue(bool isFirstStart)169 void RSPathAnimation::OnUpdateStagingValue(bool isFirstStart)
170 {
171     auto target = GetTarget().lock();
172     if (target == nullptr) {
173         ROSEN_LOGE("Failed to update staging value, target is null!");
174         return;
175     }
176 
177     RSPropertyAnimation::OnUpdateStagingValue(isFirstStart);
178 
179     float startTangent = 0.0f;
180     float endTangent = 0.0f;
181     switch (rotationMode_) {
182         case RotationMode::ROTATE_NONE:
183             return;
184         case RotationMode::ROTATE_AUTO:
185             startTangent = startTangent_;
186             endTangent = endTangent_;
187             break;
188         case RotationMode::ROTATE_AUTO_REVERSE:
189             startTangent = startTangent_ + 180.0f;
190             endTangent = endTangent_ + 180.0f;
191             break;
192         default:
193             ROSEN_LOGE("Unknow rotation mode!");
194             return;
195     }
196     if (!GetDirection()) {
197         std::swap(startTangent, endTangent);
198     }
199 
200     float targetRotation = 0.0f;
201     float byRotation = endTangent - startTangent;
202     if (isFirstStart) {
203         if (GetAutoReverse() && GetRepeatCount() % 2 == 0) {
204             targetRotation = startTangent;
205         } else {
206             targetRotation = endTangent;
207         }
208     } else {
209         float currentRotation = target->stagingProperties_.GetRotation();
210         if (GetAutoReverse() && GetRepeatCount() % 2 == 0) {
211             targetRotation = IsReversed() ? currentRotation + byRotation : currentRotation - byRotation;
212         } else {
213             targetRotation = IsReversed() ? currentRotation - byRotation : currentRotation + byRotation;
214         }
215     }
216 
217     target->stagingProperties_.SetRotation(targetRotation);
218 }
219 
ReplaceSubString(std::string & sourceStr,const std::string & subStr,const std::string & newStr) const220 void RSPathAnimation::ReplaceSubString(
221     std::string& sourceStr, const std::string& subStr, const std::string& newStr) const
222 {
223     std::string::size_type position = 0;
224     while ((position = sourceStr.find(subStr)) != std::string::npos) {
225         sourceStr.replace(position, subStr.length(), newStr);
226     }
227 
228     ROSEN_LOGD("SVG path:%s", sourceStr.c_str());
229 }
230 
PreProcessPath(const std::string & path,const Vector2f & startValue,const Vector2f & endValue) const231 const std::shared_ptr<RSPath> RSPathAnimation::PreProcessPath(
232     const std::string& path, const Vector2f& startValue, const Vector2f& endValue) const
233 {
234     std::string animationPath = path;
235     ReplaceSubString(animationPath, "start.x", std::to_string(startValue[0]));
236     ReplaceSubString(animationPath, "start.y", std::to_string(startValue[1]));
237     ReplaceSubString(animationPath, "end.x", std::to_string(endValue[0]));
238     ReplaceSubString(animationPath, "end.y", std::to_string(endValue[1]));
239 #ifdef ROSEN_OHOS
240     return RSPath::CreateRSPath(animationPath);
241 #else
242     return nullptr;
243 #endif
244 }
245 
IsAnimatablePathProperty(const RSAnimatableProperty & property)246 bool RSPathAnimation::IsAnimatablePathProperty(const RSAnimatableProperty& property)
247 {
248     if (find(PROP_FOR_PATH_ANIM.begin(), PROP_FOR_PATH_ANIM.end(), property) == PROP_FOR_PATH_ANIM.end()) {
249         return false;
250     }
251 
252     return true;
253 }
254 } // namespace Rosen
255 } // namespace OHOS
256