• 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_property.h"
23 #include "modifier_ng/rs_modifier_ng.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() == RSPropertyType::VECTOR2F &&
175             InitInterpolationVector2f(startValue_, endValue_)) {
176             return;
177         }
178         if (startValue_->GetPropertyType() == RSPropertyType::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     if (!node) {
251         return 0;
252     }
253     std::unique_lock<std::recursive_mutex> lock(node->GetPropertyMutex());
254     auto& modifier = node->modifiersNGCreatedBySetter_[static_cast<uint16_t>(ModifierNG::RSModifierType::TRANSFORM)];
255     if (modifier) {
256         if (const auto& property = modifier->GetProperty(ModifierNG::RSPropertyType::ROTATION)) {
257             return property->GetId();
258         }
259     }
260     for (const auto& [id, property] : node->properties_) {
261         if (property->GetPropertyTypeNG() == ModifierNG::RSPropertyType::ROTATION) {
262             return id;
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& property = node->GetPropertyById(rotationId_);
272     if (property) {
273         std::static_pointer_cast<RSProperty<float>>(property)->stagingValue_ = rotation;
274         return;
275     }
276     auto& modifier = node->modifiersNGCreatedBySetter_[static_cast<uint16_t>(ModifierNG::RSModifierType::TRANSFORM)];
277     if (modifier) {
278         return;
279     }
280     auto propertyRotation = modifier->GetProperty(ModifierNG::RSPropertyType::ROTATION);
281     if (propertyRotation && propertyRotation->GetId() == rotationId_) {
282         std::static_pointer_cast<RSProperty<float>>(property)->stagingValue_ = rotation;
283     }
284 }
285 
OnCallFinishCallback()286 void RSPathAnimation::OnCallFinishCallback()
287 {
288     if (property_ != nullptr) {
289         property_->RemovePathAnimation();
290     }
291 }
292 
ReplaceSubString(std::string & sourceStr,const std::string & subStr,const std::string & newStr) const293 void RSPathAnimation::ReplaceSubString(std::string& sourceStr, const std::string& subStr,
294     const std::string& newStr) const
295 {
296     std::string::size_type position = 0;
297     while ((position = sourceStr.find(subStr)) != std::string::npos) {
298         sourceStr.replace(position, subStr.length(), newStr);
299     }
300 
301     ROSEN_LOGD("SVG path:%{public}s", sourceStr.c_str());
302 }
303 
ProcessPath(const std::string & path,const float startX,const float startY,const float endX,const float endY) const304 const std::shared_ptr<RSPath> RSPathAnimation::ProcessPath(const std::string& path, const float startX,
305     const float startY, const float endX, const float endY) const
306 {
307     std::string animationPath = path;
308     ReplaceSubString(animationPath, "start.x", std::to_string(startX));
309     ReplaceSubString(animationPath, "start.y", std::to_string(startY));
310     ReplaceSubString(animationPath, "end.x", std::to_string(endX));
311     ReplaceSubString(animationPath, "end.y", std::to_string(endY));
312     return RSPath::CreateRSPath(animationPath);
313 }
314 
PreProcessPath(const std::string & path,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue) const315 const std::shared_ptr<RSPath> RSPathAnimation::PreProcessPath(const std::string& path,
316     const std::shared_ptr<RSPropertyBase>& startValue,
317     const std::shared_ptr<RSPropertyBase>& endValue) const
318 {
319     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
320     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
321     if (startValue->GetPropertyType() == RSPropertyType::VECTOR2F && startVector2f != nullptr &&
322         endVector2f != nullptr) {
323         return ProcessPath(path, startVector2f->Get()[0], startVector2f->Get()[1], endVector2f->Get()[0],
324             endVector2f->Get()[1]);
325     }
326 
327     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
328     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
329     if (startValue->GetPropertyType() == RSPropertyType::VECTOR4F && startVector4f != nullptr &&
330         endVector4f != nullptr) {
331         return ProcessPath(path, startVector4f->Get()[0], startVector4f->Get()[1], endVector4f->Get()[0],
332             endVector4f->Get()[1]);
333     }
334 
335     return {};
336 }
337 
InitNeedPath(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)338 void RSPathAnimation::InitNeedPath(const std::shared_ptr<RSPropertyBase>& startValue,
339     const std::shared_ptr<RSPropertyBase>& endValue)
340 {
341     if (startValue == nullptr || endValue == nullptr) {
342         ROSEN_LOGD("Input is invaild, failed to InitNeedPath.");
343         return;
344     }
345     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
346     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
347     if (startValue->GetPropertyType() == RSPropertyType::VECTOR4F &&
348         startVector4f != nullptr && endVector4f != nullptr) {
349         Vector2f start(startVector4f->Get()[0], startVector4f->Get()[1]);
350         Vector2f end(endVector4f->Get()[0], endVector4f->Get()[1]);
351         isNeedPath_ = (start != end);
352         if (isNeedPath_) {
353             SetAdditive(false);
354         }
355         return;
356     }
357 
358     SetAdditive(false);
359 }
360 
InitInterpolationVector2f(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)361 bool RSPathAnimation::InitInterpolationVector2f(const std::shared_ptr<RSPropertyBase>& startValue,
362     const std::shared_ptr<RSPropertyBase>& endValue)
363 {
364     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
365     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
366     if (startVector2f != nullptr && endVector2f != nullptr) {
367         animationPath_->GetPosTan(0.0f * beginFraction_, startVector2f->stagingValue_, startTangent_);
368         animationPath_->GetPosTan(animationPath_->GetDistance() * endFraction_,
369             endVector2f->stagingValue_, endTangent_);
370         auto originVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(GetOriginValue());
371         if (originVector2f != nullptr && needAddOrigin_) {
372             UpdateVector2fValueAddOrigin(startVector2f->stagingValue_, endVector2f->stagingValue_,
373                 originVector2f->stagingValue_);
374         }
375         byValue_ = endValue - startValue;
376         return true;
377     }
378 
379     return false;
380 }
381 
InitInterpolationVector4f(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)382 bool RSPathAnimation::InitInterpolationVector4f(const std::shared_ptr<RSPropertyBase>& startValue,
383     const std::shared_ptr<RSPropertyBase>& endValue)
384 {
385     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
386     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
387     if (startVector4f != nullptr && endVector4f != nullptr) {
388         animationPath_->GetPosTan(0.0f * beginFraction_, startVector4f->stagingValue_, startTangent_);
389         animationPath_->GetPosTan(animationPath_->GetDistance() * endFraction_,
390             endVector4f->stagingValue_, endTangent_);
391         auto originVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(GetOriginValue());
392         if (originVector4f != nullptr && needAddOrigin_) {
393             UpdateVector4fValueAddOrigin(startVector4f->stagingValue_, endVector4f->stagingValue_,
394                 originVector4f->stagingValue_);
395         }
396         byValue_ = endValue - startValue;
397         return true;
398     }
399 
400     return false;
401 }
402 
UpdateVector2fValueAddOrigin(Vector2f & startValue,Vector2f & endValue,Vector2f & deltaValue)403 void RSPathAnimation::UpdateVector2fValueAddOrigin(Vector2f& startValue, Vector2f& endValue, Vector2f& deltaValue)
404 {
405     startValue += deltaValue;
406     endValue += deltaValue;
407 }
408 
UpdateVector4fValueAddOrigin(Vector4f & startValue,Vector4f & endValue,Vector4f & deltaValue)409 void RSPathAnimation::UpdateVector4fValueAddOrigin(Vector4f& startValue, Vector4f& endValue, Vector4f& deltaValue)
410 {
411     startValue[0] += deltaValue[0];
412     startValue[1] += deltaValue[1];
413     endValue[0] += deltaValue[0];
414     endValue[1] += deltaValue[1];
415 }
416 } // namespace Rosen
417 } // namespace OHOS
418