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

Side by Side Diff: ui/views/animation/square_ink_drop_ripple.cc

Issue 2805813007: Improve toolbar button ink drop ripples at 1.25x (Closed)
Patch Set: relax dcheck Created 3 years, 8 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/views/animation/square_ink_drop_ripple.h" 5 #include "ui/views/animation/square_ink_drop_ripple.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "ui/compositor/layer.h" 10 #include "ui/compositor/layer.h"
11 #include "ui/compositor/layer_animation_sequence.h" 11 #include "ui/compositor/layer_animation_sequence.h"
12 #include "ui/compositor/scoped_layer_animation_settings.h" 12 #include "ui/compositor/scoped_layer_animation_settings.h"
13 #include "ui/gfx/geometry/point3_f.h" 13 #include "ui/gfx/geometry/point3_f.h"
14 #include "ui/gfx/geometry/point_conversions.h" 14 #include "ui/gfx/geometry/point_conversions.h"
15 #include "ui/gfx/geometry/point_f.h" 15 #include "ui/gfx/geometry/point_f.h"
16 #include "ui/gfx/geometry/vector3d_f.h" 16 #include "ui/gfx/geometry/vector3d_f.h"
17 #include "ui/gfx/transform_util.h" 17 #include "ui/gfx/transform_util.h"
18 #include "ui/views/animation/ink_drop_painted_layer_delegates.h" 18 #include "ui/views/animation/ink_drop_painted_layer_delegates.h"
19 #include "ui/views/view.h" 19 #include "ui/views/view.h"
20 20
21 namespace views {
22
21 namespace { 23 namespace {
22 24
23 // The minimum scale factor to use when scaling rectangle layers. Smaller values 25 // The minimum scale factor to use when scaling rectangle layers. Smaller values
24 // were causing visual anomalies. 26 // were causing visual anomalies.
25 const float kMinimumRectScale = 0.0001f; 27 const float kMinimumRectScale = 0.0001f;
26 28
27 // The minimum scale factor to use when scaling circle layers. Smaller values 29 // The minimum scale factor to use when scaling circle layers. Smaller values
28 // were causing visual anomalies. 30 // were causing visual anomalies.
29 const float kMinimumCircleScale = 0.001f; 31 const float kMinimumCircleScale = 0.001f;
30 32
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 200, // ALTERNATE_ACTION_TRIGGERED_TRANSFORM 122 200, // ALTERNATE_ACTION_TRIGGERED_TRANSFORM
121 200, // ACTIVATED_CIRCLE_TRANSFORM 123 200, // ACTIVATED_CIRCLE_TRANSFORM
122 160, // ACTIVATED_RECT_TRANSFORM 124 160, // ACTIVATED_RECT_TRANSFORM
123 150, // DEACTIVATED_FADE_OUT 125 150, // DEACTIVATED_FADE_OUT
124 200, // DEACTIVATED_TRANSFORM 126 200, // DEACTIVATED_TRANSFORM
125 }; 127 };
126 128
127 // Returns the InkDropState sub animation duration for the given |state|. 129 // Returns the InkDropState sub animation duration for the given |state|.
128 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) { 130 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
129 return base::TimeDelta::FromMilliseconds( 131 return base::TimeDelta::FromMilliseconds(
130 (views::InkDropRipple::UseFastAnimations() 132 (InkDropRipple::UseFastAnimations()
131 ? 1 133 ? 1
132 : views::InkDropRipple::kSlowAnimationDurationFactor) * 134 : InkDropRipple::kSlowAnimationDurationFactor) *
133 kAnimationDurationInMs[state]); 135 kAnimationDurationInMs[state]);
134 } 136 }
135 137
136 // Calculates a Transform for a circle layer. The transform will be set up to
137 // translate by -|center_offset|, scale, and then translate to the target point
138 // defined by |target_center_x| and |target_center_y|.
139 gfx::Transform CalculateCircleTransform(const gfx::Vector2dF& center_offset,
140 float scale,
141 float target_center_x,
142 float target_center_y) {
143 gfx::Transform transform;
144 transform.Translate(target_center_x, target_center_y);
145 transform.Scale(scale, scale);
146 transform.Translate(-center_offset.x(), -center_offset.y());
147 return transform;
148 }
149
150 // Calculates a Transform for a rectangle layer. The transform will be set up to
151 // translate by -|center_offset| and then scale by the |x_scale| and |y_scale|
152 // factors.
153 gfx::Transform CalculateRectTransform(const gfx::Vector2dF& center_offset,
154 float x_scale,
155 float y_scale) {
156 gfx::Transform transform;
157 transform.Scale(x_scale, y_scale);
158 transform.Translate(-center_offset.x(), -center_offset.y());
159 return transform;
160 }
161
162 } // namespace 138 } // namespace
163 139
164 namespace views {
165
166 SquareInkDropRipple::SquareInkDropRipple(const gfx::Size& large_size, 140 SquareInkDropRipple::SquareInkDropRipple(const gfx::Size& large_size,
167 int large_corner_radius, 141 int large_corner_radius,
168 const gfx::Size& small_size, 142 const gfx::Size& small_size,
169 int small_corner_radius, 143 int small_corner_radius,
170 const gfx::Point& center_point, 144 const gfx::Point& center_point,
171 SkColor color, 145 SkColor color,
172 float visible_opacity) 146 float visible_opacity)
173 : activated_shape_(ROUNDED_RECT), 147 : activated_shape_(ROUNDED_RECT),
174 visible_opacity_(visible_opacity), 148 visible_opacity_(visible_opacity),
175 large_size_(large_size), 149 large_size_(large_size),
176 large_corner_radius_(large_corner_radius), 150 large_corner_radius_(large_corner_radius),
177 small_size_(small_size), 151 small_size_(small_size),
178 small_corner_radius_(small_corner_radius), 152 small_corner_radius_(small_corner_radius),
153 center_point_(center_point),
179 circle_layer_delegate_(new CircleLayerDelegate( 154 circle_layer_delegate_(new CircleLayerDelegate(
180 color, 155 color,
181 std::min(large_size_.width(), large_size_.height()) / 2)), 156 std::min(large_size_.width(), large_size_.height()) / 2)),
182 rect_layer_delegate_( 157 rect_layer_delegate_(
183 new RectangleLayerDelegate(color, gfx::SizeF(large_size_))), 158 new RectangleLayerDelegate(color, gfx::SizeF(large_size_))),
184 root_layer_(ui::LAYER_NOT_DRAWN) { 159 root_layer_(ui::LAYER_NOT_DRAWN) {
185 root_layer_.set_name("SquareInkDropRipple:ROOT_LAYER"); 160 root_layer_.set_name("SquareInkDropRipple:ROOT_LAYER");
186 161
187 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) 162 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
188 AddPaintLayer(static_cast<PaintedShape>(i)); 163 AddPaintLayer(static_cast<PaintedShape>(i));
189 164
190 root_layer_.SetMasksToBounds(false); 165 root_layer_.SetMasksToBounds(false);
191 root_layer_.SetBounds(gfx::Rect(large_size_)); 166 root_layer_.SetBounds(gfx::Rect(large_size_));
192 167
193 gfx::Transform transform;
194 transform.Translate(center_point.x(), center_point.y());
195 root_layer_.SetTransform(transform);
196
197 SetStateToHidden(); 168 SetStateToHidden();
198 } 169 }
199 170
200 SquareInkDropRipple::~SquareInkDropRipple() { 171 SquareInkDropRipple::~SquareInkDropRipple() {
201 // Explicitly aborting all the animations ensures all callbacks are invoked 172 // Explicitly aborting all the animations ensures all callbacks are invoked
202 // while this instance still exists. 173 // while this instance still exists.
203 AbortAllAnimations(); 174 AbortAllAnimations();
204 } 175 }
205 176
206 void SquareInkDropRipple::SnapToActivated() { 177 void SquareInkDropRipple::SnapToActivated() {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 CalculateCircleTransforms(small_size_, &transforms); 229 CalculateCircleTransforms(small_size_, &transforms);
259 AnimateToTransforms( 230 AnimateToTransforms(
260 transforms, GetAnimationDuration(HIDDEN_TRANSFORM), 231 transforms, GetAnimationDuration(HIDDEN_TRANSFORM),
261 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, 232 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
262 gfx::Tween::EASE_IN_OUT, animation_observer); 233 gfx::Tween::EASE_IN_OUT, animation_observer);
263 } 234 }
264 break; 235 break;
265 case InkDropState::ACTION_PENDING: 236 case InkDropState::ACTION_PENDING:
266 DCHECK_EQ(InkDropState::HIDDEN, old_ink_drop_state) 237 DCHECK_EQ(InkDropState::HIDDEN, old_ink_drop_state)
267 << " old_ink_drop_state=" << ToString(old_ink_drop_state); 238 << " old_ink_drop_state=" << ToString(old_ink_drop_state);
268 ;
269 AnimateToOpacity(visible_opacity_, 239 AnimateToOpacity(visible_opacity_,
270 GetAnimationDuration(ACTION_PENDING_FADE_IN), 240 GetAnimationDuration(ACTION_PENDING_FADE_IN),
271 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, 241 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
272 gfx::Tween::EASE_IN, animation_observer); 242 gfx::Tween::EASE_IN, animation_observer);
273 AnimateToOpacity(visible_opacity_, 243 AnimateToOpacity(visible_opacity_,
274 GetAnimationDuration(ACTION_PENDING_TRANSFORM), 244 GetAnimationDuration(ACTION_PENDING_TRANSFORM),
275 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, 245 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
276 gfx::Tween::EASE_IN, animation_observer); 246 gfx::Tween::EASE_IN, animation_observer);
277 CalculateCircleTransforms(large_size_, &transforms); 247 CalculateCircleTransforms(large_size_, &transforms);
278 AnimateToTransforms(transforms, 248 AnimateToTransforms(transforms,
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 } 423 }
454 424
455 void SquareInkDropRipple::CalculateCircleTransforms( 425 void SquareInkDropRipple::CalculateCircleTransforms(
456 const gfx::Size& size, 426 const gfx::Size& size,
457 InkDropTransforms* transforms_out) const { 427 InkDropTransforms* transforms_out) const {
458 CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f, 428 CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f,
459 transforms_out); 429 transforms_out);
460 } 430 }
461 431
462 void SquareInkDropRipple::CalculateRectTransforms( 432 void SquareInkDropRipple::CalculateRectTransforms(
463 const gfx::Size& size, 433 const gfx::Size& desired_size,
464 float corner_radius, 434 float corner_radius,
465 InkDropTransforms* transforms_out) const { 435 InkDropTransforms* transforms_out) const {
466 DCHECK_GE(size.width() / 2.0f, corner_radius) 436 DCHECK_GE(desired_size.width() / 2.0f, corner_radius)
467 << "The circle's diameter should not be greater than the total width."; 437 << "The circle's diameter should not be greater than the total width.";
468 DCHECK_GE(size.height() / 2.0f, corner_radius) 438 DCHECK_GE(desired_size.height() / 2.0f, corner_radius)
469 << "The circle's diameter should not be greater than the total height."; 439 << "The circle's diameter should not be greater than the total height.";
470 440
441 gfx::SizeF size(desired_size);
bruthig 2017/04/12 17:57:39 nit: Consider renaming as |effective_size|.
Evan Stade 2017/04/12 23:48:28 it's used so often below I wanted to keep it short
442 // This function can be called before the layer's been added to a view,
443 // either at construction time or in tests.
444 if (root_layer_.GetCompositor()) {
445 // Modify |desired_size| so that the ripple aligns to pixel bounds.
446 const float dsf = root_layer_.GetCompositor()->device_scale_factor();
447 gfx::RectF ripple_bounds((gfx::PointF(center_point_)), gfx::SizeF());
bruthig 2017/04/12 17:57:39 I'm assuming the 'extra' parenthesis are required.
Evan Stade 2017/04/12 23:48:28 yes. disambiguates a function call or some such.
448 ripple_bounds.Inset(-gfx::InsetsF(desired_size.height() / 2.0f,
449 desired_size.width() / 2.0f));
450 ripple_bounds.Scale(dsf);
451 ripple_bounds = gfx::RectF(gfx::ToEnclosingRect(ripple_bounds));
452 ripple_bounds.Scale(1.0f / dsf);
453 size = ripple_bounds.size();
454 }
455
471 // The shapes are drawn such that their center points are not at the origin. 456 // The shapes are drawn such that their center points are not at the origin.
472 // Thus we use the CalculateCircleTransform() and CalculateRectTransform() 457 // Thus we use the CalculateCircleTransform() and CalculateRectTransform()
473 // methods to calculate the complex Transforms. 458 // methods to calculate the complex Transforms.
474 459
475 const float circle_scale = std::max( 460 const float circle_scale = std::max(
476 kMinimumCircleScale, 461 kMinimumCircleScale,
477 corner_radius / static_cast<float>(circle_layer_delegate_->radius())); 462 corner_radius / static_cast<float>(circle_layer_delegate_->radius()));
478 463
479 const float circle_target_x_offset = size.width() / 2.0f - corner_radius; 464 const float circle_target_x_offset = size.width() / 2.0f - corner_radius;
480 const float circle_target_y_offset = size.height() / 2.0f - corner_radius; 465 const float circle_target_y_offset = size.height() / 2.0f - corner_radius;
481 466
482 const gfx::Vector2dF circle_center_offset =
483 circle_layer_delegate_->GetCenteringOffset();
484 (*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform( 467 (*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform(
485 circle_center_offset, circle_scale, -circle_target_x_offset, 468 circle_scale, -circle_target_x_offset, -circle_target_y_offset);
486 -circle_target_y_offset); 469 (*transforms_out)[TOP_RIGHT_CIRCLE] = CalculateCircleTransform(
470 circle_scale, circle_target_x_offset, -circle_target_y_offset);
471 (*transforms_out)[BOTTOM_RIGHT_CIRCLE] = CalculateCircleTransform(
472 circle_scale, circle_target_x_offset, circle_target_y_offset);
473 (*transforms_out)[BOTTOM_LEFT_CIRCLE] = CalculateCircleTransform(
474 circle_scale, -circle_target_x_offset, circle_target_y_offset);
487 475
488 (*transforms_out)[TOP_RIGHT_CIRCLE] = 476 const float rect_delegate_width = rect_layer_delegate_->size().width();
489 CalculateCircleTransform(circle_center_offset, circle_scale, 477 const float rect_delegate_height = rect_layer_delegate_->size().height();
490 circle_target_x_offset, -circle_target_y_offset);
491 478
492 (*transforms_out)[BOTTOM_RIGHT_CIRCLE] =
493 CalculateCircleTransform(circle_center_offset, circle_scale,
494 circle_target_x_offset, circle_target_y_offset);
495
496 (*transforms_out)[BOTTOM_LEFT_CIRCLE] =
497 CalculateCircleTransform(circle_center_offset, circle_scale,
498 -circle_target_x_offset, circle_target_y_offset);
499
500 const float rect_delegate_width =
501 static_cast<float>(rect_layer_delegate_->size().width());
502 const float rect_delegate_height =
503 static_cast<float>(rect_layer_delegate_->size().height());
504
505 const gfx::Vector2dF rect_center_offset =
506 rect_layer_delegate_->GetCenteringOffset();
507 (*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform( 479 (*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform(
508 rect_center_offset,
509 std::max(kMinimumRectScale, size.width() / rect_delegate_width), 480 std::max(kMinimumRectScale, size.width() / rect_delegate_width),
510 std::max(kMinimumRectScale, 481 std::max(kMinimumRectScale,
511 (size.height() - 2.0f * corner_radius) / rect_delegate_height)); 482 (size.height() - 2.0f * corner_radius) / rect_delegate_height));
512 483
513 (*transforms_out)[VERTICAL_RECT] = CalculateRectTransform( 484 (*transforms_out)[VERTICAL_RECT] = CalculateRectTransform(
514 rect_center_offset,
515 std::max(kMinimumRectScale, 485 std::max(kMinimumRectScale,
516 (size.width() - 2.0f * corner_radius) / rect_delegate_width), 486 (size.width() - 2.0f * corner_radius) / rect_delegate_width),
517 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); 487 std::max(kMinimumRectScale, size.height() / rect_delegate_height));
518 } 488 }
519 489
490 gfx::Transform SquareInkDropRipple::CalculateCircleTransform(
491 float scale,
492 float target_center_x,
493 float target_center_y) const {
494 gfx::Transform transform;
495 // Offset for the center point of the ripple.
496 transform.Translate(center_point_.x(), center_point_.y());
497 // Move circle to target.
498 transform.Translate(target_center_x, target_center_y);
499 transform.Scale(scale, scale);
500 // Align center point of the painted circle.
501 const gfx::Vector2dF circle_center_offset =
502 circle_layer_delegate_->GetCenteringOffset();
503 transform.Translate(-circle_center_offset.x(), -circle_center_offset.y());
504 return transform;
505 }
506
507 gfx::Transform SquareInkDropRipple::CalculateRectTransform(
508 float x_scale,
509 float y_scale) const {
510 gfx::Transform transform;
511 transform.Translate(center_point_.x(), center_point_.y());
512 transform.Scale(x_scale, y_scale);
513 const gfx::Vector2dF rect_center_offset =
514 rect_layer_delegate_->GetCenteringOffset();
515 transform.Translate(-rect_center_offset.x(), -rect_center_offset.y());
516 return transform;
517 }
518
520 void SquareInkDropRipple::GetCurrentTransforms( 519 void SquareInkDropRipple::GetCurrentTransforms(
521 InkDropTransforms* transforms_out) const { 520 InkDropTransforms* transforms_out) const {
522 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) 521 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i)
523 (*transforms_out)[i] = painted_layers_[i]->transform(); 522 (*transforms_out)[i] = painted_layers_[i]->transform();
524 } 523 }
525 524
526 void SquareInkDropRipple::GetActivatedTargetTransforms( 525 void SquareInkDropRipple::GetActivatedTargetTransforms(
527 InkDropTransforms* transforms_out) const { 526 InkDropTransforms* transforms_out) const {
528 switch (activated_shape_) { 527 switch (activated_shape_) {
529 case CIRCLE: 528 case CIRCLE:
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 layer->set_delegate(delegate); 574 layer->set_delegate(delegate);
576 layer->SetVisible(true); 575 layer->SetVisible(true);
577 layer->SetOpacity(1.0); 576 layer->SetOpacity(1.0);
578 layer->SetMasksToBounds(false); 577 layer->SetMasksToBounds(false);
579 layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape)); 578 layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape));
580 579
581 painted_layers_[painted_shape].reset(layer); 580 painted_layers_[painted_shape].reset(layer);
582 } 581 }
583 582
584 } // namespace views 583 } // namespace views
OLDNEW
« ui/views/animation/square_ink_drop_ripple.h ('K') | « ui/views/animation/square_ink_drop_ripple.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698