Skip to content

Commit

Permalink
Reland: ash: Make cross-fade duration based on area, not width
Browse files Browse the repository at this point in the history
This better corresponds with the user's notion of the visual impact of the change, especially for animations where the width doesn't change much.

BUG=none
TEST=updated unit tests

Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=142773

Reverted: http://src.chromium.org/viewvc/chrome?view=rev&revision=142781


Review URL: https://chromiumcodereview.appspot.com/10561031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@142860 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
jamescook@chromium.org committed Jun 18, 2012
1 parent e152ebd commit 117410d
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 28 deletions.
26 changes: 14 additions & 12 deletions ash/wm/window_animations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ namespace {
const int kDefaultAnimationDurationForMenuMS = 150;

// Durations for the cross-fade animation, in milliseconds.
const float kCrossFadeDurationMinMs = 200.f;
const float kCrossFadeDurationMinMs = 100.f;
const float kCrossFadeDurationMaxMs = 400.f;

const float kWindowAnimation_HideOpacity = 0.f;
Expand Down Expand Up @@ -649,16 +649,14 @@ ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver(
return new internal::HidingWindowAnimationObserver(window);
}

namespace internal {

void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds) {
DCHECK(window->TargetVisibility());
gfx::Rect old_bounds = window->bounds();

// Create fresh layers for the window and all its children to paint into.
// Takes ownership of the old layer and all its children, which will be
// cleaned up after the animation completes.
ui::Layer* old_layer = RecreateWindowLayers(window);
ui::Layer* old_layer = internal::RecreateWindowLayers(window);
ui::Layer* new_layer = window->layer();

// Ensure the higher-resolution layer is on top.
Expand All @@ -672,12 +670,12 @@ void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds) {
// aligned during the animation.
const ui::Tween::Type kTransformTween = ui::Tween::EASE_OUT;
// Shorten the animation if there's not much visual movement.
TimeDelta duration = GetCrossFadeDuration(old_bounds, new_bounds);
TimeDelta duration = internal::GetCrossFadeDuration(old_bounds, new_bounds);
{
// Scale up the old layer while translating to new position.
ui::ScopedLayerAnimationSettings settings(old_layer->GetAnimator());
// Animation observer owns the old layer and deletes itself.
settings.AddObserver(new CrossFadeObserver(window, old_layer));
settings.AddObserver(new internal::CrossFadeObserver(window, old_layer));
settings.SetTransitionDuration(duration);
settings.SetTweenType(kTransformTween);
ui::Transform out_transform;
Expand Down Expand Up @@ -730,20 +728,24 @@ void CrossFadeToBounds(aura::Window* window, const gfx::Rect& new_bounds) {
}
}

namespace internal {

TimeDelta GetCrossFadeDuration(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
int max_width = std::max(old_bounds.width(), new_bounds.width());
int old_area = old_bounds.width() * old_bounds.height();
int new_area = new_bounds.width() * new_bounds.height();
int max_area = std::max(old_area, new_area);
// Avoid divide by zero.
if (max_width == 0)
if (max_area == 0)
return TimeDelta();

int delta_width = std::abs(old_bounds.width() - new_bounds.width());
// If the width didn't change, the animation is instantaneous.
if (delta_width == 0)
int delta_area = std::abs(old_area - new_area);
// If the area didn't change, the animation is instantaneous.
if (delta_area == 0)
return TimeDelta();

float factor =
static_cast<float>(delta_width) / static_cast<float>(max_width);
static_cast<float>(delta_area) / static_cast<float>(max_area);
const float kRange = kCrossFadeDurationMaxMs - kCrossFadeDurationMinMs;
return TimeDelta::FromMilliseconds(
Round64(kCrossFadeDurationMinMs + (factor * kRange)));
Expand Down
4 changes: 2 additions & 2 deletions ash/wm/window_animations.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,12 @@ ASH_EXPORT void SetWindowVisibilityAnimationVerticalPosition(
ASH_EXPORT ui::ImplicitAnimationObserver* CreateHidingWindowAnimationObserver(
aura::Window* window);

namespace internal {

// Animate a cross-fade of |window| from its current bounds to |new_bounds|.
ASH_EXPORT void CrossFadeToBounds(aura::Window* window,
const gfx::Rect& new_bounds);

namespace internal {

// Returns the duration of the cross-fade animation based on the |old_bounds|
// and |new_bounds| of the window.
ASH_EXPORT base::TimeDelta GetCrossFadeDuration(const gfx::Rect& old_bounds,
Expand Down
30 changes: 16 additions & 14 deletions ash/wm/window_animations_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -173,25 +173,27 @@ TEST_F(WindowAnimationsTest, GetCrossFadeDuration) {
EXPECT_EQ(0, GetCrossFadeDuration(screen, screen).InMilliseconds());

// Small changes are fast.
gfx::Rect almost_screen(10, 10, 900, 400);
EXPECT_EQ(220, GetCrossFadeDuration(almost_screen, screen).InMilliseconds());
EXPECT_EQ(220, GetCrossFadeDuration(screen, almost_screen).InMilliseconds());
const int kMinimum = 100;
const int kRange = 300;
gfx::Rect almost_screen(10, 10, 1000, 450); // 90% of screen area
EXPECT_EQ(kMinimum + kRange / 10,
GetCrossFadeDuration(almost_screen, screen).InMilliseconds());
EXPECT_EQ(kMinimum + kRange / 10,
GetCrossFadeDuration(screen, almost_screen).InMilliseconds());

// Large changes are slow.
gfx::Rect small(10, 10, 100, 100);
EXPECT_EQ(380, GetCrossFadeDuration(small, screen).InMilliseconds());
EXPECT_EQ(380, GetCrossFadeDuration(screen, small).InMilliseconds());
gfx::Rect small(10, 10, 100, 500); // 10% of screen area
EXPECT_EQ(kMinimum + kRange * 9 / 10,
GetCrossFadeDuration(small, screen).InMilliseconds());
EXPECT_EQ(kMinimum + kRange * 9 / 10,
GetCrossFadeDuration(screen, small).InMilliseconds());

// Medium changes take medium time.
gfx::Rect half_screen(10, 10, 500, 250);
EXPECT_EQ(300, GetCrossFadeDuration(half_screen, screen).InMilliseconds());
EXPECT_EQ(300, GetCrossFadeDuration(screen, half_screen).InMilliseconds());

// Change is based on width.
gfx::Rect narrow(10, 10, 100, 500);
gfx::Rect wide(10, 10, 900, 500);
EXPECT_EQ(380, GetCrossFadeDuration(narrow, screen).InMilliseconds());
EXPECT_EQ(220, GetCrossFadeDuration(wide, screen).InMilliseconds());
EXPECT_EQ(kMinimum + kRange * 3 / 4,
GetCrossFadeDuration(half_screen, screen).InMilliseconds());
EXPECT_EQ(kMinimum + kRange * 3 / 4,
GetCrossFadeDuration(screen, half_screen).InMilliseconds());
}

} // namespace internal
Expand Down

0 comments on commit 117410d

Please sign in to comment.