• 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 path 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     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
159     if (target->NeedForcedSendToRemote()) {
160         std::unique_ptr<RSCommand> commandForRemote =
161             std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
162         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
163     }
164 }
165 
InitInterpolationValue()166 void RSPathAnimation::InitInterpolationValue()
167 {
168     if (!animationPath_) {
169         ROSEN_LOGE("Failed to update interpolation value, path is null!");
170         return;
171     }
172 
173     if (isNeedPath_) {
174         if (startValue_->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F &&
175             InitInterpolationVector2f(startValue_, endValue_)) {
176             return;
177         }
178         if (startValue_->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F &&
179             InitInterpolationVector4f(startValue_, endValue_)) {
180             return;
181         }
182     }
183 
184     byValue_ = endValue_ - startValue_;
185 }
186 
OnUpdateStagingValue(bool isFirstStart)187 void RSPathAnimation::OnUpdateStagingValue(bool isFirstStart)
188 {
189     auto target = GetTarget().lock();
190     if (target == nullptr) {
191         ROSEN_LOGE("Failed to update staging value, target is null!");
192         return;
193     }
194 
195     RSPropertyAnimation::OnUpdateStagingValue(isFirstStart);
196 
197     float startTangent = 0.0f;
198     float endTangent = 0.0f;
199     switch (rotationMode_) {
200         case RotationMode::ROTATE_NONE:
201             return;
202         case RotationMode::ROTATE_AUTO:
203             startTangent = startTangent_;
204             endTangent = endTangent_;
205             break;
206         case RotationMode::ROTATE_AUTO_REVERSE:
207             startTangent = startTangent_ + 180.0f;
208             endTangent = endTangent_ + 180.0f;
209             break;
210         default:
211             ROSEN_LOGE("Unknow rotation mode!");
212             return;
213     }
214     if (!GetDirection()) {
215         std::swap(startTangent, endTangent);
216     }
217 
218     float targetRotation = 0.0f;
219     if (isFirstStart) {
220         if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
221             targetRotation = startTangent;
222         } else {
223             targetRotation = endTangent;
224         }
225     } else {
226         float byRotation = endTangent - startTangent;
227         float currentRotation = target->GetStagingProperties().GetRotation();
228         if (GetAutoReverse() && GetRepeatCount() % NUMBER_FOR_HALF == 0) {
229             targetRotation = IsReversed() ? currentRotation + byRotation
230                 : currentRotation - byRotation;
231         } else {
232             targetRotation = IsReversed() ? currentRotation - byRotation
233                 : currentRotation + byRotation;
234         }
235     }
236 
237     SetRotation(target, targetRotation);
238 }
239 
InitRotationId(const std::shared_ptr<RSNode> & node)240 void RSPathAnimation::InitRotationId(const std::shared_ptr<RSNode>& node)
241 {
242     if (GetRotationPropertyId(node) == 0) {
243         node->SetRotation(0.f);
244     }
245     rotationId_ = GetRotationPropertyId(node);
246 }
247 
GetRotationPropertyId(const std::shared_ptr<RSNode> & node)248 PropertyId RSPathAnimation::GetRotationPropertyId(const std::shared_ptr<RSNode>& node)
249 {
250     std::unique_lock<std::recursive_mutex> lock(node->GetPropertyMutex());
251     auto iter = node->propertyModifiers_.find(RSModifierType::ROTATION);
252     if (iter != node->propertyModifiers_.end()) {
253         return iter->second->GetPropertyId();
254     }
255 
256     for (const auto& [id, modifier] : node->modifiers_) {
257         if (modifier->GetModifierType() == RSModifierType::ROTATION) {
258             return modifier->GetPropertyId();
259         }
260     }
261     return 0;
262 }
263 
SetRotation(const std::shared_ptr<RSNode> & node,const float rotation)264 void RSPathAnimation::SetRotation(const std::shared_ptr<RSNode>& node, const float rotation)
265 {
266     std::unique_lock<std::recursive_mutex> lock(node->GetPropertyMutex());
267     auto iter = node->modifiers_.find(rotationId_);
268     if (iter != node->modifiers_.end()) {
269         auto modifier = iter->second;
270         if (modifier != nullptr) {
271             std::static_pointer_cast<RSProperty<float>>(modifier->GetProperty())->stagingValue_ = rotation;
272         }
273         return;
274     }
275 
276     for (const auto& [type, modifier] : node->propertyModifiers_) {
277         if (modifier != nullptr && modifier->GetPropertyId() == rotationId_) {
278             std::static_pointer_cast<RSProperty<float>>(modifier->GetProperty())->stagingValue_ = rotation;
279         }
280         return;
281     }
282 }
283 
OnCallFinishCallback()284 void RSPathAnimation::OnCallFinishCallback()
285 {
286     if (property_ != nullptr) {
287         property_->RemovePathAnimation();
288     }
289 }
290 
ReplaceSubString(std::string & sourceStr,const std::string & subStr,const std::string & newStr) const291 void RSPathAnimation::ReplaceSubString(std::string& sourceStr, const std::string& subStr,
292     const std::string& newStr) const
293 {
294     std::string::size_type position = 0;
295     while ((position = sourceStr.find(subStr)) != std::string::npos) {
296         sourceStr.replace(position, subStr.length(), newStr);
297     }
298 
299     ROSEN_LOGD("SVG path:%{public}s", sourceStr.c_str());
300 }
301 
ProcessPath(const std::string & path,const float startX,const float startY,const float endX,const float endY) const302 const std::shared_ptr<RSPath> RSPathAnimation::ProcessPath(const std::string& path, const float startX,
303     const float startY, const float endX, const float endY) const
304 {
305     std::string animationPath = path;
306     ReplaceSubString(animationPath, "start.x", std::to_string(startX));
307     ReplaceSubString(animationPath, "start.y", std::to_string(startY));
308     ReplaceSubString(animationPath, "end.x", std::to_string(endX));
309     ReplaceSubString(animationPath, "end.y", std::to_string(endY));
310     return RSPath::CreateRSPath(animationPath);
311 }
312 
PreProcessPath(const std::string & path,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue) const313 const std::shared_ptr<RSPath> RSPathAnimation::PreProcessPath(const std::string& path,
314     const std::shared_ptr<RSPropertyBase>& startValue,
315     const std::shared_ptr<RSPropertyBase>& endValue) const
316 {
317     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
318     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
319     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F && startVector2f != nullptr &&
320         endVector2f != nullptr) {
321         return ProcessPath(path, startVector2f->Get()[0], startVector2f->Get()[1], endVector2f->Get()[0],
322             endVector2f->Get()[1]);
323     }
324 
325     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
326     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
327     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F && startVector4f != nullptr &&
328         endVector4f != nullptr) {
329         return ProcessPath(path, startVector4f->Get()[0], startVector4f->Get()[1], endVector4f->Get()[0],
330             endVector4f->Get()[1]);
331     }
332 
333     return {};
334 }
335 
InitNeedPath(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)336 void RSPathAnimation::InitNeedPath(const std::shared_ptr<RSPropertyBase>& startValue,
337     const std::shared_ptr<RSPropertyBase>& endValue)
338 {
339     if (startValue == nullptr || endValue == nullptr) {
340         ROSEN_LOGD("Input is invaild, failed to InitNeedPath.");
341         return;
342     }
343     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
344     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
345     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F &&
346         startVector4f != nullptr && endVector4f != nullptr) {
347         Vector2f start(startVector4f->Get()[0], startVector4f->Get()[1]);
348         Vector2f end(endVector4f->Get()[0], endVector4f->Get()[1]);
349         isNeedPath_ = (start != end);
350         if (isNeedPath_) {
351             SetAdditive(false);
352         }
353         return;
354     }
355 
356     SetAdditive(false);
357 }
358 
InitInterpolationVector2f(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)359 bool RSPathAnimation::InitInterpolationVector2f(const std::shared_ptr<RSPropertyBase>& startValue,
360     const std::shared_ptr<RSPropertyBase>& endValue)
361 {
362     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
363     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
364     if (startVector2f != nullptr && endVector2f != nullptr) {
365         animationPath_->GetPosTan(0.0f * beginFraction_, startVector2f->stagingValue_, startTangent_);
366         animationPath_->GetPosTan(animationPath_->GetDistance() * endFraction_,
367             endVector2f->stagingValue_, endTangent_);
368         auto originVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(GetOriginValue());
369         if (originVector2f != nullptr && needAddOrigin_) {
370             UpdateVector2fValueAddOrigin(startVector2f->stagingValue_, endVector2f->stagingValue_,
371                 originVector2f->stagingValue_);
372         }
373         byValue_ = endValue - startValue;
374         return true;
375     }
376 
377     return false;
378 }
379 
InitInterpolationVector4f(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)380 bool RSPathAnimation::InitInterpolationVector4f(const std::shared_ptr<RSPropertyBase>& startValue,
381     const std::shared_ptr<RSPropertyBase>& endValue)
382 {
383     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
384     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
385     if (startVector4f != nullptr && endVector4f != nullptr) {
386         animationPath_->GetPosTan(0.0f * beginFraction_, startVector4f->stagingValue_, startTangent_);
387         animationPath_->GetPosTan(animationPath_->GetDistance() * endFraction_,
388             endVector4f->stagingValue_, endTangent_);
389         auto originVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(GetOriginValue());
390         if (originVector4f != nullptr && needAddOrigin_) {
391             UpdateVector4fValueAddOrigin(startVector4f->stagingValue_, endVector4f->stagingValue_,
392                 originVector4f->stagingValue_);
393         }
394         byValue_ = endValue - startValue;
395         return true;
396     }
397 
398     return false;
399 }
400 
UpdateVector2fValueAddOrigin(Vector2f & startValue,Vector2f & endValue,Vector2f & deltaValue)401 void RSPathAnimation::UpdateVector2fValueAddOrigin(Vector2f& startValue, Vector2f& endValue, Vector2f& deltaValue)
402 {
403     startValue += deltaValue;
404     endValue += deltaValue;
405 }
406 
UpdateVector4fValueAddOrigin(Vector4f & startValue,Vector4f & endValue,Vector4f & deltaValue)407 void RSPathAnimation::UpdateVector4fValueAddOrigin(Vector4f& startValue, Vector4f& endValue, Vector4f& deltaValue)
408 {
409     startValue[0] += deltaValue[0];
410     startValue[1] += deltaValue[1];
411     endValue[0] += deltaValue[0];
412     endValue[1] += deltaValue[1];
413 }
414 } // namespace Rosen
415 } // namespace OHOS
416