• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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_path_animation.h"
17 
18 #include "animation/rs_animation_common.h"
19 #include "animation/rs_motion_path_option.h"
20 #include "animation/rs_render_path_animation.h"
21 #include "command/rs_animation_command.h"
22 #include "modifier/rs_modifier.h"
23 #include "modifier/rs_property.h"
24 #include "platform/common/rs_log.h"
25 #include "render/rs_path.h"
26 #include "transaction/rs_transaction_proxy.h"
27 #include "ui/rs_node.h"
28 
29 namespace OHOS {
30 namespace Rosen {
31 static constexpr int NUMBER_FOR_HALF = 2;
32 
RSPathAnimation(std::shared_ptr<RSPropertyBase> property,const std::shared_ptr<RSPath> & animationPath)33 RSPathAnimation::RSPathAnimation(std::shared_ptr<RSPropertyBase> property,
34     const std::shared_ptr<RSPath>& animationPath) : RSPropertyAnimation(property), animationPath_(animationPath)
35 {}
36 
RSPathAnimation(std::shared_ptr<RSPropertyBase> property,const std::string & path,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)37 RSPathAnimation::RSPathAnimation(std::shared_ptr<RSPropertyBase> property, const std::string& path,
38     const std::shared_ptr<RSPropertyBase>& startValue, const std::shared_ptr<RSPropertyBase>& endValue)
39     : RSPathAnimation(property, PreProcessPath(path, startValue, endValue))
40 {
41     startValue_ = startValue;
42     endValue_ = endValue;
43     InitNeedPath(startValue_, endValue_);
44 }
45 
SetTimingCurve(const RSAnimationTimingCurve & timingCurve)46 void RSPathAnimation::SetTimingCurve(const RSAnimationTimingCurve& timingCurve)
47 {
48     timingCurve_ = timingCurve;
49 }
50 
GetTimingCurve() const51 const RSAnimationTimingCurve& RSPathAnimation::GetTimingCurve() const
52 {
53     return timingCurve_;
54 }
55 
SetRotationMode(const RotationMode & rotationMode)56 void RSPathAnimation::SetRotationMode(const RotationMode& rotationMode)
57 {
58     if (RSAnimation::IsStarted()) {
59         ROSEN_LOGE("Failed to enable rotate, path animation has started!");
60         return;
61     }
62 
63     rotationMode_ = rotationMode;
64 }
65 
GetRotationMode() const66 RotationMode RSPathAnimation::GetRotationMode() const
67 {
68     return rotationMode_;
69 }
70 
SetBeginFraction(float fraction)71 void RSPathAnimation::SetBeginFraction(float fraction)
72 {
73     if (IsStarted()) {
74         ROSEN_LOGE("Failed to set begin fraction, path animation has started!");
75         return;
76     }
77 
78     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction > endFraction_) {
79         ROSEN_LOGE("Failed to set begin fraction, invalid value:%{public}f", fraction);
80         return;
81     }
82 
83     beginFraction_ = fraction;
84 }
85 
GetBeginFraction() const86 float RSPathAnimation::GetBeginFraction() const
87 {
88     return beginFraction_;
89 }
90 
SetEndFraction(float fraction)91 void RSPathAnimation::SetEndFraction(float fraction)
92 {
93     if (IsStarted()) {
94         ROSEN_LOGE("Failed to set end fraction, path animation has started!");
95         return;
96     }
97 
98     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX || fraction < beginFraction_) {
99         ROSEN_LOGE("Failed to set end fraction, invalid value:%{public}f", fraction);
100         return;
101     }
102 
103     endFraction_ = fraction;
104 }
105 
GetEndFraction() const106 float RSPathAnimation::GetEndFraction() const
107 {
108     return endFraction_;
109 }
110 
SetPathNeedAddOrigin(bool needAddOrigin)111 void RSPathAnimation::SetPathNeedAddOrigin(bool needAddOrigin)
112 {
113     if (IsStarted()) {
114         ROSEN_LOGE("Failed to set need Add Origin, path animation has started!");
115         return;
116     }
117 
118     needAddOrigin_ = needAddOrigin;
119 }
120 
GetPathNeedAddOrigin() const121 bool RSPathAnimation::GetPathNeedAddOrigin() const
122 {
123     return needAddOrigin_;
124 }
125 
OnStart()126 void RSPathAnimation::OnStart()
127 {
128     if (!animationPath_) {
129         ROSEN_LOGE("Failed to start path animation, path is null!");
130         return;
131     }
132 
133     RSPropertyAnimation::OnStart();
134     auto target = GetTarget().lock();
135     if (target == nullptr) {
136         ROSEN_LOGE("Failed to start curve animation, target is null!");
137         return;
138     }
139 
140     InitRotationId(target);
141     auto interpolator = timingCurve_.GetInterpolator(GetDuration());
142     auto animation = std::make_shared<RSRenderPathAnimation>(GetId(), GetPropertyId(),
143         originValue_->GetRenderProperty(), startValue_->GetRenderProperty(), endValue_->GetRenderProperty(),
144         target->GetStagingProperties().GetRotation(), animationPath_);
145     UpdateParamToRenderAnimation(animation);
146     animation->SetInterpolator(interpolator);
147     animation->SetRotationMode(GetRotationMode());
148     animation->SetBeginFraction(GetBeginFraction());
149     animation->SetEndFraction(GetEndFraction());
150     animation->SetIsNeedPath(isNeedPath_);
151     animation->SetPathNeedAddOrigin(GetPathNeedAddOrigin());
152     animation->SetAdditive(GetAdditive());
153     animation->SetRotationId(rotationId_);
154     if (isNeedPath_) {
155         property_->AddPathAnimation();
156     }
157     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
158     auto transactionProxy = RSTransactionProxy::GetInstance();
159     if (transactionProxy != nullptr) {
160         transactionProxy->AddCommand(command, target->IsRenderServiceNode(),
161             target->GetFollowType(), target->GetId());
162         if (target->NeedForcedSendToRemote()) {
163             std::unique_ptr<RSCommand> commandForRemote =
164                 std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
165             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
166         }
167     }
168 }
169 
InitInterpolationValue()170 void RSPathAnimation::InitInterpolationValue()
171 {
172     if (!animationPath_) {
173         ROSEN_LOGE("Failed to update interpolation value, path is null!");
174         return;
175     }
176 
177     if (isNeedPath_) {
178         if (startValue_->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F &&
179             InitInterpolationVector2f(startValue_, endValue_)) {
180             return;
181         }
182         if (startValue_->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F &&
183             InitInterpolationVector4f(startValue_, endValue_)) {
184             return;
185         }
186     }
187 
188     byValue_ = endValue_ - startValue_;
189 }
190 
OnUpdateStagingValue(bool isFirstStart)191 void RSPathAnimation::OnUpdateStagingValue(bool isFirstStart)
192 {
193     auto target = GetTarget().lock();
194     if (target == nullptr) {
195         ROSEN_LOGE("Failed to update staging value, target is null!");
196         return;
197     }
198 
199     RSPropertyAnimation::OnUpdateStagingValue(isFirstStart);
200 
201     float startTangent = 0.0f;
202     float endTangent = 0.0f;
203     switch (rotationMode_) {
204         case RotationMode::ROTATE_NONE:
205             return;
206         case RotationMode::ROTATE_AUTO:
207             startTangent = startTangent_;
208             endTangent = endTangent_;
209             break;
210         case RotationMode::ROTATE_AUTO_REVERSE:
211             startTangent = startTangent_ + 180.0f;
212             endTangent = endTangent_ + 180.0f;
213             break;
214         default:
215             ROSEN_LOGE("Unknow rotation mode!");
216             return;
217     }
218     if (!GetDirection()) {
219         std::swap(startTangent, endTangent);
220     }
221 
222     float targetRotation = 0.0f;
223     if (isFirstStart) {
224         if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
225             targetRotation = startTangent;
226         } else {
227             targetRotation = endTangent;
228         }
229     } else {
230         float byRotation = endTangent - startTangent;
231         float currentRotation = target->GetStagingProperties().GetRotation();
232         if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
233             targetRotation = IsReversed() ? currentRotation + byRotation
234                 : currentRotation - byRotation;
235         } else {
236             targetRotation = IsReversed() ? currentRotation - byRotation
237                 : currentRotation + byRotation;
238         }
239     }
240 
241     SetRotation(target, targetRotation);
242 }
243 
InitRotationId(const std::shared_ptr<RSNode> & node)244 void RSPathAnimation::InitRotationId(const std::shared_ptr<RSNode>& node)
245 {
246     if (GetRotationPropertyId(node) == 0) {
247         node->SetRotation(0.f);
248     }
249     rotationId_ = GetRotationPropertyId(node);
250 }
251 
GetRotationPropertyId(const std::shared_ptr<RSNode> & node)252 PropertyId RSPathAnimation::GetRotationPropertyId(const std::shared_ptr<RSNode>& node)
253 {
254     std::unique_lock<std::recursive_mutex> lock(node->GetPropertyMutex());
255     auto iter = node->propertyModifiers_.find(RSModifierType::ROTATION);
256     if (iter != node->propertyModifiers_.end()) {
257         return iter->second->GetPropertyId();
258     }
259 
260     for (const auto& [id, modifier] : node->modifiers_) {
261         if (modifier->GetModifierType() == RSModifierType::ROTATION) {
262             return modifier->GetPropertyId();
263         }
264     }
265     return 0;
266 }
267 
SetRotation(const std::shared_ptr<RSNode> & node,const float rotation)268 void RSPathAnimation::SetRotation(const std::shared_ptr<RSNode>& node, const float rotation)
269 {
270     std::unique_lock<std::recursive_mutex> lock(node->GetPropertyMutex());
271     auto iter = node->modifiers_.find(rotationId_);
272     if (iter != node->modifiers_.end()) {
273         auto modifier = iter->second;
274         if (modifier != nullptr) {
275             std::static_pointer_cast<RSProperty<float>>(modifier->GetProperty())->stagingValue_ = rotation;
276         }
277         return;
278     }
279 
280     for (const auto& [type, modifier] : node->propertyModifiers_) {
281         if (modifier != nullptr && modifier->GetPropertyId() == rotationId_) {
282             std::static_pointer_cast<RSProperty<float>>(modifier->GetProperty())->stagingValue_ = rotation;
283         }
284         return;
285     }
286 }
287 
OnCallFinishCallback()288 void RSPathAnimation::OnCallFinishCallback()
289 {
290     if (property_ != nullptr) {
291         property_->RemovePathAnimation();
292     }
293 }
294 
ReplaceSubString(std::string & sourceStr,const std::string & subStr,const std::string & newStr) const295 void RSPathAnimation::ReplaceSubString(std::string& sourceStr, const std::string& subStr,
296     const std::string& newStr) const
297 {
298     std::string::size_type position = 0;
299     while ((position = sourceStr.find(subStr)) != std::string::npos) {
300         sourceStr.replace(position, subStr.length(), newStr);
301     }
302 
303     ROSEN_LOGD("SVG path:%{public}s", sourceStr.c_str());
304 }
305 
ProcessPath(const std::string & path,const float startX,const float startY,const float endX,const float endY) const306 const std::shared_ptr<RSPath> RSPathAnimation::ProcessPath(const std::string& path, const float startX,
307     const float startY, const float endX, const float endY) const
308 {
309     std::string animationPath = path;
310     ReplaceSubString(animationPath, "start.x", std::to_string(startX));
311     ReplaceSubString(animationPath, "start.y", std::to_string(startY));
312     ReplaceSubString(animationPath, "end.x", std::to_string(endX));
313     ReplaceSubString(animationPath, "end.y", std::to_string(endY));
314     return RSPath::CreateRSPath(animationPath);
315 }
316 
PreProcessPath(const std::string & path,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue) const317 const std::shared_ptr<RSPath> RSPathAnimation::PreProcessPath(const std::string& path,
318     const std::shared_ptr<RSPropertyBase>& startValue,
319     const std::shared_ptr<RSPropertyBase>& endValue) const
320 {
321     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
322     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
323     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F && startVector2f != nullptr &&
324         endVector2f != nullptr) {
325         return ProcessPath(path, startVector2f->Get()[0], startVector2f->Get()[1], endVector2f->Get()[0],
326             endVector2f->Get()[1]);
327     }
328 
329     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
330     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
331     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F && startVector4f != nullptr &&
332         endVector4f != nullptr) {
333         return ProcessPath(path, startVector4f->Get()[0], startVector4f->Get()[1], endVector4f->Get()[0],
334             endVector4f->Get()[1]);
335     }
336 
337     return {};
338 }
339 
InitNeedPath(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)340 void RSPathAnimation::InitNeedPath(const std::shared_ptr<RSPropertyBase>& startValue,
341     const std::shared_ptr<RSPropertyBase>& endValue)
342 {
343     if (startValue == nullptr || endValue == nullptr) {
344         ROSEN_LOGD("Input is invaild, failed to InitNeedPath.");
345         return;
346     }
347     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
348     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
349     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F &&
350         startVector4f != nullptr && endVector4f != nullptr) {
351         Vector2f start(startVector4f->Get()[0], startVector4f->Get()[1]);
352         Vector2f end(endVector4f->Get()[0], endVector4f->Get()[1]);
353         isNeedPath_ = (start != end);
354         if (isNeedPath_) {
355             SetAdditive(false);
356         }
357         return;
358     }
359 
360     SetAdditive(false);
361 }
362 
InitInterpolationVector2f(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)363 bool RSPathAnimation::InitInterpolationVector2f(const std::shared_ptr<RSPropertyBase>& startValue,
364     const std::shared_ptr<RSPropertyBase>& endValue)
365 {
366     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
367     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
368     if (startVector2f != nullptr && endVector2f != nullptr) {
369         animationPath_->GetPosTan(0.0f * beginFraction_, startVector2f->stagingValue_, startTangent_);
370         animationPath_->GetPosTan(animationPath_->GetDistance() * endFraction_,
371             endVector2f->stagingValue_, endTangent_);
372         auto originVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(GetOriginValue());
373         if (originVector2f != nullptr && needAddOrigin_) {
374             UpdateVector2fValueAddOrigin(startVector2f->stagingValue_, endVector2f->stagingValue_,
375                 originVector2f->stagingValue_);
376         }
377         byValue_ = endValue - startValue;
378         return true;
379     }
380 
381     return false;
382 }
383 
InitInterpolationVector4f(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)384 bool RSPathAnimation::InitInterpolationVector4f(const std::shared_ptr<RSPropertyBase>& startValue,
385     const std::shared_ptr<RSPropertyBase>& endValue)
386 {
387     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
388     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
389     if (startVector4f != nullptr && endVector4f != nullptr) {
390         animationPath_->GetPosTan(0.0f * beginFraction_, startVector4f->stagingValue_, startTangent_);
391         animationPath_->GetPosTan(animationPath_->GetDistance() * endFraction_,
392             endVector4f->stagingValue_, endTangent_);
393         auto originVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(GetOriginValue());
394         if (originVector4f != nullptr && needAddOrigin_) {
395             UpdateVector4fValueAddOrigin(startVector4f->stagingValue_, endVector4f->stagingValue_,
396                 originVector4f->stagingValue_);
397         }
398         byValue_ = endValue - startValue;
399         return true;
400     }
401 
402     return false;
403 }
404 
UpdateVector2fValueAddOrigin(Vector2f & startValue,Vector2f & endValue,Vector2f & deltaValue)405 void RSPathAnimation::UpdateVector2fValueAddOrigin(Vector2f& startValue, Vector2f& endValue, Vector2f& deltaValue)
406 {
407     startValue += deltaValue;
408     endValue += deltaValue;
409 }
410 
UpdateVector4fValueAddOrigin(Vector4f & startValue,Vector4f & endValue,Vector4f & deltaValue)411 void RSPathAnimation::UpdateVector4fValueAddOrigin(Vector4f& startValue, Vector4f& endValue, Vector4f& deltaValue)
412 {
413     startValue[0] += deltaValue[0];
414     startValue[1] += deltaValue[1];
415     endValue[0] += deltaValue[0];
416     endValue[1] += deltaValue[1];
417 }
418 } // namespace Rosen
419 } // namespace OHOS
420