1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/animation/keyframed_animation_curve.h"
6
7 #include "cc/animation/transform_operations.h"
8 #include "cc/test/geometry_test_utils.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/gfx/animation/tween.h"
12 #include "ui/gfx/geometry/box_f.h"
13 #include "ui/gfx/test/gfx_util.h"
14
15 namespace cc {
16 namespace {
17
ExpectTranslateX(SkScalar translate_x,const TransformOperations & operations)18 void ExpectTranslateX(SkScalar translate_x,
19 const TransformOperations& operations) {
20 EXPECT_FLOAT_EQ(translate_x, operations.Apply().matrix().get(0, 3));
21 }
22
ExpectBrightness(double brightness,const FilterOperations & filter)23 void ExpectBrightness(double brightness, const FilterOperations& filter) {
24 EXPECT_EQ(1u, filter.size());
25 EXPECT_EQ(FilterOperation::BRIGHTNESS, filter.at(0).type());
26 EXPECT_FLOAT_EQ(brightness, filter.at(0).amount());
27 }
28
29 // Tests that a color animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneColorKeyFrame)30 TEST(KeyframedAnimationCurveTest, OneColorKeyFrame) {
31 SkColor color = SkColorSetARGB(255, 255, 255, 255);
32 std::unique_ptr<KeyframedColorAnimationCurve> curve(
33 KeyframedColorAnimationCurve::Create());
34 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta(), color, nullptr));
35
36 EXPECT_SKCOLOR_EQ(color,
37 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
38 EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
39 EXPECT_SKCOLOR_EQ(color,
40 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
41 EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
42 EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
43 }
44
45 // Tests that a color animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoColorKeyFrame)46 TEST(KeyframedAnimationCurveTest, TwoColorKeyFrame) {
47 SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
48 SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
49 SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
50 std::unique_ptr<KeyframedColorAnimationCurve> curve(
51 KeyframedColorAnimationCurve::Create());
52 curve->AddKeyframe(
53 ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
54 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
55 color_b, nullptr));
56
57 EXPECT_SKCOLOR_EQ(color_a,
58 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
59 EXPECT_SKCOLOR_EQ(color_a,
60 curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
61 EXPECT_SKCOLOR_EQ(color_midpoint,
62 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
63 EXPECT_SKCOLOR_EQ(color_b,
64 curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
65 EXPECT_SKCOLOR_EQ(color_b,
66 curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
67 }
68
69 // Tests that a color animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeColorKeyFrame)70 TEST(KeyframedAnimationCurveTest, ThreeColorKeyFrame) {
71 SkColor color_a = SkColorSetARGB(255, 255, 0, 0);
72 SkColor color_b = SkColorSetARGB(255, 0, 255, 0);
73 SkColor color_c = SkColorSetARGB(255, 0, 0, 255);
74 SkColor color_midpoint1 =
75 gfx::Tween::ColorValueBetween(0.5, color_a, color_b);
76 SkColor color_midpoint2 =
77 gfx::Tween::ColorValueBetween(0.5, color_b, color_c);
78 std::unique_ptr<KeyframedColorAnimationCurve> curve(
79 KeyframedColorAnimationCurve::Create());
80 curve->AddKeyframe(
81 ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
82 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
83 color_b, nullptr));
84 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
85 color_c, nullptr));
86
87 EXPECT_SKCOLOR_EQ(color_a,
88 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
89 EXPECT_SKCOLOR_EQ(color_a,
90 curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
91 EXPECT_SKCOLOR_EQ(color_midpoint1,
92 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
93 EXPECT_SKCOLOR_EQ(color_b,
94 curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
95 EXPECT_SKCOLOR_EQ(color_midpoint2,
96 curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
97 EXPECT_SKCOLOR_EQ(color_c,
98 curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
99 EXPECT_SKCOLOR_EQ(color_c,
100 curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
101 }
102
103 // Tests that a color animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest,RepeatedColorKeyFrame)104 TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) {
105 SkColor color_a = SkColorSetARGB(255, 64, 0, 0);
106 SkColor color_b = SkColorSetARGB(255, 192, 0, 0);
107
108 std::unique_ptr<KeyframedColorAnimationCurve> curve(
109 KeyframedColorAnimationCurve::Create());
110 curve->AddKeyframe(
111 ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr));
112 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
113 color_a, nullptr));
114 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
115 color_b, nullptr));
116 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
117 color_b, nullptr));
118
119 EXPECT_SKCOLOR_EQ(color_a,
120 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
121 EXPECT_SKCOLOR_EQ(color_a,
122 curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
123 EXPECT_SKCOLOR_EQ(color_a,
124 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
125
126 SkColor value = curve->GetValue(base::TimeDelta::FromSecondsD(1.0f));
127 EXPECT_EQ(255u, SkColorGetA(value));
128 int red_value = SkColorGetR(value);
129 EXPECT_LE(64, red_value);
130 EXPECT_GE(192, red_value);
131
132 EXPECT_SKCOLOR_EQ(color_b,
133 curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
134 EXPECT_SKCOLOR_EQ(color_b,
135 curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
136 EXPECT_SKCOLOR_EQ(color_b,
137 curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
138 }
139
140 // Tests that a float animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneFloatKeyframe)141 TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
142 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
143 KeyframedFloatAnimationCurve::Create());
144 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
145 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
146 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
147 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
148 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
149 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
150 }
151
152 // Tests that a float animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoFloatKeyframe)153 TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) {
154 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
155 KeyframedFloatAnimationCurve::Create());
156 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
157 curve->AddKeyframe(
158 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
159 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
160 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
161 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
162 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
163 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
164 }
165
166 // Tests that a float animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeFloatKeyframe)167 TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) {
168 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
169 KeyframedFloatAnimationCurve::Create());
170 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
171 curve->AddKeyframe(
172 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
173 curve->AddKeyframe(
174 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 8.f, nullptr));
175 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
176 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
177 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
178 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
179 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
180 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
181 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
182 }
183
184 // Tests that a float animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest,RepeatedFloatKeyTimes)185 TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) {
186 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
187 KeyframedFloatAnimationCurve::Create());
188 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 4.f, nullptr));
189 curve->AddKeyframe(
190 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr));
191 curve->AddKeyframe(
192 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 6.f, nullptr));
193 curve->AddKeyframe(
194 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 6.f, nullptr));
195
196 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
197 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
198 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
199
200 // There is a discontinuity at 1. Any value between 4 and 6 is valid.
201 float value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
202 EXPECT_TRUE(value >= 4 && value <= 6);
203
204 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
205 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
206 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
207 }
208
209 // Tests that a transform animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneTransformKeyframe)210 TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) {
211 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
212 KeyframedTransformAnimationCurve::Create());
213 TransformOperations operations;
214 operations.AppendTranslate(2.f, 0.f, 0.f);
215 curve->AddKeyframe(
216 TransformKeyframe::Create(base::TimeDelta(), operations, nullptr));
217
218 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
219 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
220 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
221 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
222 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
223 }
224
225 // Tests that a transform animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoTransformKeyframe)226 TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) {
227 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
228 KeyframedTransformAnimationCurve::Create());
229 TransformOperations operations1;
230 operations1.AppendTranslate(2.f, 0.f, 0.f);
231 TransformOperations operations2;
232 operations2.AppendTranslate(4.f, 0.f, 0.f);
233
234 curve->AddKeyframe(
235 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
236 curve->AddKeyframe(TransformKeyframe::Create(
237 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
238 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
239 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
240 ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
241 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
242 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
243 }
244
245 // Tests that a transform animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeTransformKeyframe)246 TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) {
247 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
248 KeyframedTransformAnimationCurve::Create());
249 TransformOperations operations1;
250 operations1.AppendTranslate(2.f, 0.f, 0.f);
251 TransformOperations operations2;
252 operations2.AppendTranslate(4.f, 0.f, 0.f);
253 TransformOperations operations3;
254 operations3.AppendTranslate(8.f, 0.f, 0.f);
255 curve->AddKeyframe(
256 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
257 curve->AddKeyframe(TransformKeyframe::Create(
258 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
259 curve->AddKeyframe(TransformKeyframe::Create(
260 base::TimeDelta::FromSecondsD(2.0), operations3, nullptr));
261 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
262 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
263 ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
264 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
265 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
266 ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
267 ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
268 }
269
270 // Tests that a transform animation with multiple keys at a given time works
271 // sanely.
TEST(KeyframedAnimationCurveTest,RepeatedTransformKeyTimes)272 TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) {
273 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
274 KeyframedTransformAnimationCurve::Create());
275 // A step function.
276 TransformOperations operations1;
277 operations1.AppendTranslate(4.f, 0.f, 0.f);
278 TransformOperations operations2;
279 operations2.AppendTranslate(4.f, 0.f, 0.f);
280 TransformOperations operations3;
281 operations3.AppendTranslate(6.f, 0.f, 0.f);
282 TransformOperations operations4;
283 operations4.AppendTranslate(6.f, 0.f, 0.f);
284 curve->AddKeyframe(
285 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
286 curve->AddKeyframe(TransformKeyframe::Create(
287 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
288 curve->AddKeyframe(TransformKeyframe::Create(
289 base::TimeDelta::FromSecondsD(1.0), operations3, nullptr));
290 curve->AddKeyframe(TransformKeyframe::Create(
291 base::TimeDelta::FromSecondsD(2.0), operations4, nullptr));
292
293 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
294 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
295 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
296
297 // There is a discontinuity at 1. Any value between 4 and 6 is valid.
298 gfx::Transform value =
299 curve->GetValue(base::TimeDelta::FromSecondsD(1.f)).Apply();
300 EXPECT_GE(value.matrix().get(0, 3), 4.f);
301 EXPECT_LE(value.matrix().get(0, 3), 6.f);
302
303 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
304 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
305 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
306 }
307
308 // Tests that a discrete transform animation (e.g. where one or more keyframes
309 // is a non-invertible matrix) works as expected.
TEST(KeyframedAnimationCurveTest,DiscreteLinearTransformAnimation)310 TEST(KeyframedAnimationCurveTest, DiscreteLinearTransformAnimation) {
311 gfx::Transform non_invertible_matrix(0, 0, 0, 0, 0, 0);
312 gfx::Transform identity_matrix;
313
314 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
315 KeyframedTransformAnimationCurve::Create());
316 TransformOperations operations1;
317 operations1.AppendMatrix(non_invertible_matrix);
318 TransformOperations operations2;
319 operations2.AppendMatrix(identity_matrix);
320 TransformOperations operations3;
321 operations3.AppendMatrix(non_invertible_matrix);
322
323 curve->AddKeyframe(
324 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
325 curve->AddKeyframe(TransformKeyframe::Create(
326 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr));
327 curve->AddKeyframe(TransformKeyframe::Create(
328 base::TimeDelta::FromSecondsD(2.0), operations3, nullptr));
329
330 TransformOperations result;
331
332 // Between 0 and 0.5 seconds, the first keyframe should be returned.
333 result = curve->GetValue(base::TimeDelta::FromSecondsD(0.01f));
334 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
335
336 result = curve->GetValue(base::TimeDelta::FromSecondsD(0.49f));
337 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
338
339 // Between 0.5 and 1.5 seconds, the middle keyframe should be returned.
340 result = curve->GetValue(base::TimeDelta::FromSecondsD(0.5f));
341 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
342
343 result = curve->GetValue(base::TimeDelta::FromSecondsD(1.49f));
344 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
345
346 // Between 1.5 and 2.0 seconds, the last keyframe should be returned.
347 result = curve->GetValue(base::TimeDelta::FromSecondsD(1.5f));
348 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
349
350 result = curve->GetValue(base::TimeDelta::FromSecondsD(2.0f));
351 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
352 }
353
TEST(KeyframedAnimationCurveTest,DiscreteCubicBezierTransformAnimation)354 TEST(KeyframedAnimationCurveTest, DiscreteCubicBezierTransformAnimation) {
355 gfx::Transform non_invertible_matrix(0, 0, 0, 0, 0, 0);
356 gfx::Transform identity_matrix;
357
358 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
359 KeyframedTransformAnimationCurve::Create());
360 TransformOperations operations1;
361 operations1.AppendMatrix(non_invertible_matrix);
362 TransformOperations operations2;
363 operations2.AppendMatrix(identity_matrix);
364 TransformOperations operations3;
365 operations3.AppendMatrix(non_invertible_matrix);
366
367 // The cubic-bezier here is a nice fairly strong ease-in curve, where 50%
368 // progression is at approximately 85% of the time.
369 curve->AddKeyframe(TransformKeyframe::Create(
370 base::TimeDelta(), operations1,
371 CubicBezierTimingFunction::Create(0.75f, 0.25f, 0.9f, 0.4f)));
372 curve->AddKeyframe(TransformKeyframe::Create(
373 base::TimeDelta::FromSecondsD(1.0), operations2,
374 CubicBezierTimingFunction::Create(0.75f, 0.25f, 0.9f, 0.4f)));
375 curve->AddKeyframe(TransformKeyframe::Create(
376 base::TimeDelta::FromSecondsD(2.0), operations3,
377 CubicBezierTimingFunction::Create(0.75f, 0.25f, 0.9f, 0.4f)));
378
379 TransformOperations result;
380
381 // Due to the cubic-bezier, the first keyframe is returned almost all the way
382 // to 1 second.
383 result = curve->GetValue(base::TimeDelta::FromSecondsD(0.01f));
384 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
385
386 result = curve->GetValue(base::TimeDelta::FromSecondsD(0.8f));
387 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
388
389 // Between ~0.85 and ~1.85 seconds, the middle keyframe should be returned.
390 result = curve->GetValue(base::TimeDelta::FromSecondsD(0.85f));
391 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
392
393 result = curve->GetValue(base::TimeDelta::FromSecondsD(1.8f));
394 EXPECT_TRANSFORMATION_MATRIX_EQ(identity_matrix, result.Apply());
395
396 // Finally the last keyframe only takes effect after ~1.85 seconds.
397 result = curve->GetValue(base::TimeDelta::FromSecondsD(1.85f));
398 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
399
400 result = curve->GetValue(base::TimeDelta::FromSecondsD(2.0f));
401 EXPECT_TRANSFORMATION_MATRIX_EQ(non_invertible_matrix, result.Apply());
402 }
403
404 // Tests that a filter animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneFilterKeyframe)405 TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) {
406 std::unique_ptr<KeyframedFilterAnimationCurve> curve(
407 KeyframedFilterAnimationCurve::Create());
408 FilterOperations operations;
409 operations.Append(FilterOperation::CreateBrightnessFilter(2.f));
410 curve->AddKeyframe(
411 FilterKeyframe::Create(base::TimeDelta(), operations, nullptr));
412
413 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
414 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
415 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
416 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
417 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
418 }
419
420 // Tests that a filter animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoFilterKeyframe)421 TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) {
422 std::unique_ptr<KeyframedFilterAnimationCurve> curve(
423 KeyframedFilterAnimationCurve::Create());
424 FilterOperations operations1;
425 operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
426 FilterOperations operations2;
427 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
428
429 curve->AddKeyframe(
430 FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
431 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
432 operations2, nullptr));
433 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
434 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
435 ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
436 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
437 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
438 }
439
440 // Tests that a filter animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeFilterKeyframe)441 TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) {
442 std::unique_ptr<KeyframedFilterAnimationCurve> curve(
443 KeyframedFilterAnimationCurve::Create());
444 FilterOperations operations1;
445 operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
446 FilterOperations operations2;
447 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
448 FilterOperations operations3;
449 operations3.Append(FilterOperation::CreateBrightnessFilter(8.f));
450 curve->AddKeyframe(
451 FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
452 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
453 operations2, nullptr));
454 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f),
455 operations3, nullptr));
456 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
457 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
458 ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
459 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
460 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
461 ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
462 ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
463 }
464
465 // Tests that a filter animation with multiple keys at a given time works
466 // sanely.
TEST(KeyframedAnimationCurveTest,RepeatedFilterKeyTimes)467 TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) {
468 std::unique_ptr<KeyframedFilterAnimationCurve> curve(
469 KeyframedFilterAnimationCurve::Create());
470 // A step function.
471 FilterOperations operations1;
472 operations1.Append(FilterOperation::CreateBrightnessFilter(4.f));
473 FilterOperations operations2;
474 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
475 FilterOperations operations3;
476 operations3.Append(FilterOperation::CreateBrightnessFilter(6.f));
477 FilterOperations operations4;
478 operations4.Append(FilterOperation::CreateBrightnessFilter(6.f));
479 curve->AddKeyframe(
480 FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr));
481 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
482 operations2, nullptr));
483 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f),
484 operations3, nullptr));
485 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f),
486 operations4, nullptr));
487
488 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
489 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
490 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
491
492 // There is a discontinuity at 1. Any value between 4 and 6 is valid.
493 FilterOperations value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f));
494 EXPECT_EQ(1u, value.size());
495 EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type());
496 EXPECT_GE(value.at(0).amount(), 4);
497 EXPECT_LE(value.at(0).amount(), 6);
498
499 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
500 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
501 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
502 }
503
504 // Tests that the keyframes may be added out of order.
TEST(KeyframedAnimationCurveTest,UnsortedKeyframes)505 TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) {
506 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
507 KeyframedFloatAnimationCurve::Create());
508 curve->AddKeyframe(
509 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 8.f, nullptr));
510 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr));
511 curve->AddKeyframe(
512 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 4.f, nullptr));
513 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
514 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
515 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
516 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
517 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
518 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
519 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
520 }
521
522 // Tests that a linear timing function works as expected.
TEST(KeyframedAnimationCurveTest,LinearTimingFunction)523 TEST(KeyframedAnimationCurveTest, LinearTimingFunction) {
524 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
525 KeyframedFloatAnimationCurve::Create());
526 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f,
527 LinearTimingFunction::Create()));
528 curve->AddKeyframe(
529 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
530
531 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
532 EXPECT_FLOAT_EQ(0.75f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
533 }
534
535 // Tests that a cubic bezier timing function works as expected.
TEST(KeyframedAnimationCurveTest,CubicBezierTimingFunction)536 TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) {
537 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
538 KeyframedFloatAnimationCurve::Create());
539 curve->AddKeyframe(FloatKeyframe::Create(
540 base::TimeDelta(), 0.f,
541 CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f)));
542 curve->AddKeyframe(
543 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
544
545 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
546 EXPECT_LT(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
547 EXPECT_GT(0.25f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
548 EXPECT_NEAR(curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)), 0.5f,
549 0.00015f);
550 EXPECT_LT(0.75f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
551 EXPECT_GT(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
552 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
553 }
554
555 // Tests a step timing function if the change of values occur at the start.
TEST(KeyframedAnimationCurveTest,StepsTimingFunctionStepAtStart)556 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtStart) {
557 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
558 KeyframedFloatAnimationCurve::Create());
559 const int num_steps = 36;
560 curve->AddKeyframe(FloatKeyframe::Create(
561 base::TimeDelta(), 0.f,
562 StepsTimingFunction::Create(num_steps,
563 StepsTimingFunction::StepPosition::START)));
564 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
565 num_steps, nullptr));
566
567 const float time_threshold = 0.0001f;
568
569 for (float i = 0.f; i < num_steps; i += 1.f) {
570 const base::TimeDelta time1 =
571 base::TimeDelta::FromSecondsD(i / num_steps - time_threshold);
572 const base::TimeDelta time2 =
573 base::TimeDelta::FromSecondsD(i / num_steps + time_threshold);
574 EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time1));
575 EXPECT_FLOAT_EQ(std::ceil(i) + 1.f, curve->GetValue(time2));
576 }
577 EXPECT_FLOAT_EQ(num_steps,
578 curve->GetValue(base::TimeDelta::FromSecondsD(1.0)));
579
580 for (float i = 0.5f; i <= num_steps; i += 1.0f) {
581 const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps);
582 EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time));
583 }
584 }
585
586 // Tests a step timing function if the change of values occur at the end.
TEST(KeyframedAnimationCurveTest,StepsTimingFunctionStepAtEnd)587 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) {
588 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
589 KeyframedFloatAnimationCurve::Create());
590 const int num_steps = 36;
591 curve->AddKeyframe(FloatKeyframe::Create(
592 base::TimeDelta(), 0.f,
593 StepsTimingFunction::Create(num_steps,
594 StepsTimingFunction::StepPosition::END)));
595 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
596 num_steps, nullptr));
597
598 const float time_threshold = 0.0001f;
599
600 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta()));
601 for (float i = 1.f; i <= num_steps; i += 1.f) {
602 const base::TimeDelta time1 =
603 base::TimeDelta::FromSecondsD(i / num_steps - time_threshold);
604 const base::TimeDelta time2 =
605 base::TimeDelta::FromSecondsD(i / num_steps + time_threshold);
606 EXPECT_FLOAT_EQ(std::floor(i) - 1.f, curve->GetValue(time1));
607 EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time2));
608 }
609 EXPECT_FLOAT_EQ(num_steps,
610 curve->GetValue(base::TimeDelta::FromSecondsD(1.0)));
611
612 for (float i = 0.5f; i <= num_steps; i += 1.0f) {
613 const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps);
614 EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time));
615 }
616 }
617
618 // Tests that animations that are translations are correctly identified.
TEST(KeyframedAnimationCurveTest,IsTranslation)619 TEST(KeyframedAnimationCurveTest, IsTranslation) {
620 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
621 KeyframedTransformAnimationCurve::Create());
622
623 TransformOperations operations1;
624 curve->AddKeyframe(
625 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
626 operations1.AppendTranslate(2.0, 3.0, -1.0);
627 TransformOperations operations2;
628 operations2.AppendTranslate(4.0, 1.0, 2.0);
629 curve->AddKeyframe(TransformKeyframe::Create(
630 base::TimeDelta::FromSecondsD(1.f), operations2, nullptr));
631
632 EXPECT_TRUE(curve->IsTranslation());
633
634 TransformOperations operations3;
635 operations3.AppendScale(2.f, 2.f, 2.f);
636 curve->AddKeyframe(TransformKeyframe::Create(
637 base::TimeDelta::FromSecondsD(2.f), operations3, nullptr));
638
639 EXPECT_FALSE(curve->IsTranslation());
640
641 TransformOperations operations4;
642 operations3.AppendTranslate(2.f, 2.f, 2.f);
643 curve->AddKeyframe(TransformKeyframe::Create(
644 base::TimeDelta::FromSecondsD(3.f), operations4, nullptr));
645
646 EXPECT_FALSE(curve->IsTranslation());
647 }
648
649 // Tests that maximum target scale is computed as expected.
TEST(KeyframedAnimationCurveTest,MaximumTargetScale)650 TEST(KeyframedAnimationCurveTest, MaximumTargetScale) {
651 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
652 KeyframedTransformAnimationCurve::Create());
653
654 TransformOperations operations1;
655 curve->AddKeyframe(
656 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
657 operations1.AppendScale(2.f, -3.f, 1.f);
658 curve->AddKeyframe(TransformKeyframe::Create(
659 base::TimeDelta::FromSecondsD(1.f), operations1,
660 CubicBezierTimingFunction::CreatePreset(
661 CubicBezierTimingFunction::EaseType::EASE)));
662
663 float maximum_scale = 0.f;
664 EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
665 EXPECT_EQ(3.f, maximum_scale);
666
667 TransformOperations operations2;
668 operations2.AppendScale(6.f, 3.f, 2.f);
669 curve->AddKeyframe(TransformKeyframe::Create(
670 base::TimeDelta::FromSecondsD(2.f), operations2,
671 CubicBezierTimingFunction::CreatePreset(
672 CubicBezierTimingFunction::EaseType::EASE)));
673
674 EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
675 EXPECT_EQ(6.f, maximum_scale);
676
677 TransformOperations operations3;
678 operations3.AppendRotate(1.f, 0.f, 0.f, 90.f);
679 curve->AddKeyframe(TransformKeyframe::Create(
680 base::TimeDelta::FromSecondsD(3.f), operations3,
681 CubicBezierTimingFunction::CreatePreset(
682 CubicBezierTimingFunction::EaseType::EASE)));
683
684 EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale));
685 EXPECT_EQ(6.f, maximum_scale);
686
687 TransformOperations operations4;
688 operations4.AppendPerspective(3.f);
689 curve->AddKeyframe(TransformKeyframe::Create(
690 base::TimeDelta::FromSecondsD(4.f), operations4,
691 CubicBezierTimingFunction::CreatePreset(
692 CubicBezierTimingFunction::EaseType::EASE)));
693
694 EXPECT_FALSE(curve->MaximumTargetScale(true, &maximum_scale));
695
696 // The original scale is not used in computing the max.
697 std::unique_ptr<KeyframedTransformAnimationCurve> curve2(
698 KeyframedTransformAnimationCurve::Create());
699
700 TransformOperations operations5;
701 operations5.AppendScale(0.4f, 0.2f, 0.6f);
702 curve2->AddKeyframe(TransformKeyframe::Create(
703 base::TimeDelta(), operations5,
704 CubicBezierTimingFunction::CreatePreset(
705 CubicBezierTimingFunction::EaseType::EASE)));
706 TransformOperations operations6;
707 operations6.AppendScale(0.5f, 0.3f, -0.8f);
708 curve2->AddKeyframe(TransformKeyframe::Create(
709 base::TimeDelta::FromSecondsD(1.f), operations6,
710 CubicBezierTimingFunction::CreatePreset(
711 CubicBezierTimingFunction::EaseType::EASE)));
712
713 EXPECT_TRUE(curve2->MaximumTargetScale(true, &maximum_scale));
714 EXPECT_EQ(0.8f, maximum_scale);
715
716 EXPECT_TRUE(curve2->MaximumTargetScale(false, &maximum_scale));
717 EXPECT_EQ(0.6f, maximum_scale);
718 }
719
720 // Tests that starting animation scale is computed as expected.
TEST(KeyframedAnimationCurveTest,AnimationStartScale)721 TEST(KeyframedAnimationCurveTest, AnimationStartScale) {
722 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
723 KeyframedTransformAnimationCurve::Create());
724
725 TransformOperations operations1;
726 curve->AddKeyframe(
727 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr));
728 operations1.AppendScale(2.f, -3.f, 1.f);
729 curve->AddKeyframe(TransformKeyframe::Create(
730 base::TimeDelta::FromSecondsD(1.f), operations1,
731 CubicBezierTimingFunction::CreatePreset(
732 CubicBezierTimingFunction::EaseType::EASE)));
733
734 float start_scale = 0.f;
735
736 // Forward direction
737 EXPECT_TRUE(curve->AnimationStartScale(true, &start_scale));
738 EXPECT_EQ(1.f, start_scale);
739
740 // Backward direction
741 EXPECT_TRUE(curve->AnimationStartScale(false, &start_scale));
742 EXPECT_EQ(3.f, start_scale);
743
744 TransformOperations operations2;
745 operations2.AppendScale(6.f, 3.f, 2.f);
746 curve->AddKeyframe(TransformKeyframe::Create(
747 base::TimeDelta::FromSecondsD(2.f), operations2,
748 CubicBezierTimingFunction::CreatePreset(
749 CubicBezierTimingFunction::EaseType::EASE)));
750
751 // Forward direction
752 EXPECT_TRUE(curve->AnimationStartScale(true, &start_scale));
753 EXPECT_EQ(1.f, start_scale);
754
755 // Backward direction
756 EXPECT_TRUE(curve->AnimationStartScale(false, &start_scale));
757 EXPECT_EQ(6.f, start_scale);
758
759 TransformOperations operations3;
760 operations3.AppendRotate(1.f, 0.f, 0.f, 90.f);
761 curve->AddKeyframe(TransformKeyframe::Create(
762 base::TimeDelta::FromSecondsD(3.f), operations3,
763 CubicBezierTimingFunction::CreatePreset(
764 CubicBezierTimingFunction::EaseType::EASE)));
765
766 EXPECT_TRUE(curve->AnimationStartScale(false, &start_scale));
767 EXPECT_EQ(1.f, start_scale);
768
769 TransformOperations operations4;
770 operations4.AppendPerspective(90.f);
771 curve->AddKeyframe(TransformKeyframe::Create(
772 base::TimeDelta::FromSecondsD(4.f), operations4,
773 CubicBezierTimingFunction::CreatePreset(
774 CubicBezierTimingFunction::EaseType::EASE)));
775
776 EXPECT_FALSE(curve->AnimationStartScale(false, &start_scale));
777 EXPECT_EQ(0.f, start_scale);
778 }
779
780 // Tests that an animation with a curve timing function works as expected.
TEST(KeyframedAnimationCurveTest,CurveTiming)781 TEST(KeyframedAnimationCurveTest, CurveTiming) {
782 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
783 KeyframedFloatAnimationCurve::Create());
784 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
785 curve->AddKeyframe(
786 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
787 curve->SetTimingFunction(
788 CubicBezierTimingFunction::Create(0.75f, 0.f, 0.25f, 1.f));
789 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
790 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
791 EXPECT_NEAR(0.05f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
792 0.005f);
793 EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
794 EXPECT_NEAR(0.95f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
795 0.005f);
796 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
797 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
798 }
799
800 // Tests that an animation with a curve and keyframe timing function works as
801 // expected.
TEST(KeyframedAnimationCurveTest,CurveAndKeyframeTiming)802 TEST(KeyframedAnimationCurveTest, CurveAndKeyframeTiming) {
803 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
804 KeyframedFloatAnimationCurve::Create());
805 curve->AddKeyframe(FloatKeyframe::Create(
806 base::TimeDelta(), 0.f,
807 CubicBezierTimingFunction::Create(0.35f, 0.f, 0.65f, 1.f)));
808 curve->AddKeyframe(
809 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
810 // Curve timing function producing outputs outside of range [0,1].
811 curve->SetTimingFunction(
812 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
813 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
814 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
815 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(
816 0.25f))); // Clamped. c(.25) < 0
817 EXPECT_NEAR(0.17f, curve->GetValue(base::TimeDelta::FromSecondsD(0.42f)),
818 0.005f); // c(.42)=.27, k(.27)=.17
819 EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
820 EXPECT_NEAR(0.83f, curve->GetValue(base::TimeDelta::FromSecondsD(0.58f)),
821 0.005f); // c(.58)=.73, k(.73)=.83
822 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(
823 0.75f))); // Clamped. c(.75) > 1
824 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
825 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
826 }
827
828 // Tests that a linear timing function works as expected for inputs outside of
829 // range [0,1]
TEST(KeyframedAnimationCurveTest,LinearTimingInputsOutsideZeroOneRange)830 TEST(KeyframedAnimationCurveTest, LinearTimingInputsOutsideZeroOneRange) {
831 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
832 KeyframedFloatAnimationCurve::Create());
833 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
834 curve->AddKeyframe(
835 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
836 // Curve timing function producing timing outputs outside of range [0,1].
837 curve->SetTimingFunction(
838 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
839
840 EXPECT_NEAR(-0.076f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
841 0.001f);
842 EXPECT_NEAR(2.076f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
843 0.001f);
844 }
845
846 // If a curve cubic-bezier timing function produces timing outputs outside
847 // the range [0, 1] then a keyframe cubic-bezier timing function
848 // should consume that input properly (using end-point gradients).
TEST(KeyframedAnimationCurveTest,CurveTimingInputsOutsideZeroOneRange)849 TEST(KeyframedAnimationCurveTest, CurveTimingInputsOutsideZeroOneRange) {
850 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
851 KeyframedFloatAnimationCurve::Create());
852 // Keyframe timing function with 0.5 gradients at each end.
853 curve->AddKeyframe(FloatKeyframe::Create(
854 base::TimeDelta(), 0.f,
855 CubicBezierTimingFunction::Create(0.5f, 0.25f, 0.5f, 0.75f)));
856 curve->AddKeyframe(
857 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
858 // Curve timing function producing timing outputs outside of range [0,1].
859 curve->SetTimingFunction(
860 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
861
862 EXPECT_NEAR(-0.02f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)),
863 0.002f); // c(.25)=-.04, -.04*0.5=-0.02
864 EXPECT_NEAR(0.33f, curve->GetValue(base::TimeDelta::FromSecondsD(0.46f)),
865 0.002f); // c(.46)=.38, k(.38)=.33
866
867 EXPECT_NEAR(0.67f, curve->GetValue(base::TimeDelta::FromSecondsD(0.54f)),
868 0.002f); // c(.54)=.62, k(.62)=.67
869 EXPECT_NEAR(1.02f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)),
870 0.002f); // c(.75)=1.04 1+.04*0.5=1.02
871 }
872
873 // Tests that a step timing function works as expected for inputs outside of
874 // range [0,1]
TEST(KeyframedAnimationCurveTest,StepsTimingStartInputsOutsideZeroOneRange)875 TEST(KeyframedAnimationCurveTest, StepsTimingStartInputsOutsideZeroOneRange) {
876 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
877 KeyframedFloatAnimationCurve::Create());
878 curve->AddKeyframe(
879 FloatKeyframe::Create(base::TimeDelta(), 0.f,
880 StepsTimingFunction::Create(
881 4, StepsTimingFunction::StepPosition::START)));
882 curve->AddKeyframe(
883 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
884 // Curve timing function producing timing outputs outside of range [0,1].
885 curve->SetTimingFunction(
886 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
887
888 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
889 EXPECT_FLOAT_EQ(2.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
890 }
891
TEST(KeyframedAnimationCurveTest,StepsTimingEndInputsOutsideZeroOneRange)892 TEST(KeyframedAnimationCurveTest, StepsTimingEndInputsOutsideZeroOneRange) {
893 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
894 KeyframedFloatAnimationCurve::Create());
895 curve->AddKeyframe(FloatKeyframe::Create(
896 base::TimeDelta(), 0.f,
897 StepsTimingFunction::Create(4, StepsTimingFunction::StepPosition::END)));
898 curve->AddKeyframe(
899 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr));
900 // Curve timing function producing timing outputs outside of range [0,1].
901 curve->SetTimingFunction(
902 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
903
904 EXPECT_FLOAT_EQ(-0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)));
905 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)));
906 }
907
908 // Tests that an animation with a curve timing function and multiple keyframes
909 // works as expected.
TEST(KeyframedAnimationCurveTest,CurveTimingMultipleKeyframes)910 TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) {
911 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
912 KeyframedFloatAnimationCurve::Create());
913 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
914 curve->AddKeyframe(
915 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
916 curve->AddKeyframe(
917 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 3.f, nullptr));
918 curve->AddKeyframe(
919 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), 6.f, nullptr));
920 curve->AddKeyframe(
921 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.f), 9.f, nullptr));
922 curve->SetTimingFunction(
923 CubicBezierTimingFunction::Create(0.5f, 0.f, 0.5f, 1.f));
924 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
925 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
926 EXPECT_NEAR(0.42f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)),
927 0.005f);
928 EXPECT_NEAR(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.455f)),
929 0.005f);
930 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
931 EXPECT_NEAR(8.72f, curve->GetValue(base::TimeDelta::FromSecondsD(3.5f)),
932 0.01f);
933 EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(4.f)));
934 EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(5.f)));
935 }
936
937 // Tests that an animation with a curve timing function that overshoots works as
938 // expected.
TEST(KeyframedAnimationCurveTest,CurveTimingOvershootMultipeKeyframes)939 TEST(KeyframedAnimationCurveTest, CurveTimingOvershootMultipeKeyframes) {
940 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
941 KeyframedFloatAnimationCurve::Create());
942 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
943 curve->AddKeyframe(
944 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr));
945 curve->AddKeyframe(
946 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 3.f, nullptr));
947 curve->AddKeyframe(
948 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.0), 6.f, nullptr));
949 curve->AddKeyframe(
950 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.0), 9.f, nullptr));
951 // Curve timing function producing outputs outside of range [0,1].
952 curve->SetTimingFunction(
953 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f));
954 EXPECT_LE(curve->GetValue(base::TimeDelta::FromSecondsD(1.f)),
955 0.f); // c(.25) < 0
956 EXPECT_GE(curve->GetValue(base::TimeDelta::FromSecondsD(3.f)),
957 9.f); // c(.75) > 1
958 }
959
960 // Tests that a float animation with multiple keys works with scaled duration.
TEST(KeyframedAnimationCurveTest,ScaledDuration)961 TEST(KeyframedAnimationCurveTest, ScaledDuration) {
962 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
963 KeyframedFloatAnimationCurve::Create());
964 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr));
965 curve->AddKeyframe(
966 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr));
967 curve->AddKeyframe(
968 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 3.f, nullptr));
969 curve->AddKeyframe(
970 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), 6.f, nullptr));
971 curve->AddKeyframe(
972 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.f), 9.f, nullptr));
973 curve->SetTimingFunction(
974 CubicBezierTimingFunction::Create(0.5f, 0.f, 0.5f, 1.f));
975
976 const double scale = 1000.0;
977 curve->set_scaled_duration(scale);
978
979 EXPECT_DOUBLE_EQ(scale * 4, curve->Duration().InSecondsF());
980
981 EXPECT_FLOAT_EQ(0.f,
982 curve->GetValue(base::TimeDelta::FromSecondsD(scale * -1.f)));
983 EXPECT_FLOAT_EQ(0.f,
984 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 0.f)));
985 EXPECT_NEAR(0.42f,
986 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 1.f)),
987 0.005f);
988 EXPECT_NEAR(1.f,
989 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 1.455f)),
990 0.005f);
991 EXPECT_FLOAT_EQ(3.f,
992 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 2.f)));
993 EXPECT_NEAR(8.72f,
994 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 3.5f)),
995 0.01f);
996 EXPECT_FLOAT_EQ(9.f,
997 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 4.f)));
998 EXPECT_FLOAT_EQ(9.f,
999 curve->GetValue(base::TimeDelta::FromSecondsD(scale * 5.f)));
1000 }
1001
1002 // Tests that a size animation with one keyframe works as expected.
TEST(KeyframedAnimationCurveTest,OneSizeKeyFrame)1003 TEST(KeyframedAnimationCurveTest, OneSizeKeyFrame) {
1004 gfx::SizeF size = gfx::SizeF(100, 100);
1005 std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1006 KeyframedSizeAnimationCurve::Create());
1007 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size, nullptr));
1008
1009 EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1010 EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1011 EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1012 EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
1013 EXPECT_SIZEF_EQ(size, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1014 }
1015
1016 // Tests that a size animation with two keyframes works as expected.
TEST(KeyframedAnimationCurveTest,TwoSizeKeyFrame)1017 TEST(KeyframedAnimationCurveTest, TwoSizeKeyFrame) {
1018 gfx::SizeF size_a = gfx::SizeF(100, 100);
1019 gfx::SizeF size_b = gfx::SizeF(100, 0);
1020 gfx::SizeF size_midpoint = gfx::Tween::SizeFValueBetween(0.5, size_a, size_b);
1021 std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1022 KeyframedSizeAnimationCurve::Create());
1023 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size_a, nullptr));
1024 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1025 size_b, nullptr));
1026
1027 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1028 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1029 EXPECT_SIZEF_EQ(size_midpoint,
1030 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1031 EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
1032 EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1033 }
1034
1035 // Tests that a size animation with three keyframes works as expected.
TEST(KeyframedAnimationCurveTest,ThreeSizeKeyFrame)1036 TEST(KeyframedAnimationCurveTest, ThreeSizeKeyFrame) {
1037 gfx::SizeF size_a = gfx::SizeF(100, 100);
1038 gfx::SizeF size_b = gfx::SizeF(100, 0);
1039 gfx::SizeF size_c = gfx::SizeF(200, 0);
1040 gfx::SizeF size_midpoint1 =
1041 gfx::Tween::SizeFValueBetween(0.5, size_a, size_b);
1042 gfx::SizeF size_midpoint2 =
1043 gfx::Tween::SizeFValueBetween(0.5, size_b, size_c);
1044 std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1045 KeyframedSizeAnimationCurve::Create());
1046 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size_a, nullptr));
1047 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1048 size_b, nullptr));
1049 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
1050 size_c, nullptr));
1051
1052 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1053 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1054 EXPECT_SIZEF_EQ(size_midpoint1,
1055 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1056 EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)));
1057 EXPECT_SIZEF_EQ(size_midpoint2,
1058 curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
1059 EXPECT_SIZEF_EQ(size_c, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1060 EXPECT_SIZEF_EQ(size_c, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
1061 }
1062
1063 // Tests that a size animation with multiple keys at a given time works sanely.
TEST(KeyframedAnimationCurveTest,RepeatedSizeKeyFrame)1064 TEST(KeyframedAnimationCurveTest, RepeatedSizeKeyFrame) {
1065 gfx::SizeF size_a = gfx::SizeF(100, 64);
1066 gfx::SizeF size_b = gfx::SizeF(100, 192);
1067
1068 std::unique_ptr<KeyframedSizeAnimationCurve> curve(
1069 KeyframedSizeAnimationCurve::Create());
1070 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta(), size_a, nullptr));
1071 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1072 size_a, nullptr));
1073 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(1.0),
1074 size_b, nullptr));
1075 curve->AddKeyframe(SizeKeyframe::Create(base::TimeDelta::FromSecondsD(2.0),
1076 size_b, nullptr));
1077
1078 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f)));
1079 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.f)));
1080 EXPECT_SIZEF_EQ(size_a, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)));
1081
1082 gfx::SizeF value = curve->GetValue(base::TimeDelta::FromSecondsD(1.0f));
1083 EXPECT_FLOAT_EQ(100.0f, value.width());
1084 EXPECT_LE(64.0f, value.height());
1085 EXPECT_GE(192.0f, value.height());
1086
1087 EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f)));
1088 EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(2.f)));
1089 EXPECT_SIZEF_EQ(size_b, curve->GetValue(base::TimeDelta::FromSecondsD(3.f)));
1090 }
1091
1092 } // namespace
1093 } // namespace cc
1094