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