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