• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_interpolator.h"
17 
18 #include <algorithm>
19 #include <cmath>
20 
21 #include "animation/rs_animation_common.h"
22 #include "animation/rs_cubic_bezier_interpolator.h"
23 #include "animation/rs_spring_interpolator.h"
24 #include "animation/rs_steps_interpolator.h"
25 
26 namespace OHOS {
27 namespace Rosen {
28 const std::shared_ptr<RSInterpolator> RSInterpolator::DEFAULT =
29     std::make_shared<RSCubicBezierInterpolator>(0.42f, 0.0f, 0.58f, 1.0f);
30 
Unmarshalling(Parcel & parcel)31 RSInterpolator* RSInterpolator::Unmarshalling(Parcel& parcel)
32 {
33     uint16_t interpolatorType = parcel.ReadUint16();
34     RSInterpolator* ret = nullptr;
35     switch (interpolatorType) {
36         case InterpolatorType::LINEAR:
37             ret = new LinearInterpolator();
38             break;
39         case InterpolatorType::CUSTOM:
40             ret = RSCustomInterpolator::Unmarshalling(parcel);
41             break;
42         case InterpolatorType::CUBIC_BEZIER:
43             ret = RSCubicBezierInterpolator::Unmarshalling(parcel);
44             break;
45         case InterpolatorType::SPRING:
46             ret = RSSpringInterpolator::Unmarshalling(parcel);
47             break;
48         case InterpolatorType::STEPS:
49             ret = RSStepsInterpolator::Unmarshalling(parcel);
50             break;
51         default:
52             break;
53     }
54     return ret;
55 }
56 
Unmarshalling(Parcel & parcel)57 RSCustomInterpolator* RSCustomInterpolator::Unmarshalling(Parcel& parcel)
58 {
59     std::vector<float> times, values;
60     if (!(parcel.ReadFloatVector(&times) && parcel.ReadFloatVector(&values))) {
61         ROSEN_LOGE("Unmarshalling CustomInterpolator failed");
62         return nullptr;
63     }
64     return new RSCustomInterpolator(std::move(times), std::move(values));
65 }
66 
RSCustomInterpolator(const std::vector<float> && times,const std::vector<float> && values)67 RSCustomInterpolator::RSCustomInterpolator(const std::vector<float>&& times, const std::vector<float>&& values)
68     : times_(times), values_(values)
69 {}
70 
RSCustomInterpolator(const std::function<float (float)> & func,int duration)71 RSCustomInterpolator::RSCustomInterpolator(const std::function<float(float)>& func, int duration)
72     : interpolateFunc_(func)
73 {
74     Convert(duration);
75 }
76 
Convert(int duration)77 void RSCustomInterpolator::Convert(int duration)
78 {
79     if (interpolateFunc_ == nullptr) {
80         ROSEN_LOGE("RSCustomInterpolator::Convert, interpolateFunc_ is nullptr");
81         return;
82     }
83     uint64_t frameInterval = 16666667;
84     int numAnim = static_cast<int>(std::ceil(static_cast<double>(duration * MS_TO_NS) / frameInterval));
85     const int maxSamplePoints = 300;
86     const int minSamplePoints = 2;
87     numAnim = std::min(std::max(minSamplePoints, numAnim), maxSamplePoints);
88     float lastAnimFrame = numAnim - 1;
89     for (int i = 0; i < numAnim; i++) {
90         float time = i / lastAnimFrame;
91         float value = interpolateFunc_(time);
92         times_.push_back(time);
93         values_.push_back(value);
94     }
95 }
96 
Interpolate(float input) const97 float RSCustomInterpolator::Interpolate(float input) const
98 {
99     if (input < times_[0] + EPSILON) {
100         return times_[0];
101     }
102     if (input > times_[times_.size() - 1] - EPSILON) {
103         return times_[times_.size() - 1];
104     }
105     auto firstGreatValue = upper_bound(times_.begin(), times_.end(), input);
106     int endLocation = firstGreatValue - times_.begin();
107     int startLocation = endLocation - 1;
108 
109     float fraction = (input - times_[startLocation]) / (times_[endLocation] - times_[startLocation]);
110     float ret = fraction * (values_[endLocation] - values_[startLocation]) + values_[startLocation];
111     return ret;
112 }
113 } // namespace Rosen
114 } // namespace OHOS
115