• 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     std::unique_ptr<RSCommand> command = std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
115     target->AddCommand(command, target->IsRenderServiceNode(), target->GetFollowType(), target->GetId());
116     if (target->NeedForcedSendToRemote()) {
117         std::unique_ptr<RSCommand> commandForRemote =
118             std::make_unique<RSAnimationCreateKeyframe>(target->GetId(), animation);
119         target->AddCommand(commandForRemote, true, target->GetFollowType(), target->GetId());
120     }
121 }
122 
StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation> & animation)123 void RSKeyframeAnimation::StartUIAnimation(const std::shared_ptr<RSRenderKeyframeAnimation>& animation)
124 {
125     StartCustomAnimation(animation);
126 }
127 
OnStart()128 void RSKeyframeAnimation::OnStart()
129 {
130     RSPropertyAnimation::OnStart();
131     if (keyframes_.empty() && durationKeyframes_.empty()) {
132         ROSEN_LOGE("Failed to start keyframe animation, keyframes is null!");
133         return;
134     }
135     auto animation = std::make_shared<RSRenderKeyframeAnimation>(GetId(), GetPropertyId(),
136         originValue_->GetRenderProperty());
137     animation->SetDurationKeyframe(isDurationKeyframe_);
138     animation->SetAdditive(GetAdditive());
139     UpdateParamToRenderAnimation(animation);
140     if (isDurationKeyframe_) {
141         for (const auto& [startDuration, endDuration, value, curve] : durationKeyframes_) {
142             animation->AddKeyframe(startDuration, endDuration, value->GetRenderProperty(),
143                 curve.GetInterpolator(GetDuration()));
144         }
145     } else {
146         for (const auto& [fraction, value, curve] : keyframes_) {
147             animation->AddKeyframe(fraction, value->GetRenderProperty(), curve.GetInterpolator(GetDuration()));
148         }
149     }
150     if (isCustom_) {
151         SetPropertyValue(originValue_);
152         property_->UpdateCustomAnimation();
153         animation->AttachRenderProperty(property_->GetRenderProperty());
154         StartUIAnimation(animation);
155     } else {
156         StartRenderAnimation(animation);
157     }
158 }
159 } // namespace Rosen
160 } // namespace OHOS
161