• 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_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 #include "platform/common/rs_log.h"
24 
25 static constexpr int DURATION_MIN = 0;
26 static constexpr int DURATION_VALUE_INDEX = 2;
27 
28 namespace OHOS {
29 namespace Rosen {
RSKeyframeAnimation(std::shared_ptr<RSPropertyBase> property)30 RSKeyframeAnimation::RSKeyframeAnimation(std::shared_ptr<RSPropertyBase> property) : RSPropertyAnimation(property)
31 {}
32 
AddKeyFrame(float fraction,const std::shared_ptr<RSPropertyBase> & value,const RSAnimationTimingCurve & timingCurve)33 void RSKeyframeAnimation::AddKeyFrame(float fraction, const std::shared_ptr<RSPropertyBase>& value,
34     const RSAnimationTimingCurve& timingCurve)
35 {
36     if (fraction < FRACTION_MIN || fraction > FRACTION_MAX) {
37         return;
38     }
39 
40     if (IsStarted()) {
41         return;
42     }
43 
44     keyframes_.push_back({ fraction, value, timingCurve });
45 }
46 
AddKeyFrames(const std::vector<std::tuple<float,std::shared_ptr<RSPropertyBase>,RSAnimationTimingCurve>> & keyframes)47 void RSKeyframeAnimation::AddKeyFrames(
48     const std::vector<std::tuple<float, std::shared_ptr<RSPropertyBase>, RSAnimationTimingCurve>>& keyframes)
49 {
50     if (IsStarted()) {
51         return;
52     }
53 
54     keyframes_ = keyframes;
55 }
56 
AddKeyFrame(int startDuration,int endDuration,const std::shared_ptr<RSPropertyBase> & value,const RSAnimationTimingCurve & timingCurve)57 void RSKeyframeAnimation::AddKeyFrame(int startDuration, int endDuration,
58     const std::shared_ptr<RSPropertyBase>& value, const RSAnimationTimingCurve& timingCurve)
59 {
60     if (startDuration > endDuration) {
61         return;
62     }
63 
64     if (IsStarted()) {
65         return;
66     }
67 
68     durationKeyframes_.push_back({ startDuration, endDuration, value, timingCurve });
69 }
70 
SetDurationKeyframe(bool isDuration)71 void RSKeyframeAnimation::SetDurationKeyframe(bool isDuration)
72 {
73     isDurationKeyframe_ = isDuration;
74 }
75 
InitInterpolationValue()76 void RSKeyframeAnimation::InitInterpolationValue()
77 {
78     if (isDurationKeyframe_) {
79         if (durationKeyframes_.empty()) {
80             return;
81         }
82 
83         auto beginKeyframe = durationKeyframes_.front();
84         durationKeyframes_.insert(durationKeyframes_.begin(),
85             { DURATION_MIN, DURATION_MIN, GetOriginValue(), RSAnimationTimingCurve::LINEAR });
86 
87         startValue_ = std::get<DURATION_VALUE_INDEX>(durationKeyframes_.front());
88         endValue_ = std::get<DURATION_VALUE_INDEX>(durationKeyframes_.back());
89         RSPropertyAnimation::InitInterpolationValue();
90         return;
91     }
92 
93     if (keyframes_.empty()) {
94         return;
95     }
96 
97     auto beginKeyframe = keyframes_.front();
98     if (std::abs(std::get<FRACTION_INDEX>(beginKeyframe) - FRACTION_MIN) > EPSILON) {
99         keyframes_.insert(keyframes_.begin(), { FRACTION_MIN, GetOriginValue(), RSAnimationTimingCurve::LINEAR });
100     }
101 
102     startValue_ = std::get<VALUE_INDEX>(keyframes_.front());
103     endValue_ = std::get<VALUE_INDEX>(keyframes_.back());
104     RSPropertyAnimation::InitInterpolationValue();
105 }
106 
StartRenderAnimation(const std::shared_ptr<RSRenderKeyframeAnimation> & animation)107 void RSKeyframeAnimation::StartRenderAnimation(const std::shared_ptr<RSRenderKeyframeAnimation>& animation)
108 {
109     auto target = GetTarget().lock();
110     if (target == nullptr) {
111         ROSEN_LOGE("Failed to start keyframe animation, target is null!");
112         return;
113     }
114 
115     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
116     auto transactionProxy = RSTransactionProxy::GetInstance();
117     if (transactionProxy != nullptr) {
118         transactionProxy->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
119         if (target->NeedForcedSendToRemote()) {
120             std::unique_ptr<RSCommand> commandForRemote =
121                 std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
122             transactionProxy->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
123         }
124     }
125 }
126 
StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation> & animation)127 void RSKeyframeAnimation::StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation>& animation)
128 {
129     StartCustomAnimation(animation);
130 }
131 
OnStart()132 void RSKeyframeAnimation::OnStart()
133 {
134     RSPropertyAnimation::OnStart();
135     if (keyframes_.empty() && durationKeyframes_.empty()) {
136         ROSEN_LOGE("Failed to start keyframe animation, keyframes is null!");
137         return;
138     }
139     auto animation = std::make_shared<RSRenderKeyframeAnimation>(GetId(), GetPropertyId(),
140         originValue_->GetRenderProperty());
141     animation->SetDurationKeyframe(isDurationKeyframe_);
142     animation->SetAdditive(GetAdditive());
143     UpdateParamToRenderAnimation(animation);
144     if (isDurationKeyframe_) {
145         for (const auto& [startDuration, endDuration, value, curve] : durationKeyframes_) {
146             animation->AddKeyframe(startDuration, endDuration, value->GetRenderProperty(),
147                 curve.GetInterpolator(GetDuration()));
148         }
149     } else {
150         for (const auto& [fraction, value, curve] : keyframes_) {
151             animation->AddKeyframe(fraction, value->GetRenderProperty(), curve.GetInterpolator(GetDuration()));
152         }
153     }
154     if (isCustom_) {
155         animation->AttachRenderProperty(property_->GetRenderProperty());
156         StartUIAnimation(animation);
157     } else {
158         StartRenderAnimation(animation);
159     }
160 }
161 } // namespace Rosen
162 } // namespace OHOS
163