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_keyframe_animation.h"
17
18 #include "animation/rs_render_keyframe_animation.h"
19 #include "command/rs_animation_command.h"
20 #include "modifier/rs_property.h"
21 #include "transaction/rs_transaction_proxy.h"
22 #include "ui/rs_node.h"
23
24 namespace OHOS {
25 namespace Rosen {
RSKeyframeAnimation(std::shared_ptr<RSPropertyBase> property)26 RSKeyframeAnimation::RSKeyframeAnimation(std::shared_ptr<RSPropertyBase> property) : RSPropertyAnimation(property)
27 {}
28
AddKeyFrame(float fraction,const std::shared_ptr<RSPropertyBase> & value,const RSAnimationTimingCurve & timingCurve)29 void RSKeyframeAnimation::AddKeyFrame(float fraction, const std::shared_ptr<RSPropertyBase>& value,
30 const RSAnimationTimingCurve& timingCurve)
31 {
32 if (fraction < FRACTION_MIN || fraction > FRACTION_MAX) {
33 return;
34 }
35
36 if (IsStarted()) {
37 return;
38 }
39
40 keyframes_.push_back({ fraction, value, timingCurve });
41 }
42
AddKeyFrames(const std::vector<std::tuple<float,std::shared_ptr<RSPropertyBase>,RSAnimationTimingCurve>> & keyframes)43 void RSKeyframeAnimation::AddKeyFrames(
44 const std::vector<std::tuple<float, std::shared_ptr<RSPropertyBase>, RSAnimationTimingCurve>>& keyframes)
45 {
46 if (IsStarted()) {
47 return;
48 }
49
50 keyframes_ = keyframes;
51 }
52
InitInterpolationValue()53 void RSKeyframeAnimation::InitInterpolationValue()
54 {
55 if (keyframes_.empty()) {
56 return;
57 }
58
59 auto beginKeyframe = keyframes_.front();
60 if (std::abs(std::get<FRACTION_INDEX>(beginKeyframe) - FRACTION_MIN) > EPSILON) {
61 keyframes_.insert(keyframes_.begin(), { FRACTION_MIN, GetOriginValue(), RSAnimationTimingCurve::LINEAR });
62 }
63
64 startValue_ = std::get<VALUE_INDEX>(keyframes_.front());
65 endValue_ = std::get<VALUE_INDEX>(keyframes_.back());
66 RSPropertyAnimation::InitInterpolationValue();
67 }
68
StartRenderAnimation(const std::shared_ptr<RSRenderKeyframeAnimation> & animation)69 void RSKeyframeAnimation::StartRenderAnimation(const std::shared_ptr<RSRenderKeyframeAnimation>& animation)
70 {
71 auto target = GetTarget().lock();
72 if (target == nullptr) {
73 ROSEN_LOGE("Failed to start keyframe animation, target is null!");
74 return;
75 }
76
77 std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
78 auto transactionProxy = RSTransactionProxy::GetInstance();
79 if (transactionProxy != nullptr) {
80 transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
81 if (target->NeedForcedSendToRemote()) {
82 std::unique_ptr<RSCommand> commandForRemote =
83 std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
84 transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
85 }
86 }
87 }
88
StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation> & animation)89 void RSKeyframeAnimation::StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation>& animation)
90 {
91 StartCustomAnimation(animation);
92 }
93
OnStart()94 void RSKeyframeAnimation::OnStart()
95 {
96 RSPropertyAnimation::OnStart();
97 if (keyframes_.empty()) {
98 ROSEN_LOGE("Failed to start keyframe animation, keyframes is null!");
99 return;
100 }
101 auto animation = std::make_shared<RSRenderKeyframeAnimation>(GetId(), GetPropertyId(),
102 originValue_->GetRenderProperty());
103 for (const auto& [fraction, value, curve] : keyframes_) {
104 animation->AddKeyframe(fraction, value->GetRenderProperty(), curve.GetInterpolator(GetDuration()));
105 }
106 animation->SetAdditive(GetAdditive());
107 UpdateParamToRenderAnimation(animation);
108 if (isCustom_) {
109 animation->AttachRenderProperty(property_->GetRenderProperty());
110 StartUIAnimation(animation);
111 } else {
112 StartRenderAnimation(animation);
113 }
114 }
115 } // namespace Rosen
116 } // namespace OHOS
117