OLD | NEW |
| (Empty) |
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 "testing/gmock/include/gmock/gmock.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 #include "ui/gfx/animation/tween.h" | |
11 #include "ui/gfx/geometry/box_f.h" | |
12 #include "ui/gfx/test/gfx_util.h" | |
13 | |
14 namespace cc { | |
15 namespace { | |
16 | |
17 void ExpectTranslateX(SkMScalar translate_x, const gfx::Transform& transform) { | |
18 EXPECT_FLOAT_EQ(translate_x, transform.matrix().get(0, 3)); | |
19 } | |
20 | |
21 void ExpectBrightness(double brightness, const FilterOperations& filter) { | |
22 EXPECT_EQ(1u, filter.size()); | |
23 EXPECT_EQ(FilterOperation::BRIGHTNESS, filter.at(0).type()); | |
24 EXPECT_FLOAT_EQ(brightness, filter.at(0).amount()); | |
25 } | |
26 | |
27 // Tests that a color animation with one keyframe works as expected. | |
28 TEST(KeyframedAnimationCurveTest, OneColorKeyFrame) { | |
29 SkColor color = SkColorSetARGB(255, 255, 255, 255); | |
30 scoped_ptr<KeyframedColorAnimationCurve> curve( | |
31 KeyframedColorAnimationCurve::Create()); | |
32 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta(), color, nullptr)); | |
33 | |
34 EXPECT_SKCOLOR_EQ(color, | |
35 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
36 EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
37 EXPECT_SKCOLOR_EQ(color, | |
38 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
39 EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
40 EXPECT_SKCOLOR_EQ(color, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
41 } | |
42 | |
43 // Tests that a color animation with two keyframes works as expected. | |
44 TEST(KeyframedAnimationCurveTest, TwoColorKeyFrame) { | |
45 SkColor color_a = SkColorSetARGB(255, 255, 0, 0); | |
46 SkColor color_b = SkColorSetARGB(255, 0, 255, 0); | |
47 SkColor color_midpoint = gfx::Tween::ColorValueBetween(0.5, color_a, color_b); | |
48 scoped_ptr<KeyframedColorAnimationCurve> curve( | |
49 KeyframedColorAnimationCurve::Create()); | |
50 curve->AddKeyframe( | |
51 ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr)); | |
52 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
53 color_b, nullptr)); | |
54 | |
55 EXPECT_SKCOLOR_EQ(color_a, | |
56 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
57 EXPECT_SKCOLOR_EQ(color_a, | |
58 curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
59 EXPECT_SKCOLOR_EQ(color_midpoint, | |
60 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
61 EXPECT_SKCOLOR_EQ(color_b, | |
62 curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
63 EXPECT_SKCOLOR_EQ(color_b, | |
64 curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
65 } | |
66 | |
67 // Tests that a color animation with three keyframes works as expected. | |
68 TEST(KeyframedAnimationCurveTest, ThreeColorKeyFrame) { | |
69 SkColor color_a = SkColorSetARGB(255, 255, 0, 0); | |
70 SkColor color_b = SkColorSetARGB(255, 0, 255, 0); | |
71 SkColor color_c = SkColorSetARGB(255, 0, 0, 255); | |
72 SkColor color_midpoint1 = | |
73 gfx::Tween::ColorValueBetween(0.5, color_a, color_b); | |
74 SkColor color_midpoint2 = | |
75 gfx::Tween::ColorValueBetween(0.5, color_b, color_c); | |
76 scoped_ptr<KeyframedColorAnimationCurve> curve( | |
77 KeyframedColorAnimationCurve::Create()); | |
78 curve->AddKeyframe( | |
79 ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr)); | |
80 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
81 color_b, nullptr)); | |
82 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), | |
83 color_c, nullptr)); | |
84 | |
85 EXPECT_SKCOLOR_EQ(color_a, | |
86 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
87 EXPECT_SKCOLOR_EQ(color_a, | |
88 curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
89 EXPECT_SKCOLOR_EQ(color_midpoint1, | |
90 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
91 EXPECT_SKCOLOR_EQ(color_b, | |
92 curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
93 EXPECT_SKCOLOR_EQ(color_midpoint2, | |
94 curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
95 EXPECT_SKCOLOR_EQ(color_c, | |
96 curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
97 EXPECT_SKCOLOR_EQ(color_c, | |
98 curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
99 } | |
100 | |
101 // Tests that a colro animation with multiple keys at a given time works sanely. | |
102 TEST(KeyframedAnimationCurveTest, RepeatedColorKeyFrame) { | |
103 SkColor color_a = SkColorSetARGB(255, 64, 0, 0); | |
104 SkColor color_b = SkColorSetARGB(255, 192, 0, 0); | |
105 | |
106 scoped_ptr<KeyframedColorAnimationCurve> curve( | |
107 KeyframedColorAnimationCurve::Create()); | |
108 curve->AddKeyframe( | |
109 ColorKeyframe::Create(base::TimeDelta(), color_a, nullptr)); | |
110 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
111 color_a, nullptr)); | |
112 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
113 color_b, nullptr)); | |
114 curve->AddKeyframe(ColorKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), | |
115 color_b, nullptr)); | |
116 | |
117 EXPECT_SKCOLOR_EQ(color_a, | |
118 curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
119 EXPECT_SKCOLOR_EQ(color_a, | |
120 curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
121 EXPECT_SKCOLOR_EQ(color_a, | |
122 curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
123 | |
124 SkColor value = curve->GetValue(base::TimeDelta::FromSecondsD(1.0f)); | |
125 EXPECT_EQ(255u, SkColorGetA(value)); | |
126 int red_value = SkColorGetR(value); | |
127 EXPECT_LE(64, red_value); | |
128 EXPECT_GE(192, red_value); | |
129 | |
130 EXPECT_SKCOLOR_EQ(color_b, | |
131 curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
132 EXPECT_SKCOLOR_EQ(color_b, | |
133 curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
134 EXPECT_SKCOLOR_EQ(color_b, | |
135 curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
136 } | |
137 | |
138 // Tests that a float animation with one keyframe works as expected. | |
139 TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) { | |
140 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
141 KeyframedFloatAnimationCurve::Create()); | |
142 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); | |
143 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
144 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
145 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
146 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
147 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
148 } | |
149 | |
150 // Tests that a float animation with two keyframes works as expected. | |
151 TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) { | |
152 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
153 KeyframedFloatAnimationCurve::Create()); | |
154 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); | |
155 curve->AddKeyframe( | |
156 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr)); | |
157 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
158 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
159 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
160 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
161 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
162 } | |
163 | |
164 // Tests that a float animation with three keyframes works as expected. | |
165 TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) { | |
166 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
167 KeyframedFloatAnimationCurve::Create()); | |
168 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); | |
169 curve->AddKeyframe( | |
170 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr)); | |
171 curve->AddKeyframe( | |
172 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 8.f, nullptr)); | |
173 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
174 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
175 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
176 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
177 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
178 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
179 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
180 } | |
181 | |
182 // Tests that a float animation with multiple keys at a given time works sanely. | |
183 TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) { | |
184 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
185 KeyframedFloatAnimationCurve::Create()); | |
186 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 4.f, nullptr)); | |
187 curve->AddKeyframe( | |
188 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 4.f, nullptr)); | |
189 curve->AddKeyframe( | |
190 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 6.f, nullptr)); | |
191 curve->AddKeyframe( | |
192 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 6.f, nullptr)); | |
193 | |
194 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
195 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
196 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
197 | |
198 // There is a discontinuity at 1. Any value between 4 and 6 is valid. | |
199 float value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f)); | |
200 EXPECT_TRUE(value >= 4 && value <= 6); | |
201 | |
202 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
203 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
204 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
205 } | |
206 | |
207 // Tests that a transform animation with one keyframe works as expected. | |
208 TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) { | |
209 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
210 KeyframedTransformAnimationCurve::Create()); | |
211 TransformOperations operations; | |
212 operations.AppendTranslate(2.f, 0.f, 0.f); | |
213 curve->AddKeyframe( | |
214 TransformKeyframe::Create(base::TimeDelta(), operations, nullptr)); | |
215 | |
216 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
217 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
218 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
219 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
220 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
221 } | |
222 | |
223 // Tests that a transform animation with two keyframes works as expected. | |
224 TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) { | |
225 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
226 KeyframedTransformAnimationCurve::Create()); | |
227 TransformOperations operations1; | |
228 operations1.AppendTranslate(2.f, 0.f, 0.f); | |
229 TransformOperations operations2; | |
230 operations2.AppendTranslate(4.f, 0.f, 0.f); | |
231 | |
232 curve->AddKeyframe( | |
233 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
234 curve->AddKeyframe(TransformKeyframe::Create( | |
235 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); | |
236 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
237 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
238 ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
239 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
240 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
241 } | |
242 | |
243 // Tests that a transform animation with three keyframes works as expected. | |
244 TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) { | |
245 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
246 KeyframedTransformAnimationCurve::Create()); | |
247 TransformOperations operations1; | |
248 operations1.AppendTranslate(2.f, 0.f, 0.f); | |
249 TransformOperations operations2; | |
250 operations2.AppendTranslate(4.f, 0.f, 0.f); | |
251 TransformOperations operations3; | |
252 operations3.AppendTranslate(8.f, 0.f, 0.f); | |
253 curve->AddKeyframe( | |
254 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
255 curve->AddKeyframe(TransformKeyframe::Create( | |
256 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); | |
257 curve->AddKeyframe(TransformKeyframe::Create( | |
258 base::TimeDelta::FromSecondsD(2.0), operations3, nullptr)); | |
259 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
260 ExpectTranslateX(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
261 ExpectTranslateX(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
262 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
263 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
264 ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
265 ExpectTranslateX(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
266 } | |
267 | |
268 // Tests that a transform animation with multiple keys at a given time works | |
269 // sanely. | |
270 TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) { | |
271 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
272 KeyframedTransformAnimationCurve::Create()); | |
273 // A step function. | |
274 TransformOperations operations1; | |
275 operations1.AppendTranslate(4.f, 0.f, 0.f); | |
276 TransformOperations operations2; | |
277 operations2.AppendTranslate(4.f, 0.f, 0.f); | |
278 TransformOperations operations3; | |
279 operations3.AppendTranslate(6.f, 0.f, 0.f); | |
280 TransformOperations operations4; | |
281 operations4.AppendTranslate(6.f, 0.f, 0.f); | |
282 curve->AddKeyframe( | |
283 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
284 curve->AddKeyframe(TransformKeyframe::Create( | |
285 base::TimeDelta::FromSecondsD(1.0), operations2, nullptr)); | |
286 curve->AddKeyframe(TransformKeyframe::Create( | |
287 base::TimeDelta::FromSecondsD(1.0), operations3, nullptr)); | |
288 curve->AddKeyframe(TransformKeyframe::Create( | |
289 base::TimeDelta::FromSecondsD(2.0), operations4, nullptr)); | |
290 | |
291 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
292 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
293 ExpectTranslateX(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
294 | |
295 // There is a discontinuity at 1. Any value between 4 and 6 is valid. | |
296 gfx::Transform value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f)); | |
297 EXPECT_GE(value.matrix().get(0, 3), 4.f); | |
298 EXPECT_LE(value.matrix().get(0, 3), 6.f); | |
299 | |
300 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
301 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
302 ExpectTranslateX(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
303 } | |
304 | |
305 // Tests that a filter animation with one keyframe works as expected. | |
306 TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) { | |
307 scoped_ptr<KeyframedFilterAnimationCurve> curve( | |
308 KeyframedFilterAnimationCurve::Create()); | |
309 FilterOperations operations; | |
310 operations.Append(FilterOperation::CreateBrightnessFilter(2.f)); | |
311 curve->AddKeyframe( | |
312 FilterKeyframe::Create(base::TimeDelta(), operations, nullptr)); | |
313 | |
314 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
315 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
316 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
317 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
318 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
319 } | |
320 | |
321 // Tests that a filter animation with two keyframes works as expected. | |
322 TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) { | |
323 scoped_ptr<KeyframedFilterAnimationCurve> curve( | |
324 KeyframedFilterAnimationCurve::Create()); | |
325 FilterOperations operations1; | |
326 operations1.Append(FilterOperation::CreateBrightnessFilter(2.f)); | |
327 FilterOperations operations2; | |
328 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f)); | |
329 | |
330 curve->AddKeyframe( | |
331 FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
332 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), | |
333 operations2, nullptr)); | |
334 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
335 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
336 ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
337 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
338 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
339 } | |
340 | |
341 // Tests that a filter animation with three keyframes works as expected. | |
342 TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) { | |
343 scoped_ptr<KeyframedFilterAnimationCurve> curve( | |
344 KeyframedFilterAnimationCurve::Create()); | |
345 FilterOperations operations1; | |
346 operations1.Append(FilterOperation::CreateBrightnessFilter(2.f)); | |
347 FilterOperations operations2; | |
348 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f)); | |
349 FilterOperations operations3; | |
350 operations3.Append(FilterOperation::CreateBrightnessFilter(8.f)); | |
351 curve->AddKeyframe( | |
352 FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
353 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), | |
354 operations2, nullptr)); | |
355 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), | |
356 operations3, nullptr)); | |
357 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
358 ExpectBrightness(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
359 ExpectBrightness(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
360 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
361 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
362 ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
363 ExpectBrightness(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
364 } | |
365 | |
366 // Tests that a filter animation with multiple keys at a given time works | |
367 // sanely. | |
368 TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) { | |
369 scoped_ptr<KeyframedFilterAnimationCurve> curve( | |
370 KeyframedFilterAnimationCurve::Create()); | |
371 // A step function. | |
372 FilterOperations operations1; | |
373 operations1.Append(FilterOperation::CreateBrightnessFilter(4.f)); | |
374 FilterOperations operations2; | |
375 operations2.Append(FilterOperation::CreateBrightnessFilter(4.f)); | |
376 FilterOperations operations3; | |
377 operations3.Append(FilterOperation::CreateBrightnessFilter(6.f)); | |
378 FilterOperations operations4; | |
379 operations4.Append(FilterOperation::CreateBrightnessFilter(6.f)); | |
380 curve->AddKeyframe( | |
381 FilterKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
382 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), | |
383 operations2, nullptr)); | |
384 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), | |
385 operations3, nullptr)); | |
386 curve->AddKeyframe(FilterKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), | |
387 operations4, nullptr)); | |
388 | |
389 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
390 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
391 ExpectBrightness(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
392 | |
393 // There is a discontinuity at 1. Any value between 4 and 6 is valid. | |
394 FilterOperations value = curve->GetValue(base::TimeDelta::FromSecondsD(1.f)); | |
395 EXPECT_EQ(1u, value.size()); | |
396 EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type()); | |
397 EXPECT_GE(value.at(0).amount(), 4); | |
398 EXPECT_LE(value.at(0).amount(), 6); | |
399 | |
400 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
401 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
402 ExpectBrightness(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
403 } | |
404 | |
405 // Tests that the keyframes may be added out of order. | |
406 TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) { | |
407 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
408 KeyframedFloatAnimationCurve::Create()); | |
409 curve->AddKeyframe( | |
410 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 8.f, nullptr)); | |
411 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 2.f, nullptr)); | |
412 curve->AddKeyframe( | |
413 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 4.f, nullptr)); | |
414 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
415 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
416 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
417 EXPECT_FLOAT_EQ(4.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
418 EXPECT_FLOAT_EQ(6.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.5f))); | |
419 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
420 EXPECT_FLOAT_EQ(8.f, curve->GetValue(base::TimeDelta::FromSecondsD(3.f))); | |
421 } | |
422 | |
423 // Tests that a cubic bezier timing function works as expected. | |
424 TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) { | |
425 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
426 KeyframedFloatAnimationCurve::Create()); | |
427 curve->AddKeyframe(FloatKeyframe::Create( | |
428 base::TimeDelta(), 0.f, | |
429 CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f))); | |
430 curve->AddKeyframe( | |
431 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr)); | |
432 | |
433 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
434 EXPECT_LT(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f))); | |
435 EXPECT_GT(0.25f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f))); | |
436 EXPECT_NEAR(curve->GetValue(base::TimeDelta::FromSecondsD(0.5f)), 0.5f, | |
437 0.00015f); | |
438 EXPECT_LT(0.75f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f))); | |
439 EXPECT_GT(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f))); | |
440 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
441 } | |
442 | |
443 // Tests a step timing function if the change of values occur at the start. | |
444 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtStart) { | |
445 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
446 KeyframedFloatAnimationCurve::Create()); | |
447 const int num_steps = 36; | |
448 const float steps_start_offset = 1.0f; | |
449 curve->AddKeyframe(FloatKeyframe::Create( | |
450 base::TimeDelta(), 0.f, | |
451 StepsTimingFunction::Create(num_steps, steps_start_offset))); | |
452 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
453 num_steps, nullptr)); | |
454 | |
455 const float time_threshold = 0.0001f; | |
456 | |
457 for (float i = 0.f; i < num_steps; i += 1.f) { | |
458 const base::TimeDelta time1 = | |
459 base::TimeDelta::FromSecondsD(i / num_steps - time_threshold); | |
460 const base::TimeDelta time2 = | |
461 base::TimeDelta::FromSecondsD(i / num_steps + time_threshold); | |
462 EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time1)); | |
463 EXPECT_FLOAT_EQ(std::ceil(i) + 1.f, curve->GetValue(time2)); | |
464 } | |
465 EXPECT_FLOAT_EQ(num_steps, | |
466 curve->GetValue(base::TimeDelta::FromSecondsD(1.0))); | |
467 | |
468 for (float i = 0.5f; i <= num_steps; i += 1.0f) { | |
469 const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps); | |
470 EXPECT_FLOAT_EQ(std::ceil(i), curve->GetValue(time)); | |
471 } | |
472 } | |
473 | |
474 // Tests a step timing function if the change of values occur at the middle. | |
475 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtMiddle) { | |
476 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
477 KeyframedFloatAnimationCurve::Create()); | |
478 const int num_steps = 36; | |
479 const float steps_start_offset = 0.5f; | |
480 curve->AddKeyframe(FloatKeyframe::Create( | |
481 base::TimeDelta(), 0.f, | |
482 StepsTimingFunction::Create(num_steps, steps_start_offset))); | |
483 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
484 num_steps, nullptr)); | |
485 | |
486 const float time_threshold = 0.0001f; | |
487 | |
488 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta())); | |
489 for (float i = 0.5f; i < num_steps; i += 1.f) { | |
490 const base::TimeDelta time1 = | |
491 base::TimeDelta::FromSecondsD(i / num_steps - time_threshold); | |
492 const base::TimeDelta time2 = | |
493 base::TimeDelta::FromSecondsD(i / num_steps + time_threshold); | |
494 EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time1)); | |
495 EXPECT_FLOAT_EQ(std::floor(i) + 1.f, curve->GetValue(time2)); | |
496 } | |
497 EXPECT_FLOAT_EQ(num_steps, | |
498 curve->GetValue(base::TimeDelta::FromSecondsD(1.0))); | |
499 | |
500 for (float i = 0.25f; i <= num_steps; i += 1.0f) { | |
501 const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps); | |
502 EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time)); | |
503 } | |
504 } | |
505 | |
506 // Tests a step timing function if the change of values occur at the end. | |
507 TEST(KeyframedAnimationCurveTest, StepsTimingFunctionStepAtEnd) { | |
508 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
509 KeyframedFloatAnimationCurve::Create()); | |
510 const int num_steps = 36; | |
511 const float steps_start_offset = 0.0f; | |
512 curve->AddKeyframe(FloatKeyframe::Create( | |
513 base::TimeDelta(), 0.f, | |
514 StepsTimingFunction::Create(num_steps, steps_start_offset))); | |
515 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), | |
516 num_steps, nullptr)); | |
517 | |
518 const float time_threshold = 0.0001f; | |
519 | |
520 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta())); | |
521 for (float i = 1.f; i <= num_steps; i += 1.f) { | |
522 const base::TimeDelta time1 = | |
523 base::TimeDelta::FromSecondsD(i / num_steps - time_threshold); | |
524 const base::TimeDelta time2 = | |
525 base::TimeDelta::FromSecondsD(i / num_steps + time_threshold); | |
526 EXPECT_FLOAT_EQ(std::floor(i) - 1.f, curve->GetValue(time1)); | |
527 EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time2)); | |
528 } | |
529 EXPECT_FLOAT_EQ(num_steps, | |
530 curve->GetValue(base::TimeDelta::FromSecondsD(1.0))); | |
531 | |
532 for (float i = 0.5f; i <= num_steps; i += 1.0f) { | |
533 const base::TimeDelta time = base::TimeDelta::FromSecondsD(i / num_steps); | |
534 EXPECT_FLOAT_EQ(std::floor(i), curve->GetValue(time)); | |
535 } | |
536 } | |
537 | |
538 // Tests that animated bounds are computed as expected. | |
539 TEST(KeyframedAnimationCurveTest, AnimatedBounds) { | |
540 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
541 KeyframedTransformAnimationCurve::Create()); | |
542 | |
543 TransformOperations operations1; | |
544 curve->AddKeyframe( | |
545 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
546 operations1.AppendTranslate(2.0, 3.0, -1.0); | |
547 curve->AddKeyframe(TransformKeyframe::Create( | |
548 base::TimeDelta::FromSecondsD(0.5f), operations1, nullptr)); | |
549 TransformOperations operations2; | |
550 operations2.AppendTranslate(4.0, 1.0, 2.0); | |
551 curve->AddKeyframe( | |
552 TransformKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), operations2, | |
553 EaseTimingFunction::Create())); | |
554 | |
555 gfx::BoxF box(2.f, 3.f, 4.f, 1.f, 3.f, 2.f); | |
556 gfx::BoxF bounds; | |
557 | |
558 EXPECT_TRUE(curve->AnimatedBoundsForBox(box, &bounds)); | |
559 EXPECT_EQ(gfx::BoxF(2.f, 3.f, 3.f, 5.f, 6.f, 5.f).ToString(), | |
560 bounds.ToString()); | |
561 } | |
562 | |
563 // Tests that animations that affect scale are correctly identified. | |
564 TEST(KeyframedAnimationCurveTest, AffectsScale) { | |
565 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
566 KeyframedTransformAnimationCurve::Create()); | |
567 | |
568 TransformOperations operations1; | |
569 curve->AddKeyframe( | |
570 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
571 operations1.AppendTranslate(2.0, 3.0, -1.0); | |
572 TransformOperations operations2; | |
573 operations2.AppendTranslate(4.0, 1.0, 2.0); | |
574 curve->AddKeyframe(TransformKeyframe::Create( | |
575 base::TimeDelta::FromSecondsD(1.f), operations2, nullptr)); | |
576 | |
577 EXPECT_FALSE(curve->AffectsScale()); | |
578 | |
579 TransformOperations operations3; | |
580 operations3.AppendScale(2.f, 2.f, 2.f); | |
581 curve->AddKeyframe(TransformKeyframe::Create( | |
582 base::TimeDelta::FromSecondsD(2.f), operations3, nullptr)); | |
583 | |
584 EXPECT_TRUE(curve->AffectsScale()); | |
585 | |
586 TransformOperations operations4; | |
587 operations3.AppendTranslate(2.f, 2.f, 2.f); | |
588 curve->AddKeyframe(TransformKeyframe::Create( | |
589 base::TimeDelta::FromSecondsD(3.f), operations4, nullptr)); | |
590 | |
591 EXPECT_TRUE(curve->AffectsScale()); | |
592 } | |
593 | |
594 // Tests that animations that are translations are correctly identified. | |
595 TEST(KeyframedAnimationCurveTest, IsTranslation) { | |
596 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
597 KeyframedTransformAnimationCurve::Create()); | |
598 | |
599 TransformOperations operations1; | |
600 curve->AddKeyframe( | |
601 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
602 operations1.AppendTranslate(2.0, 3.0, -1.0); | |
603 TransformOperations operations2; | |
604 operations2.AppendTranslate(4.0, 1.0, 2.0); | |
605 curve->AddKeyframe(TransformKeyframe::Create( | |
606 base::TimeDelta::FromSecondsD(1.f), operations2, nullptr)); | |
607 | |
608 EXPECT_TRUE(curve->IsTranslation()); | |
609 | |
610 TransformOperations operations3; | |
611 operations3.AppendScale(2.f, 2.f, 2.f); | |
612 curve->AddKeyframe(TransformKeyframe::Create( | |
613 base::TimeDelta::FromSecondsD(2.f), operations3, nullptr)); | |
614 | |
615 EXPECT_FALSE(curve->IsTranslation()); | |
616 | |
617 TransformOperations operations4; | |
618 operations3.AppendTranslate(2.f, 2.f, 2.f); | |
619 curve->AddKeyframe(TransformKeyframe::Create( | |
620 base::TimeDelta::FromSecondsD(3.f), operations4, nullptr)); | |
621 | |
622 EXPECT_FALSE(curve->IsTranslation()); | |
623 } | |
624 | |
625 // Tests that maximum target scale is computed as expected. | |
626 TEST(KeyframedAnimationCurveTest, MaximumTargetScale) { | |
627 scoped_ptr<KeyframedTransformAnimationCurve> curve( | |
628 KeyframedTransformAnimationCurve::Create()); | |
629 | |
630 TransformOperations operations1; | |
631 curve->AddKeyframe( | |
632 TransformKeyframe::Create(base::TimeDelta(), operations1, nullptr)); | |
633 operations1.AppendScale(2.f, -3.f, 1.f); | |
634 curve->AddKeyframe( | |
635 TransformKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), operations1, | |
636 EaseTimingFunction::Create())); | |
637 | |
638 float maximum_scale = 0.f; | |
639 EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale)); | |
640 EXPECT_EQ(3.f, maximum_scale); | |
641 | |
642 TransformOperations operations2; | |
643 operations2.AppendScale(6.f, 3.f, 2.f); | |
644 curve->AddKeyframe( | |
645 TransformKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), operations2, | |
646 EaseTimingFunction::Create())); | |
647 | |
648 EXPECT_TRUE(curve->MaximumTargetScale(true, &maximum_scale)); | |
649 EXPECT_EQ(6.f, maximum_scale); | |
650 | |
651 TransformOperations operations3; | |
652 operations3.AppendRotate(1.f, 0.f, 0.f, 90.f); | |
653 curve->AddKeyframe( | |
654 TransformKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), operations3, | |
655 EaseTimingFunction::Create())); | |
656 | |
657 EXPECT_FALSE(curve->MaximumTargetScale(true, &maximum_scale)); | |
658 | |
659 // The original scale is not used in computing the max. | |
660 scoped_ptr<KeyframedTransformAnimationCurve> curve2( | |
661 KeyframedTransformAnimationCurve::Create()); | |
662 | |
663 TransformOperations operations4; | |
664 operations4.AppendScale(0.4f, 0.2f, 0.6f); | |
665 curve2->AddKeyframe(TransformKeyframe::Create(base::TimeDelta(), operations4, | |
666 EaseTimingFunction::Create())); | |
667 TransformOperations operations5; | |
668 operations5.AppendScale(0.5f, 0.3f, -0.8f); | |
669 curve2->AddKeyframe( | |
670 TransformKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), operations5, | |
671 EaseTimingFunction::Create())); | |
672 | |
673 EXPECT_TRUE(curve2->MaximumTargetScale(true, &maximum_scale)); | |
674 EXPECT_EQ(0.8f, maximum_scale); | |
675 | |
676 EXPECT_TRUE(curve2->MaximumTargetScale(false, &maximum_scale)); | |
677 EXPECT_EQ(0.6f, maximum_scale); | |
678 } | |
679 | |
680 // Tests that an animation with a curve timing function works as expected. | |
681 TEST(KeyframedAnimationCurveTest, CurveTiming) { | |
682 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
683 KeyframedFloatAnimationCurve::Create()); | |
684 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); | |
685 curve->AddKeyframe( | |
686 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr)); | |
687 curve->SetTimingFunction( | |
688 CubicBezierTimingFunction::Create(0.75f, 0.f, 0.25f, 1.f).Pass()); | |
689 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
690 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
691 EXPECT_NEAR(0.05f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)), | |
692 0.005f); | |
693 EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
694 EXPECT_NEAR(0.95f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)), | |
695 0.005f); | |
696 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
697 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
698 } | |
699 | |
700 // Tests that an animation with a curve and keyframe timing function works as | |
701 // expected. | |
702 TEST(KeyframedAnimationCurveTest, CurveAndKeyframeTiming) { | |
703 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
704 KeyframedFloatAnimationCurve::Create()); | |
705 curve->AddKeyframe(FloatKeyframe::Create( | |
706 base::TimeDelta(), 0.f, | |
707 CubicBezierTimingFunction::Create(0.35f, 0.f, 0.65f, 1.f).Pass())); | |
708 curve->AddKeyframe( | |
709 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr)); | |
710 // Curve timing function producing outputs outside of range [0,1]. | |
711 curve->SetTimingFunction( | |
712 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass()); | |
713 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
714 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
715 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD( | |
716 0.25f))); // Clamped. c(.25) < 0 | |
717 EXPECT_NEAR(0.17f, curve->GetValue(base::TimeDelta::FromSecondsD(0.42f)), | |
718 0.005f); // c(.42)=.27, k(.27)=.17 | |
719 EXPECT_FLOAT_EQ(0.5f, curve->GetValue(base::TimeDelta::FromSecondsD(0.5f))); | |
720 EXPECT_NEAR(0.83f, curve->GetValue(base::TimeDelta::FromSecondsD(0.58f)), | |
721 0.005f); // c(.58)=.73, k(.73)=.83 | |
722 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD( | |
723 0.75f))); // Clamped. c(.75) > 1 | |
724 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f))); | |
725 EXPECT_FLOAT_EQ(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
726 } | |
727 | |
728 // Tests that a linear timing function works as expected for inputs outside of | |
729 // range [0,1] | |
730 TEST(KeyframedAnimationCurveTest, LinearTimingInputsOutsideZeroOneRange) { | |
731 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
732 KeyframedFloatAnimationCurve::Create()); | |
733 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); | |
734 curve->AddKeyframe( | |
735 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr)); | |
736 // Curve timing function producing timing outputs outside of range [0,1]. | |
737 curve->SetTimingFunction( | |
738 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass()); | |
739 | |
740 EXPECT_NEAR(-0.076f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)), | |
741 0.001f); | |
742 EXPECT_NEAR(2.076f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)), | |
743 0.001f); | |
744 } | |
745 | |
746 // If a curve cubic-bezier timing function produces timing outputs outside | |
747 // the range [0, 1] then a keyframe cubic-bezier timing function | |
748 // should consume that input properly (using end-point gradients). | |
749 TEST(KeyframedAnimationCurveTest, CurveTimingInputsOutsideZeroOneRange) { | |
750 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
751 KeyframedFloatAnimationCurve::Create()); | |
752 // Keyframe timing function with 0.5 gradients at each end. | |
753 curve->AddKeyframe(FloatKeyframe::Create( | |
754 base::TimeDelta(), 0.f, | |
755 CubicBezierTimingFunction::Create(0.5f, 0.25f, 0.5f, 0.75f).Pass())); | |
756 curve->AddKeyframe( | |
757 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr)); | |
758 // Curve timing function producing timing outputs outside of range [0,1]. | |
759 curve->SetTimingFunction( | |
760 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass()); | |
761 | |
762 EXPECT_NEAR(-0.02f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f)), | |
763 0.002f); // c(.25)=-.04, -.04*0.5=-0.02 | |
764 EXPECT_NEAR(0.33f, curve->GetValue(base::TimeDelta::FromSecondsD(0.46f)), | |
765 0.002f); // c(.46)=.38, k(.38)=.33 | |
766 | |
767 EXPECT_NEAR(0.67f, curve->GetValue(base::TimeDelta::FromSecondsD(0.54f)), | |
768 0.002f); // c(.54)=.62, k(.62)=.67 | |
769 EXPECT_NEAR(1.02f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f)), | |
770 0.002f); // c(.75)=1.04 1+.04*0.5=1.02 | |
771 } | |
772 | |
773 // Tests that a step timing function works as expected for inputs outside of | |
774 // range [0,1] | |
775 TEST(KeyframedAnimationCurveTest, StepsTimingInputsOutsideZeroOneRange) { | |
776 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
777 KeyframedFloatAnimationCurve::Create()); | |
778 curve->AddKeyframe(FloatKeyframe::Create( | |
779 base::TimeDelta(), 0.f, StepsTimingFunction::Create(4, 0.5f))); | |
780 curve->AddKeyframe( | |
781 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 2.f, nullptr)); | |
782 // Curve timing function producing timing outputs outside of range [0,1]. | |
783 curve->SetTimingFunction( | |
784 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass()); | |
785 | |
786 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.25f))); | |
787 EXPECT_FLOAT_EQ(2.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.75f))); | |
788 } | |
789 | |
790 // Tests that an animation with a curve timing function and multiple keyframes | |
791 // works as expected. | |
792 TEST(KeyframedAnimationCurveTest, CurveTimingMultipleKeyframes) { | |
793 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
794 KeyframedFloatAnimationCurve::Create()); | |
795 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); | |
796 curve->AddKeyframe( | |
797 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.f), 1.f, nullptr)); | |
798 curve->AddKeyframe( | |
799 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.f), 3.f, nullptr)); | |
800 curve->AddKeyframe( | |
801 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.f), 6.f, nullptr)); | |
802 curve->AddKeyframe( | |
803 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.f), 9.f, nullptr)); | |
804 curve->SetTimingFunction( | |
805 CubicBezierTimingFunction::Create(0.5f, 0.f, 0.5f, 1.f).Pass()); | |
806 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(-1.f))); | |
807 EXPECT_FLOAT_EQ(0.f, curve->GetValue(base::TimeDelta::FromSecondsD(0.f))); | |
808 EXPECT_NEAR(0.42f, curve->GetValue(base::TimeDelta::FromSecondsD(1.f)), | |
809 0.005f); | |
810 EXPECT_NEAR(1.f, curve->GetValue(base::TimeDelta::FromSecondsD(1.455f)), | |
811 0.005f); | |
812 EXPECT_FLOAT_EQ(3.f, curve->GetValue(base::TimeDelta::FromSecondsD(2.f))); | |
813 EXPECT_NEAR(8.72f, curve->GetValue(base::TimeDelta::FromSecondsD(3.5f)), | |
814 0.01f); | |
815 EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(4.f))); | |
816 EXPECT_FLOAT_EQ(9.f, curve->GetValue(base::TimeDelta::FromSecondsD(5.f))); | |
817 } | |
818 | |
819 // Tests that an animation with a curve timing function that overshoots works as | |
820 // expected. | |
821 TEST(KeyframedAnimationCurveTest, CurveTimingOvershootMultipeKeyframes) { | |
822 scoped_ptr<KeyframedFloatAnimationCurve> curve( | |
823 KeyframedFloatAnimationCurve::Create()); | |
824 curve->AddKeyframe(FloatKeyframe::Create(base::TimeDelta(), 0.f, nullptr)); | |
825 curve->AddKeyframe( | |
826 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 1.f, nullptr)); | |
827 curve->AddKeyframe( | |
828 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(2.0), 3.f, nullptr)); | |
829 curve->AddKeyframe( | |
830 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(3.0), 6.f, nullptr)); | |
831 curve->AddKeyframe( | |
832 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(4.0), 9.f, nullptr)); | |
833 // Curve timing function producing outputs outside of range [0,1]. | |
834 curve->SetTimingFunction( | |
835 CubicBezierTimingFunction::Create(0.5f, -0.5f, 0.5f, 1.5f).Pass()); | |
836 EXPECT_LE(curve->GetValue(base::TimeDelta::FromSecondsD(1.f)), | |
837 0.f); // c(.25) < 0 | |
838 EXPECT_GE(curve->GetValue(base::TimeDelta::FromSecondsD(3.f)), | |
839 9.f); // c(.75) > 1 | |
840 } | |
841 | |
842 } // namespace | |
843 } // namespace cc | |
OLD | NEW |