• 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 {
RSPathAnimation(std::shared_ptr<RSPropertyBase> property,const std::shared_ptr<RSPath> & animationPath)31 RSPathAnimation::RSPathAnimation(std::shared_ptr<RSPropertyBase> property,
32     const std::shared_ptr<RSPath>& animationPath) : RSPropertyAnimation(property), animationPath_(animationPath)
33 {}
34 
RSPathAnimation(std::shared_ptr<RSPropertyBase> property,const std::string & path,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)35 RSPathAnimation::RSPathAnimation(std::shared_ptr<RSPropertyBase> property, const std::string& path,
36     const std::shared_ptr<RSPropertyBase>& startValue, const std::shared_ptr<RSPropertyBase>& endValue)
37     : RSPathAnimation(property, PreProcessPath(path, startValue, endValue))
38 {
39     startValue_ = startValue;
40     endValue_ = endValue;
41     InitNeedPath(startValue_, endValue_);
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 (RSAnimation::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 
SetPathNeedAddOrigin(bool needAddOrigin)109 void RSPathAnimation::SetPathNeedAddOrigin(bool needAddOrigin)
110 {
111     if (IsStarted()) {
112         ROSEN_LOGE("Failed to set need Add Origin, path animation has started!");
113         return;
114     }
115 
116     needAddOrigin_ = needAddOrigin;
117 }
118 
GetPathNeedAddOrigin() const119 bool RSPathAnimation::GetPathNeedAddOrigin() const
120 {
121     return needAddOrigin_;
122 }
123 
OnStart()124 void RSPathAnimation::OnStart()
125 {
126     if (!animationPath_) {
127         ROSEN_LOGE("Failed to start path animation, path is null!");
128         return;
129     }
130 
131     RSPropertyAnimation::OnStart();
132     auto target = GetTarget().lock();
133     if (target == nullptr) {
134         ROSEN_LOGE("Failed to start curve animation, target is null!");
135         return;
136     }
137 
138     InitRotationId(target);
139     auto interpolator = timingCurve_.GetInterpolator(GetDuration());
140     auto animation = std::make_shared<RSRenderPathAnimation>(GetId(), GetPropertyId(),
141         originValue_->CreateRenderProperty(), startValue_->CreateRenderProperty(), endValue_->CreateRenderProperty(),
142         target->GetStagingProperties().GetRotation(), animationPath_);
143     UpdateParamToRenderAnimation(animation);
144     animation->SetInterpolator(interpolator);
145     animation->SetRotationMode(GetRotationMode());
146     animation->SetBeginFraction(GetBeginFraction());
147     animation->SetEndFraction(GetEndFraction());
148     animation->SetIsNeedPath(isNeedPath_);
149     animation->SetPathNeedAddOrigin(GetPathNeedAddOrigin());
150     animation->SetAdditive(GetAdditive());
151     animation->SetRotationId(rotationId_);
152     if (isNeedPath_) {
153         property_->AddPathAnimation();
154     }
155     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
156     auto transactionProxy = RSTransactionProxy::GetInstance();
157     if (transactionProxy != nullptr) {
158         transactionProxy->AddCommand(command, target->IsRenderServiceNode(),
159             target->GetFollowType(), target->GetId());
160         if (target->NeedForcedSendToRemote()) {
161             std::unique_ptr<RSCommand> commandForRemote =
162                 std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
163             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
164         }
165         if (target->NeedSendExtraCommand()) {
166             std::unique_ptr<RSCommand> extraCommand =
167                 std::make_unique<RSAnimationCreatePath>(target->GetId(), animation);
168             transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
169                 target->GetId());
170         }
171     }
172 }
173 
InitInterpolationValue()174 void RSPathAnimation::InitInterpolationValue()
175 {
176     if (!animationPath_) {
177         ROSEN_LOGE("Failed to update interpolation value, path is null!");
178         return;
179     }
180 
181     if (isNeedPath_) {
182         if (startValue_->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F &&
183             InitInterpolationVector2f(startValue_, endValue_)) {
184             return;
185         }
186         if (startValue_->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F &&
187             InitInterpolationVector4f(startValue_, endValue_)) {
188             return;
189         }
190     }
191 
192     byValue_ = endValue_ - startValue_;
193 }
194 
OnUpdateStagingValue(bool isFirstStart)195 void RSPathAnimation::OnUpdateStagingValue(bool isFirstStart)
196 {
197     auto target = GetTarget().lock();
198     if (target == nullptr) {
199         ROSEN_LOGE("Failed to update staging value, target is null!");
200         return;
201     }
202 
203     RSPropertyAnimation::OnUpdateStagingValue(isFirstStart);
204 
205     float startTangent = 0.0f;
206     float endTangent = 0.0f;
207     switch (rotationMode_) {
208         case RotationMode::ROTATE_NONE:
209             return;
210         case RotationMode::ROTATE_AUTO:
211             startTangent = startTangent_;
212             endTangent = endTangent_;
213             break;
214         case RotationMode::ROTATE_AUTO_REVERSE:
215             startTangent = startTangent_ + 180.0f;
216             endTangent = endTangent_ + 180.0f;
217             break;
218         default:
219             ROSEN_LOGE("Unknow rotation mode!");
220             return;
221     }
222     if (!GetDirection()) {
223         std::swap(startTangent, endTangent);
224     }
225 
226     float targetRotation = 0.0f;
227     float byRotation = endTangent - startTangent;
228     if (isFirstStart) {
229         if (GetAutoReverse() && GetRepeatCount() % 2 == 0) {
230             targetRotation = startTangent;
231         } else {
232             targetRotation = endTangent;
233         }
234     } else {
235         float currentRotation = target->GetStagingProperties().GetRotation();
236         if (GetAutoReverse() && GetRepeatCount() % 2 == 0) {
237             targetRotation = IsReversed() ? currentRotation + byRotation
238                 : currentRotation - byRotation;
239         } else {
240             targetRotation = IsReversed() ? currentRotation - byRotation
241                 : currentRotation + byRotation;
242         }
243     }
244 
245     SetRotation(target, targetRotation);
246 }
247 
InitRotationId(const std::shared_ptr<RSNode> & node)248 void RSPathAnimation::InitRotationId(const std::shared_ptr<RSNode>& node)
249 {
250     if (GetRotationPropertyId(node) == 0) {
251         node->SetRotation(0.f);
252     }
253     rotationId_ = GetRotationPropertyId(node);
254 }
255 
GetRotationPropertyId(const std::shared_ptr<RSNode> & node)256 PropertyId RSPathAnimation::GetRotationPropertyId(const std::shared_ptr<RSNode>& node)
257 {
258     auto iter = node->propertyModifiers_.find(RSModifierType::ROTATION);
259     if (iter != node->propertyModifiers_.end()) {
260         return iter->second->GetPropertyId();
261     }
262 
263     for (const auto& [id, modifier] : node->modifiers_) {
264         if (modifier->GetModifierType() == RSModifierType::ROTATION) {
265             return modifier->GetPropertyId();
266         }
267     }
268     return 0;
269 }
270 
SetRotation(const std::shared_ptr<RSNode> & node,const float rotation)271 void RSPathAnimation::SetRotation(const std::shared_ptr<RSNode>& node, const float rotation)
272 {
273     auto iter = node->modifiers_.find(rotationId_);
274     if (iter != node->modifiers_.end()) {
275         auto modifier = iter->second;
276         if (modifier != nullptr) {
277             std::static_pointer_cast<RSProperty<float>>(modifier->GetProperty())->stagingValue_ = rotation;
278         }
279         return;
280     }
281 
282     for (const auto& [type, modifier] : node->propertyModifiers_) {
283         if (modifier != nullptr && modifier->GetPropertyId() == rotationId_) {
284             std::static_pointer_cast<RSProperty<float>>(modifier->GetProperty())->stagingValue_ = rotation;
285         }
286         return;
287     }
288 }
289 
OnCallFinishCallback()290 void RSPathAnimation::OnCallFinishCallback()
291 {
292     if (property_ != nullptr) {
293         property_->RemovePathAnimation();
294     }
295 }
296 
ReplaceSubString(std::string & sourceStr,const std::string & subStr,const std::string & newStr) const297 void RSPathAnimation::ReplaceSubString(std::string& sourceStr, const std::string& subStr,
298     const std::string& newStr) const
299 {
300     std::string::size_type position = 0;
301     while ((position = sourceStr.find(subStr)) != std::string::npos) {
302         sourceStr.replace(position, subStr.length(), newStr);
303     }
304 
305     ROSEN_LOGD("SVG path:%s", sourceStr.c_str());
306 }
307 
ProcessPath(const std::string & path,const float startX,const float startY,const float endX,const float endY) const308 const std::shared_ptr<RSPath> RSPathAnimation::ProcessPath(const std::string& path, const float startX,
309     const float startY, const float endX, const float endY) const
310 {
311     std::string animationPath = path;
312     ReplaceSubString(animationPath, "start.x", std::to_string(startX));
313     ReplaceSubString(animationPath, "start.y", std::to_string(startY));
314     ReplaceSubString(animationPath, "end.x", std::to_string(endX));
315     ReplaceSubString(animationPath, "end.y", std::to_string(endY));
316     return RSPath::CreateRSPath(animationPath);
317 }
318 
PreProcessPath(const std::string & path,const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue) const319 const std::shared_ptr<RSPath> RSPathAnimation::PreProcessPath(const std::string& path,
320     const std::shared_ptr<RSPropertyBase>& startValue,
321     const std::shared_ptr<RSPropertyBase>& endValue) const
322 {
323     auto startVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(startValue);
324     auto endVector2f = std::static_pointer_cast<RSProperty<Vector2f>>(endValue);
325     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR2F && startVector2f != nullptr &&
326         endVector2f != nullptr) {
327         return ProcessPath(path, startVector2f->Get()[0], startVector2f->Get()[1], endVector2f->Get()[0],
328             endVector2f->Get()[1]);
329     }
330 
331     auto startVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(startValue);
332     auto endVector4f = std::static_pointer_cast<RSProperty<Vector4f>>(endValue);
333     if (startValue->GetPropertyType() == RSRenderPropertyType::PROPERTY_VECTOR4F && startVector4f != nullptr &&
334         endVector4f != nullptr) {
335         return ProcessPath(path, startVector4f->Get()[0], startVector4f->Get()[1], endVector4f->Get()[0],
336             endVector4f->Get()[1]);
337     }
338 
339     return {};
340 }
341 
InitNeedPath(const std::shared_ptr<RSPropertyBase> & startValue,const std::shared_ptr<RSPropertyBase> & endValue)342 void RSPathAnimation::InitNeedPath(const std::shared_ptr<RSPropertyBase>& startValue,
343     const std::shared_ptr<RSPropertyBase>& endValue)
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() == RSRenderPropertyType::PROPERTY_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