keyframed_animation_curve.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/animation/keyframed_animation_curve.h"
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "ui/gfx/animation/tween.h"
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/gfx/box_f.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template <class Keyframe>
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InsertKeyframe(scoped_ptr<Keyframe> keyframe,
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    ScopedPtrVector<Keyframe>& keyframes) {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Usually, the keyframes will be added in order, so this loop would be
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // unnecessary and we should skip it if possible.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!keyframes.empty() && keyframe->Time() < keyframes.back()->Time()) {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (size_t i = 0; i < keyframes.size(); ++i) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (keyframe->Time() < keyframes[i]->Time()) {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        keyframes.insert(keyframes.begin() + i, keyframe.Pass());
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  keyframes.push_back(keyframe.Pass());
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template <class Keyframes>
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)float GetProgress(double t, size_t i, const Keyframes& keyframes) {
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float progress =
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      static_cast<float>((t - keyframes[i]->Time()) /
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                         (keyframes[i + 1]->Time() - keyframes[i]->Time()));
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (keyframes[i]->timing_function())
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    progress = keyframes[i]->timing_function()->GetValue(progress);
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return progress;
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<TimingFunction> CloneTimingFunction(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TimingFunction* timing_function) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(timing_function);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AnimationCurve> curve(timing_function->Clone());
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<TimingFunction>(
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      static_cast<TimingFunction*>(curve.release()));
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Keyframe::Keyframe(double time, scoped_ptr<TimingFunction> timing_function)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : time_(time),
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      timing_function_(timing_function.Pass()) {}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Keyframe::~Keyframe() {}
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)double Keyframe::Time() const {
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return time_;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<ColorKeyframe> ColorKeyframe::Create(
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    double time,
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    SkColor value,
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<TimingFunction> timing_function) {
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return make_scoped_ptr(
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      new ColorKeyframe(time, value, timing_function.Pass()));
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ColorKeyframe::ColorKeyframe(double time,
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             SkColor value,
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             scoped_ptr<TimingFunction> timing_function)
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : Keyframe(time, timing_function.Pass()),
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      value_(value) {}
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ColorKeyframe::~ColorKeyframe() {}
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)SkColor ColorKeyframe::Value() const { return value_; }
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<ColorKeyframe> ColorKeyframe::Clone() const {
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<TimingFunction> func;
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (timing_function())
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    func = CloneTimingFunction(timing_function());
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return ColorKeyframe::Create(Time(), Value(), func.Pass());
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<FloatKeyframe> FloatKeyframe::Create(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    double time,
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    float value,
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TimingFunction> timing_function) {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new FloatKeyframe(time, value, timing_function.Pass()));
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FloatKeyframe::FloatKeyframe(double time,
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             float value,
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             scoped_ptr<TimingFunction> timing_function)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : Keyframe(time, timing_function.Pass()),
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value_(value) {}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FloatKeyframe::~FloatKeyframe() {}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)float FloatKeyframe::Value() const {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return value_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<FloatKeyframe> FloatKeyframe::Clone() const {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TimingFunction> func;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (timing_function())
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    func = CloneTimingFunction(timing_function());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return FloatKeyframe::Create(Time(), Value(), func.Pass());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<TransformKeyframe> TransformKeyframe::Create(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    double time,
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const TransformOperations& value,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TimingFunction> timing_function) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new TransformKeyframe(time, value, timing_function.Pass()));
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TransformKeyframe::TransformKeyframe(double time,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     const TransformOperations& value,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     scoped_ptr<TimingFunction> timing_function)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : Keyframe(time, timing_function.Pass()),
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      value_(value) {}
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TransformKeyframe::~TransformKeyframe() {}
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const TransformOperations& TransformKeyframe::Value() const {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return value_;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<TransformKeyframe> TransformKeyframe::Clone() const {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<TimingFunction> func;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (timing_function())
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    func = CloneTimingFunction(timing_function());
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return TransformKeyframe::Create(Time(), Value(), func.Pass());
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<FilterKeyframe> FilterKeyframe::Create(
141ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    double time,
142ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const FilterOperations& value,
143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    scoped_ptr<TimingFunction> timing_function) {
144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return make_scoped_ptr(
145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      new FilterKeyframe(time, value, timing_function.Pass()));
146ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
147ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
148ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochFilterKeyframe::FilterKeyframe(double time,
149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               const FilterOperations& value,
150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               scoped_ptr<TimingFunction> timing_function)
151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    : Keyframe(time, timing_function.Pass()),
152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      value_(value) {}
153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochFilterKeyframe::~FilterKeyframe() {}
155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
156ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochconst FilterOperations& FilterKeyframe::Value() const {
157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return value_;
158ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
159ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
160ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<FilterKeyframe> FilterKeyframe::Clone() const {
161ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<TimingFunction> func;
162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (timing_function())
163ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    func = CloneTimingFunction(timing_function());
164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return FilterKeyframe::Create(Time(), Value(), func.Pass());
165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
166ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
1671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<KeyframedColorAnimationCurve> KeyframedColorAnimationCurve::
1681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    Create() {
1691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return make_scoped_ptr(new KeyframedColorAnimationCurve);
1701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)KeyframedColorAnimationCurve::KeyframedColorAnimationCurve() {}
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)KeyframedColorAnimationCurve::~KeyframedColorAnimationCurve() {}
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void KeyframedColorAnimationCurve::AddKeyframe(
1771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    scoped_ptr<ColorKeyframe> keyframe) {
1781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  InsertKeyframe(keyframe.Pass(), keyframes_);
1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)double KeyframedColorAnimationCurve::Duration() const {
1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return keyframes_.back()->Time() - keyframes_.front()->Time();
1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)scoped_ptr<AnimationCurve> KeyframedColorAnimationCurve::Clone() const {
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  scoped_ptr<KeyframedColorAnimationCurve> to_return(
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      KeyframedColorAnimationCurve::Create());
1881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (size_t i = 0; i < keyframes_.size(); ++i)
1891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    to_return->AddKeyframe(keyframes_[i]->Clone());
1901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return to_return.PassAs<AnimationCurve>();
1911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)SkColor KeyframedColorAnimationCurve::GetValue(double t) const {
1941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (t <= keyframes_.front()->Time())
1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return keyframes_.front()->Value();
1961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (t >= keyframes_.back()->Time())
1981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return keyframes_.back()->Value();
1991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t i = 0;
2011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  for (; i < keyframes_.size() - 1; ++i) {
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (t < keyframes_[i + 1]->Time())
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      break;
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float progress = GetProgress(t, i, keyframes_);
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return gfx::Tween::ColorValueBetween(
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      progress, keyframes_[i]->Value(), keyframes_[i + 1]->Value());
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// KeyframedFloatAnimationCurve
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<KeyframedFloatAnimationCurve> KeyframedFloatAnimationCurve::
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Create() {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(new KeyframedFloatAnimationCurve);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KeyframedFloatAnimationCurve::KeyframedFloatAnimationCurve() {}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KeyframedFloatAnimationCurve::~KeyframedFloatAnimationCurve() {}
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KeyframedFloatAnimationCurve::AddKeyframe(
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<FloatKeyframe> keyframe) {
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InsertKeyframe(keyframe.Pass(), keyframes_);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)double KeyframedFloatAnimationCurve::Duration() const {
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return keyframes_.back()->Time() - keyframes_.front()->Time();
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<AnimationCurve> KeyframedFloatAnimationCurve::Clone() const {
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<KeyframedFloatAnimationCurve> to_return(
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      KeyframedFloatAnimationCurve::Create());
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < keyframes_.size(); ++i)
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    to_return->AddKeyframe(keyframes_[i]->Clone());
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return to_return.PassAs<AnimationCurve>();
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)float KeyframedFloatAnimationCurve::GetValue(double t) const {
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (t <= keyframes_.front()->Time())
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return keyframes_.front()->Value();
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (t >= keyframes_.back()->Time())
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return keyframes_.back()->Value();
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t i = 0;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (; i < keyframes_.size() - 1; ++i) {
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (t < keyframes_[i+1]->Time())
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  float progress = GetProgress(t, i, keyframes_);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return keyframes_[i]->Value() +
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (keyframes_[i+1]->Value() - keyframes_[i]->Value()) * progress;
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<KeyframedTransformAnimationCurve> KeyframedTransformAnimationCurve::
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Create() {
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return make_scoped_ptr(new KeyframedTransformAnimationCurve);
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KeyframedTransformAnimationCurve::KeyframedTransformAnimationCurve() {}
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)KeyframedTransformAnimationCurve::~KeyframedTransformAnimationCurve() {}
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void KeyframedTransformAnimationCurve::AddKeyframe(
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<TransformKeyframe> keyframe) {
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InsertKeyframe(keyframe.Pass(), keyframes_);
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)double KeyframedTransformAnimationCurve::Duration() const {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return keyframes_.back()->Time() - keyframes_.front()->Time();
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<AnimationCurve> KeyframedTransformAnimationCurve::Clone() const {
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<KeyframedTransformAnimationCurve> to_return(
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      KeyframedTransformAnimationCurve::Create());
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < keyframes_.size(); ++i)
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    to_return->AddKeyframe(keyframes_[i]->Clone());
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return to_return.PassAs<AnimationCurve>();
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
285ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Assumes that (*keyframes).front()->Time() < t < (*keyframes).back()-Time().
286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochtemplate<typename ValueType, typename KeyframeType>
287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic ValueType GetCurveValue(const ScopedPtrVector<KeyframeType>* keyframes,
288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                               double t) {
289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  size_t i = 0;
290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for (; i < keyframes->size() - 1; ++i) {
291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    if (t < (*keyframes)[i+1]->Time())
292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      break;
293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
295ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  double progress = (t - (*keyframes)[i]->Time()) /
296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                    ((*keyframes)[i+1]->Time() - (*keyframes)[i]->Time());
297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
298ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if ((*keyframes)[i]->timing_function())
299ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    progress = (*keyframes)[i]->timing_function()->GetValue(progress);
300ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
301ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return (*keyframes)[i+1]->Value().Blend((*keyframes)[i]->Value(), progress);
302ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
303ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::Transform KeyframedTransformAnimationCurve::GetValue(double t) const {
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (t <= keyframes_.front()->Time())
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return keyframes_.front()->Value().Apply();
3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (t >= keyframes_.back()->Time())
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return keyframes_.back()->Value().Apply();
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
311ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return GetCurveValue<gfx::Transform, TransformKeyframe>(&keyframes_, t);
312ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool KeyframedTransformAnimationCurve::AnimatedBoundsForBox(
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const gfx::BoxF& box,
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gfx::BoxF* bounds) const {
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK_GE(keyframes_.size(), 2ul);
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  *bounds = gfx::BoxF();
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < keyframes_.size() - 1; ++i) {
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    gfx::BoxF bounds_for_step;
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    float min_progress = 0.0;
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    float max_progress = 1.0;
3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (keyframes_[i]->timing_function())
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      keyframes_[i]->timing_function()->Range(&min_progress, &max_progress);
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (!keyframes_[i+1]->Value().BlendedBoundsForBox(box,
3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                      keyframes_[i]->Value(),
3273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                      min_progress,
3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                      max_progress,
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                      &bounds_for_step))
3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      return false;
3313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bounds->Union(bounds_for_step);
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
3333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return true;
3343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
336e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool KeyframedTransformAnimationCurve::AffectsScale() const {
337e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  for (size_t i = 0; i < keyframes_.size(); ++i) {
338e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    if (keyframes_[i]->Value().AffectsScale())
339e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      return true;
340e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
341e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  return false;
342e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}
343e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
344ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<KeyframedFilterAnimationCurve> KeyframedFilterAnimationCurve::
345ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    Create() {
346ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return make_scoped_ptr(new KeyframedFilterAnimationCurve);
347ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
349ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochKeyframedFilterAnimationCurve::KeyframedFilterAnimationCurve() {}
350ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
351ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochKeyframedFilterAnimationCurve::~KeyframedFilterAnimationCurve() {}
352ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
353ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid KeyframedFilterAnimationCurve::AddKeyframe(
354ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    scoped_ptr<FilterKeyframe> keyframe) {
355ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  InsertKeyframe(keyframe.Pass(), keyframes_);
356ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
357ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
358ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochdouble KeyframedFilterAnimationCurve::Duration() const {
359ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return keyframes_.back()->Time() - keyframes_.front()->Time();
360ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
361ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
362ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochscoped_ptr<AnimationCurve> KeyframedFilterAnimationCurve::Clone() const {
363ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  scoped_ptr<KeyframedFilterAnimationCurve> to_return(
364ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      KeyframedFilterAnimationCurve::Create());
365ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  for (size_t i = 0; i < keyframes_.size(); ++i)
366ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    to_return->AddKeyframe(keyframes_[i]->Clone());
367ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return to_return.PassAs<AnimationCurve>();
368ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}
369ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochFilterOperations KeyframedFilterAnimationCurve::GetValue(double t) const {
371ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (t <= keyframes_.front()->Time())
372ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return keyframes_.front()->Value();
373ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
374ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (t >= keyframes_.back()->Time())
375ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    return keyframes_.back()->Value();
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  return GetCurveValue<FilterOperations, FilterKeyframe>(&keyframes_, t);
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool KeyframedFilterAnimationCurve::HasFilterThatMovesPixels() const {
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < keyframes_.size(); ++i) {
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (keyframes_[i]->Value().HasFilterThatMovesPixels()) {
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return true;
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return false;
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
390