1 // Copyright (c) 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.
5 #include "ui/gfx/animation/tween.h"
15 #include "base/basictypes.h"
16 #include "base/logging.h"
17 #include "base/numerics/safe_conversions.h"
18 #include "ui/gfx/geometry/cubic_bezier.h"
19 #include "ui/gfx/safe_integer_conversions.h"
24 double Tween::CalculateValue(Tween::Type type
, double state
) {
37 return pow(state
* 2, 2) / 2.0;
38 return 1.0 - (pow((state
- 1.0) * 2, 2) / 2.0);
41 return (pow(state
- 0.5, 3) + 0.125) / 0.25;
47 state
= 0.95 * (1.0 - pow(1.0 - state
, 2));
51 return 1.0 - pow(1.0 - state
, 2);
56 case FAST_OUT_SLOW_IN
:
57 return gfx::CubicBezier(0.4, 0, 0.2, 1).Solve(state
);
59 case LINEAR_OUT_SLOW_IN
:
60 return gfx::CubicBezier(0, 0, .2, 1).Solve(state
);
62 case FAST_OUT_LINEAR_IN
:
63 return gfx::CubicBezier(0.4, 0, 1, 1).Solve(state
);
74 uint8
FloatToColorByte(float f
) {
75 return base::saturated_cast
<uint8
>(ToRoundedInt(f
* 255.f
));
78 uint8
BlendColorComponents(uint8 start
,
84 // Since progress can be outside [0, 1], blending can produce a value outside
86 float blended_premultiplied
= Tween::FloatValueBetween(
87 progress
, start
/ 255.f
* start_alpha
, target
/ 255.f
* target_alpha
);
88 return FloatToColorByte(blended_premultiplied
/ blended_alpha
);
94 SkColor
Tween::ColorValueBetween(double value
, SkColor start
, SkColor target
) {
95 float start_a
= SkColorGetA(start
) / 255.f
;
96 float target_a
= SkColorGetA(target
) / 255.f
;
97 float blended_a
= FloatValueBetween(value
, start_a
, target_a
);
99 return SkColorSetARGB(0, 0, 0, 0);
100 blended_a
= std::min(blended_a
, 1.f
);
102 uint8 blended_r
= BlendColorComponents(SkColorGetR(start
),
108 uint8 blended_g
= BlendColorComponents(SkColorGetG(start
),
114 uint8 blended_b
= BlendColorComponents(SkColorGetB(start
),
121 return SkColorSetARGB(
122 FloatToColorByte(blended_a
), blended_r
, blended_g
, blended_b
);
126 double Tween::DoubleValueBetween(double value
, double start
, double target
) {
127 return start
+ (target
- start
) * value
;
131 float Tween::FloatValueBetween(double value
, float start
, float target
) {
132 return static_cast<float>(start
+ (target
- start
) * value
);
136 int Tween::IntValueBetween(double value
, int start
, int target
) {
139 double delta
= static_cast<double>(target
- start
);
145 return start
+ static_cast<int>(value
* _nextafter(delta
, 0));
147 return start
+ static_cast<int>(value
* nextafter(delta
, 0));
152 int Tween::LinearIntValueBetween(double value
, int start
, int target
) {
153 // NOTE: Do not use ToRoundedInt()! See comments on function declaration.
154 return ToFlooredInt(0.5 + DoubleValueBetween(value
, start
, target
));
158 gfx::Rect
Tween::RectValueBetween(double value
,
159 const gfx::Rect
& start_bounds
,
160 const gfx::Rect
& target_bounds
) {
162 LinearIntValueBetween(value
, start_bounds
.x(), target_bounds
.x()),
163 LinearIntValueBetween(value
, start_bounds
.y(), target_bounds
.y()),
164 LinearIntValueBetween(value
, start_bounds
.width(), target_bounds
.width()),
165 LinearIntValueBetween(
166 value
, start_bounds
.height(), target_bounds
.height()));
170 gfx::Transform
Tween::TransformValueBetween(
172 const gfx::Transform
& start_transform
,
173 const gfx::Transform
& end_transform
) {
175 return end_transform
;
177 return start_transform
;
179 gfx::Transform to_return
= end_transform
;
180 to_return
.Blend(start_transform
, value
);