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 if (target->NeedSendExtraCommand()) {
87 std::unique_ptr<RSCommand> extraCommand =
88 std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
89 transactionProxy->AddCommand(extraCommand, !target->IsRenderServiceNode(), target->GetFollowType(),
90 target->GetId());
91 }
92 }
93 }
94
StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation> & animation)95 void RSKeyframeAnimation::StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation>& animation)
96 {
97 StartCustomPropertyAnimation(animation);
98 }
99
OnStart()100 void RSKeyframeAnimation::OnStart()
101 {
102 RSPropertyAnimation::OnStart();
103 if (keyframes_.empty()) {
104 ROSEN_LOGE("Failed to start keyframe animation, keyframes is null!");
105 return;
106 }
107 auto animation = std::make_shared<RSRenderKeyframeAnimation>(GetId(), GetPropertyId(),
108 originValue_->CreateRenderProperty());
109 for (const auto& [fraction, value, curve] : keyframes_) {
110 animation->AddKeyframe(fraction, value->CreateRenderProperty(), curve.GetInterpolator(GetDuration()));
111 }
112 animation->SetAdditive(GetAdditive());
113 UpdateParamToRenderAnimation(animation);
114 if (isCustom_) {
115 StartUIAnimation(animation);
116 } else {
117 StartRenderAnimation(animation);
118 }
119 }
120 } // namespace Rosen
121 } // namespace OHOS
122