Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Unified Diff: ui/views/animation/ink_drop_animation.cc

Issue 1422593003: Made material design ink drop QUICK_ACTION animation more visible. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Minor fixes after self-review. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/views/animation/ink_drop_animation.h ('k') | ui/views/animation/ink_drop_painted_layer_delegates.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/animation/ink_drop_animation.cc
diff --git a/ui/views/animation/ink_drop_animation.cc b/ui/views/animation/ink_drop_animation.cc
index d33eb43a0589a43d502ea2d666d1a04190f83901..b75672d340b7fff36c5707e771c04f465b93ef22 100644
--- a/ui/views/animation/ink_drop_animation.cc
+++ b/ui/views/animation/ink_drop_animation.cc
@@ -14,6 +14,10 @@
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
+#include "ui/gfx/geometry/point3_f.h"
+#include "ui/gfx/geometry/point_conversions.h"
+#include "ui/gfx/geometry/point_f.h"
+#include "ui/gfx/geometry/vector3d_f.h"
#include "ui/gfx/transform_util.h"
#include "ui/views/animation/ink_drop_animation_observer.h"
#include "ui/views/animation/ink_drop_painted_layer_delegates.h"
@@ -37,14 +41,32 @@ const float kVisibleOpacity = 0.14f;
// The opacity of the ink drop when it is not visible.
const float kHiddenOpacity = 0.0f;
-// Durations for the different InkDropState animations in milliseconds.
-const int kHiddenStateAnimationDurationMs = 1;
-const int kActionPendingStateAnimationDurationMs = 500;
-const int kQuickActionStateAnimationDurationMs = 250;
-const int kSlowActionPendingStateAnimationDurationMs = 500;
-const int kSlowActionStateAnimationDurationMs = 250;
-const int kActivatedStateAnimationDurationMs = 125;
-const int kDeactivatedStateAnimationDurationMs = 250;
+// The time taken to animate the ACTION_PENDING animation.
+const int kActionPendingAnimationDurationMs = 500;
+
+// The time taken to animate the visible portion of the QUICK_ACTION animation.
+const int kQuickActionVisibleAnimationDurationMs = 200;
+
+// The time taken to animate the fade out portion of the QUICK_ACTION animation.
+const int kQuickActionFadeOutAnimationDurationMs = 100;
+
+// The time taken to animate the SLOW_ACTION_PENDING animation.
+const int kSlowActionPendingAnimationDurationMs = 100;
+
+// The time taken to animate the visible portion of the SLOW_ACTION animation.
+const int kSlowActionVisibleAnimationDurationMs = 150;
+
+// The time taken to animate the fade out portion of the SLOW_ACTION animation.
+const int kSlowActionFadeOutAnimationDurationMs = 100;
+
+// The time taken to animate the ACTIVATED animation.
+const int kActivatedAnimationDurationMs = 125;
+
+// The time taken to animate the visible portion of the DEACTIVATED animation.
+const int kDeactivatedVisibleAnimationDurationMs = 150;
+
+// The time taken to animate the fade out portion of the SLOW_ACTION animation.
varkha 2015/10/22 18:33:08 s/SLOW_ACTION/DEACTIVATED?
bruthig 2015/11/04 21:51:02 Done.
+const int kDeactivatedFadeOutAnimationDurationMs = 100;
// A multiplicative factor used to slow down InkDropState animations.
const int kSlowAnimationDurationFactor = 3;
@@ -59,33 +81,85 @@ bool UseFastAnimations() {
return fast;
}
-// Returns the InkDropState animation duration for the given |state|.
-base::TimeDelta GetAnimationDuration(views::InkDropState state) {
+// All the sub animations that are used to animate each of the InkDropStates.
+enum InkDropSubAnimations {
varkha 2015/10/22 18:33:07 Should this enum be above the time constants since
bruthig 2015/11/04 21:51:02 Done.
+ // The ACTION_PENDING animation has only one sub animation which animates to a
+ // |large_size_| circle at visible opacity.
+ ACTION_PENDING,
+
+ // The QUICK_ACTION animation consists of the two sub animations:
+ // QUICK_ACTION_VISIBLE, QUICK_ACTION_FADE_OUT. The final frame of the
+ // animation is a |large_size_| circle at hidden opacity.
+
+ // The portion of the QUICK_ACTION animation that is at visible opacity.
+ QUICK_ACTION_VISIBLE,
varkha 2015/10/22 18:33:08 nit: White space after this line for consistency.
bruthig 2015/11/04 21:51:02 Done.
+ // The portion of the QUICK_ACTION animation that is at fading out to a hidden
+ // opacity.
+ QUICK_ACTION_FADE_OUT,
+
+ // The SLOW_ACTION_PENDING animation has only one sub animation which animates
+ // to a |small_size_| rounded rectangle at visible opacity.
+ SLOW_ACTION_PENDING,
+
+ // The SLOW_ACTION animation consists of the two sub animations:
+ // SLOW_ACTION_VISIBLE, SLOW_ACTION_FADE_OUT. The final frame of the
+ // animation is a |large_size_| rounded rectangle at hidden opacity.
+
+ // The portion of the SLOW_ACTION animation that is at visible opacity.
+ SLOW_ACTION_VISIBLE,
+
+ // The portion of the SLOW_ACTION animation that is fading out to a hidden
+ // opacity.
+ SLOW_ACTION_FADE_OUT,
+
+ // The ACTIVATED animation has only one sub animation which animates to a
+ // |small_size_| rounded rectangle at visible opacity.
+ ACTIVATED,
+
+ // The DEACTIVATED animation consists of the two sub animations:
+ // DEACTIVATED_VISIBLE, DEACTIVATED_FADE_OUT. The final frame of the
+ // animation is a |large_size_| rounded rectangle at hidden opacity.
+
+ // The portion of the DEACTIVATED animation that is at visible opacity.
+ DEACTIVATED_VISIBLE,
+
+ // The portion of the DEACTIVATED animation that is fading out to a hidden
+ // opacity.
+ DEACTIVATED_FADE_OUT,
+};
+
+// // Returns the InkDropState animation duration for the given |state|.
varkha 2015/10/22 18:33:08 nit: extra //.
bruthig 2015/11/04 21:51:02 Done.
+base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
int duration = 0;
switch (state) {
- case views::InkDropState::HIDDEN:
- duration = kHiddenStateAnimationDurationMs;
+ case ACTION_PENDING:
+ duration = kActionPendingAnimationDurationMs;
+ break;
+ case QUICK_ACTION_VISIBLE:
+ duration = kQuickActionVisibleAnimationDurationMs;
+ break;
+ case QUICK_ACTION_FADE_OUT:
+ duration = kQuickActionFadeOutAnimationDurationMs;
break;
- case views::InkDropState::ACTION_PENDING:
- duration = kActionPendingStateAnimationDurationMs;
+ case SLOW_ACTION_PENDING:
+ duration = kSlowActionPendingAnimationDurationMs;
break;
- case views::InkDropState::QUICK_ACTION:
- duration = kQuickActionStateAnimationDurationMs;
+ case SLOW_ACTION_VISIBLE:
+ duration = kSlowActionVisibleAnimationDurationMs;
break;
- case views::InkDropState::SLOW_ACTION_PENDING:
- duration = kSlowActionPendingStateAnimationDurationMs;
+ case SLOW_ACTION_FADE_OUT:
+ duration = kSlowActionFadeOutAnimationDurationMs;
break;
- case views::InkDropState::SLOW_ACTION:
- duration = kSlowActionStateAnimationDurationMs;
+ case ACTIVATED:
+ duration = kActivatedAnimationDurationMs;
break;
- case views::InkDropState::ACTIVATED:
- duration = kActivatedStateAnimationDurationMs;
+ case DEACTIVATED_VISIBLE:
+ duration = kDeactivatedVisibleAnimationDurationMs;
break;
- case views::InkDropState::DEACTIVATED:
- duration = kDeactivatedStateAnimationDurationMs;
+ case DEACTIVATED_FADE_OUT:
+ duration = kDeactivatedFadeOutAnimationDurationMs;
break;
}
-
return base::TimeDelta::FromMilliseconds(
(UseFastAnimations() ? 1 : kSlowAnimationDurationFactor) * duration);
}
@@ -180,6 +254,7 @@ void InkDropAnimation::SetCenterPoint(const gfx::Point& center_point) {
void InkDropAnimation::AnimateToStateInternal(
InkDropState ink_drop_state,
ui::LayerAnimationObserver* animation_observer) {
+ const InkDropState previous_ink_drop_state_ = ink_drop_state_;
ink_drop_state_ = ink_drop_state;
if (ink_drop_state_ == InkDropState::HIDDEN) {
@@ -189,7 +264,6 @@ void InkDropAnimation::AnimateToStateInternal(
// running animation prior to receiving an InkDropAnimationStarted() event
// for the HIDDEN 'animation'.
AbortAllAnimations();
- root_layer_->SetVisible(false);
SetStateToHidden();
return;
}
@@ -202,45 +276,99 @@ void InkDropAnimation::AnimateToStateInternal(
// This case is handled above in a short circuit return.
break;
case InkDropState::ACTION_PENDING:
varkha 2015/10/22 18:33:08 General comment in this method. The code seems lik
bruthig 2015/11/04 21:51:02 I'm not so sure how to reduce the amount of code h
+ AnimateToOpacity(kVisibleOpacity, GetAnimationDuration(ACTION_PENDING),
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
CalculateCircleTransforms(large_size_, &transforms);
- AnimateToTransforms(transforms, kVisibleOpacity,
- GetAnimationDuration(InkDropState::ACTION_PENDING),
+ AnimateToTransforms(transforms, GetAnimationDuration(ACTION_PENDING),
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
animation_observer);
break;
- case InkDropState::QUICK_ACTION:
+ case InkDropState::QUICK_ACTION: {
+ float visible_duration_ratio = 1.0f;
+
+ // If the previous state is ACTION_PENDING we don't want the QUICK_ACTION
+ // to take the full duration because the expanding ripple noticably
+ // changes speed.
+ if (previous_ink_drop_state_ == InkDropState::ACTION_PENDING) {
+ GetCurrentTransforms(&transforms);
+ visible_duration_ratio =
+ visible_duration_ratio -
+ CalculateDistanceEstimateToQuickAction(transforms);
+ }
+
+ const base::TimeDelta visible_duration =
+ GetAnimationDuration(QUICK_ACTION_VISIBLE) * visible_duration_ratio;
+
+ ui::LayerAnimator::PreemptionStrategy fade_out_preemption_strategy =
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET;
+
+ base::TimeDelta total_effective_duration =
+ GetAnimationDuration(QUICK_ACTION_FADE_OUT);
+
+ if (visible_duration.InMilliseconds() > 0) {
+ fade_out_preemption_strategy = ui::LayerAnimator::ENQUEUE_NEW_ANIMATION;
+ total_effective_duration += visible_duration;
+ AnimateToOpacity(kVisibleOpacity, visible_duration,
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
+ }
+
+ AnimateToOpacity(kHiddenOpacity,
+ GetAnimationDuration(QUICK_ACTION_FADE_OUT),
+ fade_out_preemption_strategy, animation_observer);
CalculateCircleTransforms(large_size_, &transforms);
- AnimateToTransforms(transforms, kHiddenOpacity,
- GetAnimationDuration(InkDropState::QUICK_ACTION),
+ AnimateToTransforms(transforms, total_effective_duration,
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
animation_observer);
break;
+ }
case InkDropState::SLOW_ACTION_PENDING:
+ AnimateToOpacity(kVisibleOpacity,
+ GetAnimationDuration(SLOW_ACTION_PENDING),
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
CalculateRectTransforms(small_size_, small_corner_radius_, &transforms);
- AnimateToTransforms(
- transforms, kVisibleOpacity,
- GetAnimationDuration(InkDropState::SLOW_ACTION_PENDING),
- ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
- animation_observer);
+ AnimateToTransforms(transforms, GetAnimationDuration(SLOW_ACTION_PENDING),
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
break;
case InkDropState::SLOW_ACTION:
+ AnimateToOpacity(kVisibleOpacity,
+ GetAnimationDuration(SLOW_ACTION_VISIBLE),
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
+ AnimateToOpacity(
+ kHiddenOpacity, GetAnimationDuration(SLOW_ACTION_FADE_OUT),
+ ui::LayerAnimator::ENQUEUE_NEW_ANIMATION, animation_observer);
CalculateRectTransforms(large_size_, large_corner_radius_, &transforms);
- AnimateToTransforms(transforms, kHiddenOpacity,
- GetAnimationDuration(InkDropState::SLOW_ACTION),
+ AnimateToTransforms(transforms,
+ GetAnimationDuration(SLOW_ACTION_VISIBLE) +
+ GetAnimationDuration(SLOW_ACTION_FADE_OUT),
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
animation_observer);
break;
case InkDropState::ACTIVATED:
+ AnimateToOpacity(kVisibleOpacity, GetAnimationDuration(ACTIVATED),
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
CalculateRectTransforms(small_size_, small_corner_radius_, &transforms);
- AnimateToTransforms(transforms, kVisibleOpacity,
- GetAnimationDuration(InkDropState::ACTIVATED),
+ AnimateToTransforms(transforms, GetAnimationDuration(ACTIVATED),
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
animation_observer);
break;
case InkDropState::DEACTIVATED:
+ AnimateToOpacity(kVisibleOpacity,
+ GetAnimationDuration(DEACTIVATED_VISIBLE),
+ ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
+ animation_observer);
+ AnimateToOpacity(
+ kHiddenOpacity, GetAnimationDuration(DEACTIVATED_FADE_OUT),
+ ui::LayerAnimator::ENQUEUE_NEW_ANIMATION, animation_observer);
CalculateRectTransforms(large_size_, large_corner_radius_, &transforms);
- AnimateToTransforms(transforms, kHiddenOpacity,
- GetAnimationDuration(InkDropState::DEACTIVATED),
+ AnimateToTransforms(transforms,
+ GetAnimationDuration(DEACTIVATED_VISIBLE) +
+ GetAnimationDuration(DEACTIVATED_FADE_OUT),
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
animation_observer);
break;
@@ -249,23 +377,9 @@ void InkDropAnimation::AnimateToStateInternal(
void InkDropAnimation::AnimateToTransforms(
const InkDropTransforms transforms,
- float opacity,
base::TimeDelta duration,
ui::LayerAnimator::PreemptionStrategy preemption_strategy,
ui::LayerAnimationObserver* animation_observer) {
- ui::LayerAnimator* root_animator = root_layer_->GetAnimator();
- ui::ScopedLayerAnimationSettings root_animation(root_animator);
- root_animation.SetPreemptionStrategy(preemption_strategy);
- ui::LayerAnimationElement* root_element =
- ui::LayerAnimationElement::CreateOpacityElement(opacity, duration);
- ui::LayerAnimationSequence* root_sequence =
- new ui::LayerAnimationSequence(root_element);
-
- if (animation_observer)
- root_sequence->AddObserver(animation_observer);
-
- root_animator->StartAnimation(root_sequence);
-
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) {
ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator();
ui::ScopedLayerAnimationSettings animation(animator);
@@ -289,6 +403,7 @@ void InkDropAnimation::SetStateToHidden() {
CalculateCircleTransforms(gfx::Size(1, 1), &transforms);
SetTransforms(transforms);
SetOpacity(kHiddenOpacity);
+ root_layer_->SetVisible(false);
varkha 2015/10/22 18:33:07 Just a question: did it matter that this is now th
bruthig 2015/11/04 21:51:02 Nope
}
void InkDropAnimation::SetTransforms(const InkDropTransforms transforms) {
@@ -300,6 +415,25 @@ void InkDropAnimation::SetOpacity(float opacity) {
root_layer_->SetOpacity(opacity);
}
+void InkDropAnimation::AnimateToOpacity(
+ float opacity,
+ base::TimeDelta duration,
+ ui::LayerAnimator::PreemptionStrategy preemption_strategy,
+ ui::LayerAnimationObserver* animation_observer) {
+ ui::LayerAnimator* animator = root_layer_->GetAnimator();
+ ui::ScopedLayerAnimationSettings animation_settings(animator);
+ animation_settings.SetPreemptionStrategy(preemption_strategy);
+ ui::LayerAnimationElement* animation_element =
+ ui::LayerAnimationElement::CreateOpacityElement(opacity, duration);
+ ui::LayerAnimationSequence* animation_sequence =
+ new ui::LayerAnimationSequence(animation_element);
+
+ if (animation_observer)
+ animation_sequence->AddObserver(animation_observer);
+
+ animator->StartAnimation(animation_sequence);
+}
+
void InkDropAnimation::CalculateCircleTransforms(
const gfx::Size& size,
InkDropTransforms* transforms_out) const {
@@ -328,19 +462,19 @@ void InkDropAnimation::CalculateRectTransforms(
const float circle_target_y_offset = size.height() / 2.0f - corner_radius;
(*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform(
- painted_layers_[TOP_LEFT_CIRCLE]->bounds().CenterPoint(), circle_scale,
+ ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale,
-circle_target_x_offset, -circle_target_y_offset);
(*transforms_out)[TOP_RIGHT_CIRCLE] = CalculateCircleTransform(
- painted_layers_[TOP_RIGHT_CIRCLE]->bounds().CenterPoint(), circle_scale,
+ ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale,
circle_target_x_offset, -circle_target_y_offset);
(*transforms_out)[BOTTOM_RIGHT_CIRCLE] = CalculateCircleTransform(
- painted_layers_[BOTTOM_RIGHT_CIRCLE]->bounds().CenterPoint(),
- circle_scale, circle_target_x_offset, circle_target_y_offset);
+ ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale,
+ circle_target_x_offset, circle_target_y_offset);
(*transforms_out)[BOTTOM_LEFT_CIRCLE] = CalculateCircleTransform(
- painted_layers_[BOTTOM_LEFT_CIRCLE]->bounds().CenterPoint(), circle_scale,
+ ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale,
-circle_target_x_offset, circle_target_y_offset);
const float rect_delegate_width =
@@ -349,22 +483,22 @@ void InkDropAnimation::CalculateRectTransforms(
static_cast<float>(rect_layer_delegate_->size().height());
(*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform(
- painted_layers_[HORIZONTAL_RECT]->bounds().CenterPoint(),
+ ToRoundedPoint(rect_layer_delegate_->GetCenterPoint()),
std::max(kMinimumRectScale, size.width() / rect_delegate_width),
std::max(kMinimumRectScale,
(size.height() - 2.0f * corner_radius) / rect_delegate_height));
(*transforms_out)[VERTICAL_RECT] = CalculateRectTransform(
- painted_layers_[VERTICAL_RECT]->bounds().CenterPoint(),
+ ToRoundedPoint(rect_layer_delegate_->GetCenterPoint()),
std::max(kMinimumRectScale,
(size.width() - 2.0f * corner_radius) / rect_delegate_width),
std::max(kMinimumRectScale, size.height() / rect_delegate_height));
}
-void InkDropAnimation::GetCurrentTansforms(
+void InkDropAnimation::GetCurrentTransforms(
InkDropTransforms* transforms_out) const {
for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
- (*transforms_out)[i] = painted_layers_[i]->GetTargetTransform();
+ (*transforms_out)[i] = painted_layers_[i]->transform();
}
void InkDropAnimation::AddPaintLayer(PaintedShape painted_shape) {
@@ -404,6 +538,37 @@ void InkDropAnimation::AbortAllAnimations() {
painted_layers_[i]->GetAnimator()->AbortAllAnimations();
}
+float InkDropAnimation::CalculateDistanceEstimateToQuickAction(
+ const InkDropTransforms& transforms) const {
+ gfx::Point3F circle_center_point =
+ gfx::Point3F(circle_layer_delegate_->GetCenterPoint());
+
+ gfx::Point3F circle_top_point(
+ circle_center_point.x(),
+ circle_center_point.y() - circle_layer_delegate_->radius(), 0);
+
+ transforms[TOP_LEFT_CIRCLE].TransformPoint(&circle_center_point);
+ transforms[TOP_LEFT_CIRCLE].TransformPoint(&circle_top_point);
+
+ // Calculate the ratio of how far the transformed circle's center point is
+ // from the destination compared to how far it can be.
+ const float center_point_distance_estimate =
+ 1.0f -
+ gfx::Vector3dF(circle_center_point.x(), circle_center_point.y(), 0)
+ .Length() /
varkha 2015/10/22 18:33:08 nit: indentation looks a bit odd here.
bruthig 2015/11/04 21:51:02 This is the result of 'git cl format'.
+ (gfx::Vector3dF(static_cast<float>(large_size_.width()),
+ static_cast<float>(large_size_.height()), 0)
+ .Length() /
+ 2.0f);
+
+ // Calculate the ratio of how far the transformed circle's top most point is
varkha 2015/10/22 18:33:08 nit: topmost.
bruthig 2015/11/04 21:51:02 Done.
+ // from the destination compared to how far it can be.
+ const float top_point_distance_estimate = fabs(
varkha 2015/10/22 18:33:08 When is the argument of fabs ever negative?
bruthig 2015/11/04 21:51:02 circle_top_point.y() is expected to be negative si
+ circle_top_point.y() / static_cast<float>(large_size_.height()) / 2.0f);
varkha 2015/10/22 18:33:07 Are the brackets correct here? Is it not y/(h/2) s
bruthig 2015/11/04 21:51:02 Done.
+
+ return std::min(center_point_distance_estimate, top_point_distance_estimate);
+}
+
void InkDropAnimation::AnimationStartedCallback(
InkDropState ink_drop_state,
const ui::CallbackLayerAnimationObserver& observer) {
« no previous file with comments | « ui/views/animation/ink_drop_animation.h ('k') | ui/views/animation/ink_drop_painted_layer_delegates.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698