Home | History | Annotate | Download | only in animation
      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 
     11 namespace cc {
     12 namespace {
     13 
     14 void ExpectTranslateX(double translate_x, const gfx::Transform& transform) {
     15   EXPECT_FLOAT_EQ(translate_x, transform.matrix().getDouble(0, 3));
     16 }
     17 
     18 void ExpectBrightness(double brightness, const FilterOperations& filter) {
     19   EXPECT_EQ(1u, filter.size());
     20   EXPECT_EQ(FilterOperation::BRIGHTNESS, filter.at(0).type());
     21   EXPECT_FLOAT_EQ(brightness, filter.at(0).amount());
     22 }
     23 
     24 // Tests that a float animation with one keyframe works as expected.
     25 TEST(KeyframedAnimationCurveTest, OneFloatKeyframe) {
     26   scoped_ptr<KeyframedFloatAnimationCurve> curve(
     27       KeyframedFloatAnimationCurve::Create());
     28   curve->AddKeyframe(
     29       FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
     30   EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
     31   EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
     32   EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.5f));
     33   EXPECT_FLOAT_EQ(2.f, curve->GetValue(1.f));
     34   EXPECT_FLOAT_EQ(2.f, curve->GetValue(2.f));
     35 }
     36 
     37 // Tests that a float animation with two keyframes works as expected.
     38 TEST(KeyframedAnimationCurveTest, TwoFloatKeyframe) {
     39   scoped_ptr<KeyframedFloatAnimationCurve> curve(
     40       KeyframedFloatAnimationCurve::Create());
     41   curve->AddKeyframe(
     42       FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
     43   curve->AddKeyframe(
     44       FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
     45   EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
     46   EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
     47   EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
     48   EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
     49   EXPECT_FLOAT_EQ(4.f, curve->GetValue(2.f));
     50 }
     51 
     52 // Tests that a float animation with three keyframes works as expected.
     53 TEST(KeyframedAnimationCurveTest, ThreeFloatKeyframe) {
     54   scoped_ptr<KeyframedFloatAnimationCurve> curve(
     55       KeyframedFloatAnimationCurve::Create());
     56   curve->AddKeyframe(
     57       FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
     58   curve->AddKeyframe(
     59       FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
     60   curve->AddKeyframe(
     61       FloatKeyframe::Create(2.0, 8.f, scoped_ptr<TimingFunction>()));
     62   EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
     63   EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
     64   EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
     65   EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
     66   EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
     67   EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f));
     68   EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f));
     69 }
     70 
     71 // Tests that a float animation with multiple keys at a given time works sanely.
     72 TEST(KeyframedAnimationCurveTest, RepeatedFloatKeyTimes) {
     73   scoped_ptr<KeyframedFloatAnimationCurve> curve(
     74       KeyframedFloatAnimationCurve::Create());
     75   curve->AddKeyframe(
     76       FloatKeyframe::Create(0.0, 4.f, scoped_ptr<TimingFunction>()));
     77   curve->AddKeyframe(
     78       FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
     79   curve->AddKeyframe(
     80       FloatKeyframe::Create(1.0, 6.f, scoped_ptr<TimingFunction>()));
     81   curve->AddKeyframe(
     82       FloatKeyframe::Create(2.0, 6.f, scoped_ptr<TimingFunction>()));
     83 
     84   EXPECT_FLOAT_EQ(4.f, curve->GetValue(-1.f));
     85   EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.f));
     86   EXPECT_FLOAT_EQ(4.f, curve->GetValue(0.5f));
     87 
     88   // There is a discontinuity at 1. Any value between 4 and 6 is valid.
     89   float value = curve->GetValue(1.f);
     90   EXPECT_TRUE(value >= 4 && value <= 6);
     91 
     92   EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
     93   EXPECT_FLOAT_EQ(6.f, curve->GetValue(2.f));
     94   EXPECT_FLOAT_EQ(6.f, curve->GetValue(3.f));
     95 }
     96 
     97 // Tests that a transform animation with one keyframe works as expected.
     98 TEST(KeyframedAnimationCurveTest, OneTransformKeyframe) {
     99   scoped_ptr<KeyframedTransformAnimationCurve> curve(
    100       KeyframedTransformAnimationCurve::Create());
    101   TransformOperations operations;
    102   operations.AppendTranslate(2.f, 0.f, 0.f);
    103   curve->AddKeyframe(
    104       TransformKeyframe::Create(0.f, operations, scoped_ptr<TimingFunction>()));
    105 
    106   ExpectTranslateX(2.f, curve->GetValue(-1.f));
    107   ExpectTranslateX(2.f, curve->GetValue(0.f));
    108   ExpectTranslateX(2.f, curve->GetValue(0.5f));
    109   ExpectTranslateX(2.f, curve->GetValue(1.f));
    110   ExpectTranslateX(2.f, curve->GetValue(2.f));
    111 }
    112 
    113 // Tests that a transform animation with two keyframes works as expected.
    114 TEST(KeyframedAnimationCurveTest, TwoTransformKeyframe) {
    115   scoped_ptr<KeyframedTransformAnimationCurve> curve(
    116       KeyframedTransformAnimationCurve::Create());
    117   TransformOperations operations1;
    118   operations1.AppendTranslate(2.f, 0.f, 0.f);
    119   TransformOperations operations2;
    120   operations2.AppendTranslate(4.f, 0.f, 0.f);
    121 
    122   curve->AddKeyframe(TransformKeyframe::Create(
    123       0.f, operations1, scoped_ptr<TimingFunction>()));
    124   curve->AddKeyframe(TransformKeyframe::Create(
    125       1.f, operations2, scoped_ptr<TimingFunction>()));
    126   ExpectTranslateX(2.f, curve->GetValue(-1.f));
    127   ExpectTranslateX(2.f, curve->GetValue(0.f));
    128   ExpectTranslateX(3.f, curve->GetValue(0.5f));
    129   ExpectTranslateX(4.f, curve->GetValue(1.f));
    130   ExpectTranslateX(4.f, curve->GetValue(2.f));
    131 }
    132 
    133 // Tests that a transform animation with three keyframes works as expected.
    134 TEST(KeyframedAnimationCurveTest, ThreeTransformKeyframe) {
    135   scoped_ptr<KeyframedTransformAnimationCurve> curve(
    136       KeyframedTransformAnimationCurve::Create());
    137   TransformOperations operations1;
    138   operations1.AppendTranslate(2.f, 0.f, 0.f);
    139   TransformOperations operations2;
    140   operations2.AppendTranslate(4.f, 0.f, 0.f);
    141   TransformOperations operations3;
    142   operations3.AppendTranslate(8.f, 0.f, 0.f);
    143   curve->AddKeyframe(TransformKeyframe::Create(
    144       0.f, operations1, scoped_ptr<TimingFunction>()));
    145   curve->AddKeyframe(TransformKeyframe::Create(
    146       1.f, operations2, scoped_ptr<TimingFunction>()));
    147   curve->AddKeyframe(TransformKeyframe::Create(
    148       2.f, operations3, scoped_ptr<TimingFunction>()));
    149   ExpectTranslateX(2.f, curve->GetValue(-1.f));
    150   ExpectTranslateX(2.f, curve->GetValue(0.f));
    151   ExpectTranslateX(3.f, curve->GetValue(0.5f));
    152   ExpectTranslateX(4.f, curve->GetValue(1.f));
    153   ExpectTranslateX(6.f, curve->GetValue(1.5f));
    154   ExpectTranslateX(8.f, curve->GetValue(2.f));
    155   ExpectTranslateX(8.f, curve->GetValue(3.f));
    156 }
    157 
    158 // Tests that a transform animation with multiple keys at a given time works
    159 // sanely.
    160 TEST(KeyframedAnimationCurveTest, RepeatedTransformKeyTimes) {
    161   scoped_ptr<KeyframedTransformAnimationCurve> curve(
    162       KeyframedTransformAnimationCurve::Create());
    163   // A step function.
    164   TransformOperations operations1;
    165   operations1.AppendTranslate(4.f, 0.f, 0.f);
    166   TransformOperations operations2;
    167   operations2.AppendTranslate(4.f, 0.f, 0.f);
    168   TransformOperations operations3;
    169   operations3.AppendTranslate(6.f, 0.f, 0.f);
    170   TransformOperations operations4;
    171   operations4.AppendTranslate(6.f, 0.f, 0.f);
    172   curve->AddKeyframe(TransformKeyframe::Create(
    173       0.f, operations1, scoped_ptr<TimingFunction>()));
    174   curve->AddKeyframe(TransformKeyframe::Create(
    175       1.f, operations2, scoped_ptr<TimingFunction>()));
    176   curve->AddKeyframe(TransformKeyframe::Create(
    177       1.f, operations3, scoped_ptr<TimingFunction>()));
    178   curve->AddKeyframe(TransformKeyframe::Create(
    179       2.f, operations4, scoped_ptr<TimingFunction>()));
    180 
    181   ExpectTranslateX(4.f, curve->GetValue(-1.f));
    182   ExpectTranslateX(4.f, curve->GetValue(0.f));
    183   ExpectTranslateX(4.f, curve->GetValue(0.5f));
    184 
    185   // There is a discontinuity at 1. Any value between 4 and 6 is valid.
    186   gfx::Transform value = curve->GetValue(1.f);
    187   EXPECT_GE(value.matrix().getDouble(0.f, 3.f), 4);
    188   EXPECT_LE(value.matrix().getDouble(0.f, 3.f), 6);
    189 
    190   ExpectTranslateX(6.f, curve->GetValue(1.5f));
    191   ExpectTranslateX(6.f, curve->GetValue(2.f));
    192   ExpectTranslateX(6.f, curve->GetValue(3.f));
    193 }
    194 
    195 // Tests that a filter animation with one keyframe works as expected.
    196 TEST(KeyframedAnimationCurveTest, OneFilterKeyframe) {
    197   scoped_ptr<KeyframedFilterAnimationCurve> curve(
    198       KeyframedFilterAnimationCurve::Create());
    199   FilterOperations operations;
    200   operations.Append(FilterOperation::CreateBrightnessFilter(2.f));
    201   curve->AddKeyframe(
    202       FilterKeyframe::Create(0.f, operations, scoped_ptr<TimingFunction>()));
    203 
    204   ExpectBrightness(2.f, curve->GetValue(-1.f));
    205   ExpectBrightness(2.f, curve->GetValue(0.f));
    206   ExpectBrightness(2.f, curve->GetValue(0.5f));
    207   ExpectBrightness(2.f, curve->GetValue(1.f));
    208   ExpectBrightness(2.f, curve->GetValue(2.f));
    209 }
    210 
    211 // Tests that a filter animation with two keyframes works as expected.
    212 TEST(KeyframedAnimationCurveTest, TwoFilterKeyframe) {
    213   scoped_ptr<KeyframedFilterAnimationCurve> curve(
    214       KeyframedFilterAnimationCurve::Create());
    215   FilterOperations operations1;
    216   operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
    217   FilterOperations operations2;
    218   operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
    219 
    220   curve->AddKeyframe(FilterKeyframe::Create(
    221       0.f, operations1, scoped_ptr<TimingFunction>()));
    222   curve->AddKeyframe(FilterKeyframe::Create(
    223       1.f, operations2, scoped_ptr<TimingFunction>()));
    224   ExpectBrightness(2.f, curve->GetValue(-1.f));
    225   ExpectBrightness(2.f, curve->GetValue(0.f));
    226   ExpectBrightness(3.f, curve->GetValue(0.5f));
    227   ExpectBrightness(4.f, curve->GetValue(1.f));
    228   ExpectBrightness(4.f, curve->GetValue(2.f));
    229 }
    230 
    231 // Tests that a filter animation with three keyframes works as expected.
    232 TEST(KeyframedAnimationCurveTest, ThreeFilterKeyframe) {
    233   scoped_ptr<KeyframedFilterAnimationCurve> curve(
    234       KeyframedFilterAnimationCurve::Create());
    235   FilterOperations operations1;
    236   operations1.Append(FilterOperation::CreateBrightnessFilter(2.f));
    237   FilterOperations operations2;
    238   operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
    239   FilterOperations operations3;
    240   operations3.Append(FilterOperation::CreateBrightnessFilter(8.f));
    241   curve->AddKeyframe(FilterKeyframe::Create(
    242       0.f, operations1, scoped_ptr<TimingFunction>()));
    243   curve->AddKeyframe(FilterKeyframe::Create(
    244       1.f, operations2, scoped_ptr<TimingFunction>()));
    245   curve->AddKeyframe(FilterKeyframe::Create(
    246       2.f, operations3, scoped_ptr<TimingFunction>()));
    247   ExpectBrightness(2.f, curve->GetValue(-1.f));
    248   ExpectBrightness(2.f, curve->GetValue(0.f));
    249   ExpectBrightness(3.f, curve->GetValue(0.5f));
    250   ExpectBrightness(4.f, curve->GetValue(1.f));
    251   ExpectBrightness(6.f, curve->GetValue(1.5f));
    252   ExpectBrightness(8.f, curve->GetValue(2.f));
    253   ExpectBrightness(8.f, curve->GetValue(3.f));
    254 }
    255 
    256 // Tests that a filter animation with multiple keys at a given time works
    257 // sanely.
    258 TEST(KeyframedAnimationCurveTest, RepeatedFilterKeyTimes) {
    259   scoped_ptr<KeyframedFilterAnimationCurve> curve(
    260       KeyframedFilterAnimationCurve::Create());
    261   // A step function.
    262   FilterOperations operations1;
    263   operations1.Append(FilterOperation::CreateBrightnessFilter(4.f));
    264   FilterOperations operations2;
    265   operations2.Append(FilterOperation::CreateBrightnessFilter(4.f));
    266   FilterOperations operations3;
    267   operations3.Append(FilterOperation::CreateBrightnessFilter(6.f));
    268   FilterOperations operations4;
    269   operations4.Append(FilterOperation::CreateBrightnessFilter(6.f));
    270   curve->AddKeyframe(FilterKeyframe::Create(
    271       0.f, operations1, scoped_ptr<TimingFunction>()));
    272   curve->AddKeyframe(FilterKeyframe::Create(
    273       1.f, operations2, scoped_ptr<TimingFunction>()));
    274   curve->AddKeyframe(FilterKeyframe::Create(
    275       1.f, operations3, scoped_ptr<TimingFunction>()));
    276   curve->AddKeyframe(FilterKeyframe::Create(
    277       2.f, operations4, scoped_ptr<TimingFunction>()));
    278 
    279   ExpectBrightness(4.f, curve->GetValue(-1.f));
    280   ExpectBrightness(4.f, curve->GetValue(0.f));
    281   ExpectBrightness(4.f, curve->GetValue(0.5f));
    282 
    283   // There is a discontinuity at 1. Any value between 4 and 6 is valid.
    284   FilterOperations value = curve->GetValue(1.f);
    285   EXPECT_EQ(1u, value.size());
    286   EXPECT_EQ(FilterOperation::BRIGHTNESS, value.at(0).type());
    287   EXPECT_GE(value.at(0).amount(), 4);
    288   EXPECT_LE(value.at(0).amount(), 6);
    289 
    290   ExpectBrightness(6.f, curve->GetValue(1.5f));
    291   ExpectBrightness(6.f, curve->GetValue(2.f));
    292   ExpectBrightness(6.f, curve->GetValue(3.f));
    293 }
    294 
    295 // Tests that the keyframes may be added out of order.
    296 TEST(KeyframedAnimationCurveTest, UnsortedKeyframes) {
    297   scoped_ptr<KeyframedFloatAnimationCurve> curve(
    298       KeyframedFloatAnimationCurve::Create());
    299   curve->AddKeyframe(
    300       FloatKeyframe::Create(2.0, 8.f, scoped_ptr<TimingFunction>()));
    301   curve->AddKeyframe(
    302       FloatKeyframe::Create(0.0, 2.f, scoped_ptr<TimingFunction>()));
    303   curve->AddKeyframe(
    304       FloatKeyframe::Create(1.0, 4.f, scoped_ptr<TimingFunction>()));
    305   EXPECT_FLOAT_EQ(2.f, curve->GetValue(-1.f));
    306   EXPECT_FLOAT_EQ(2.f, curve->GetValue(0.f));
    307   EXPECT_FLOAT_EQ(3.f, curve->GetValue(0.5f));
    308   EXPECT_FLOAT_EQ(4.f, curve->GetValue(1.f));
    309   EXPECT_FLOAT_EQ(6.f, curve->GetValue(1.5f));
    310   EXPECT_FLOAT_EQ(8.f, curve->GetValue(2.f));
    311   EXPECT_FLOAT_EQ(8.f, curve->GetValue(3.f));
    312 }
    313 
    314 // Tests that a cubic bezier timing function works as expected.
    315 TEST(KeyframedAnimationCurveTest, CubicBezierTimingFunction) {
    316   scoped_ptr<KeyframedFloatAnimationCurve> curve(
    317       KeyframedFloatAnimationCurve::Create());
    318   curve->AddKeyframe(FloatKeyframe::Create(
    319       0.0,
    320       0.f,
    321       CubicBezierTimingFunction::Create(0.25f, 0.f, 0.75f, 1.f)
    322           .PassAs<TimingFunction>()));
    323   curve->AddKeyframe(
    324       FloatKeyframe::Create(1.0, 1.f, scoped_ptr<TimingFunction>()));
    325 
    326   EXPECT_FLOAT_EQ(0.f, curve->GetValue(0.f));
    327   EXPECT_LT(0.f, curve->GetValue(0.25f));
    328   EXPECT_GT(0.25f, curve->GetValue(0.25f));
    329   EXPECT_NEAR(curve->GetValue(0.5f), 0.5f, 0.00015f);
    330   EXPECT_LT(0.75f, curve->GetValue(0.75f));
    331   EXPECT_GT(1.f, curve->GetValue(0.75f));
    332   EXPECT_FLOAT_EQ(1.f, curve->GetValue(1.f));
    333 }
    334 
    335 }  // namespace
    336 }  // namespace cc
    337