| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "ui/views/animation/square_ink_drop_animation.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 | |
| 9 #include "base/logging.h" | |
| 10 #include "ui/compositor/layer.h" | |
| 11 #include "ui/compositor/layer_animation_sequence.h" | |
| 12 #include "ui/compositor/scoped_layer_animation_settings.h" | |
| 13 #include "ui/gfx/geometry/point3_f.h" | |
| 14 #include "ui/gfx/geometry/point_conversions.h" | |
| 15 #include "ui/gfx/geometry/point_f.h" | |
| 16 #include "ui/gfx/geometry/vector3d_f.h" | |
| 17 #include "ui/gfx/transform_util.h" | |
| 18 #include "ui/views/animation/ink_drop_painted_layer_delegates.h" | |
| 19 #include "ui/views/view.h" | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 // The minimum scale factor to use when scaling rectangle layers. Smaller values | |
| 24 // were causing visual anomalies. | |
| 25 const float kMinimumRectScale = 0.0001f; | |
| 26 | |
| 27 // The minimum scale factor to use when scaling circle layers. Smaller values | |
| 28 // were causing visual anomalies. | |
| 29 const float kMinimumCircleScale = 0.001f; | |
| 30 | |
| 31 // All the sub animations that are used to animate each of the InkDropStates. | |
| 32 // These are used to get time durations with | |
| 33 // GetAnimationDuration(InkDropSubAnimations). Note that in general a sub | |
| 34 // animation defines the duration for either a transformation animation or an | |
| 35 // opacity animation but there are some exceptions where an entire InkDropState | |
| 36 // animation consists of only 1 sub animation and it defines the duration for | |
| 37 // both the transformation and opacity animations. | |
| 38 enum InkDropSubAnimations { | |
| 39 // HIDDEN sub animations. | |
| 40 | |
| 41 // The HIDDEN sub animation that is fading out to a hidden opacity. | |
| 42 HIDDEN_FADE_OUT, | |
| 43 | |
| 44 // The HIDDEN sub animation that transforms the shape to a |small_size_| | |
| 45 // circle. | |
| 46 HIDDEN_TRANSFORM, | |
| 47 | |
| 48 // ACTION_PENDING sub animations. | |
| 49 | |
| 50 // The ACTION_PENDING sub animation that fades in to the visible opacity. | |
| 51 ACTION_PENDING_FADE_IN, | |
| 52 | |
| 53 // The ACTION_PENDING sub animation that transforms the shape to a | |
| 54 // |large_size_| circle. | |
| 55 ACTION_PENDING_TRANSFORM, | |
| 56 | |
| 57 // ACTION_TRIGGERED sub animations. | |
| 58 | |
| 59 // The ACTION_TRIGGERED sub animation that is fading out to a hidden opacity. | |
| 60 ACTION_TRIGGERED_FADE_OUT, | |
| 61 | |
| 62 // The ACTION_TRIGGERED sub animation that transforms the shape to a | |
| 63 // |large_size_| | |
| 64 // circle. | |
| 65 ACTION_TRIGGERED_TRANSFORM, | |
| 66 | |
| 67 // ALTERNATE_ACTION_PENDING sub animations. | |
| 68 | |
| 69 // The ALTERNATE_ACTION_PENDING animation has only one sub animation which | |
| 70 // animates | |
| 71 // to a |small_size_| rounded rectangle at visible opacity. | |
| 72 ALTERNATE_ACTION_PENDING, | |
| 73 | |
| 74 // ALTERNATE_ACTION_TRIGGERED sub animations. | |
| 75 | |
| 76 // The ALTERNATE_ACTION_TRIGGERED sub animation that is fading out to a hidden | |
| 77 // opacity. | |
| 78 ALTERNATE_ACTION_TRIGGERED_FADE_OUT, | |
| 79 | |
| 80 // The ALTERNATE_ACTION_TRIGGERED sub animation that transforms the shape to a | |
| 81 // |large_size_| | |
| 82 // rounded rectangle. | |
| 83 ALTERNATE_ACTION_TRIGGERED_TRANSFORM, | |
| 84 | |
| 85 // ACTIVATED sub animations. | |
| 86 | |
| 87 // The ACTIVATED sub animation that transforms the shape to a |large_size_| | |
| 88 // circle. This is used when the ink drop is in a HIDDEN state prior to | |
| 89 // animating to the ACTIVATED state. | |
| 90 ACTIVATED_CIRCLE_TRANSFORM, | |
| 91 | |
| 92 // The ACTIVATED sub animation that transforms the shape to a |small_size_| | |
| 93 // rounded rectangle. | |
| 94 ACTIVATED_RECT_TRANSFORM, | |
| 95 | |
| 96 // DEACTIVATED sub animations. | |
| 97 | |
| 98 // The DEACTIVATED sub animation that is fading out to a hidden opacity. | |
| 99 DEACTIVATED_FADE_OUT, | |
| 100 | |
| 101 // The DEACTIVATED sub animation that transforms the shape to a |large_size_| | |
| 102 // rounded rectangle. | |
| 103 DEACTIVATED_TRANSFORM, | |
| 104 }; | |
| 105 | |
| 106 // The scale factor used to burst the ACTION_TRIGGERED bubble as it fades out. | |
| 107 const float kQuickActionBurstScale = 1.3f; | |
| 108 | |
| 109 // Duration constants for InkDropStateSubAnimations. See the | |
| 110 // InkDropStateSubAnimations enum documentation for more info. | |
| 111 int kAnimationDurationInMs[] = { | |
| 112 150, // HIDDEN_FADE_OUT | |
| 113 200, // HIDDEN_TRANSFORM | |
| 114 0, // ACTION_PENDING_FADE_IN | |
| 115 160, // ACTION_PENDING_TRANSFORM | |
| 116 150, // ACTION_TRIGGERED_FADE_OUT | |
| 117 160, // ACTION_TRIGGERED_TRANSFORM | |
| 118 200, // ALTERNATE_ACTION_PENDING | |
| 119 150, // ALTERNATE_ACTION_TRIGGERED_FADE_OUT | |
| 120 200, // ALTERNATE_ACTION_TRIGGERED_TRANSFORM | |
| 121 200, // ACTIVATED_CIRCLE_TRANSFORM | |
| 122 160, // ACTIVATED_RECT_TRANSFORM | |
| 123 150, // DEACTIVATED_FADE_OUT | |
| 124 200, // DEACTIVATED_TRANSFORM | |
| 125 }; | |
| 126 | |
| 127 // Returns the InkDropState sub animation duration for the given |state|. | |
| 128 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) { | |
| 129 return base::TimeDelta::FromMilliseconds( | |
| 130 (views::InkDropAnimation::UseFastAnimations() | |
| 131 ? 1 | |
| 132 : views::InkDropAnimation::kSlowAnimationDurationFactor) * | |
| 133 kAnimationDurationInMs[state]); | |
| 134 } | |
| 135 | |
| 136 // Calculates a Transform for a circle layer. The transform will be set up to | |
| 137 // translate the |drawn_center_point| to the origin, scale, and then translate | |
| 138 // to the target point defined by |target_center_x| and |target_center_y|. | |
| 139 gfx::Transform CalculateCircleTransform(const gfx::Point& drawn_center_point, | |
| 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(-drawn_center_point.x(), -drawn_center_point.y()); | |
| 147 return transform; | |
| 148 } | |
| 149 | |
| 150 // Calculates a Transform for a rectangle layer. The transform will be set up to | |
| 151 // translate the |drawn_center_point| to the origin and then scale by the | |
| 152 // |x_scale| and |y_scale| factors. | |
| 153 gfx::Transform CalculateRectTransform(const gfx::Point& drawn_center_point, | |
| 154 float x_scale, | |
| 155 float y_scale) { | |
| 156 gfx::Transform transform; | |
| 157 transform.Scale(x_scale, y_scale); | |
| 158 transform.Translate(-drawn_center_point.x(), -drawn_center_point.y()); | |
| 159 return transform; | |
| 160 } | |
| 161 | |
| 162 } // namespace | |
| 163 | |
| 164 namespace views { | |
| 165 | |
| 166 SquareInkDropAnimation::SquareInkDropAnimation(const gfx::Size& large_size, | |
| 167 int large_corner_radius, | |
| 168 const gfx::Size& small_size, | |
| 169 int small_corner_radius, | |
| 170 const gfx::Point& center_point, | |
| 171 SkColor color) | |
| 172 : large_size_(large_size), | |
| 173 large_corner_radius_(large_corner_radius), | |
| 174 small_size_(small_size), | |
| 175 small_corner_radius_(small_corner_radius), | |
| 176 circle_layer_delegate_(new CircleLayerDelegate( | |
| 177 color, | |
| 178 std::min(large_size_.width(), large_size_.height()) / 2)), | |
| 179 rect_layer_delegate_(new RectangleLayerDelegate(color, large_size_)), | |
| 180 root_layer_(ui::LAYER_NOT_DRAWN) { | |
| 181 root_layer_.set_name("SquareInkDropAnimation:ROOT_LAYER"); | |
| 182 | |
| 183 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | |
| 184 AddPaintLayer(static_cast<PaintedShape>(i)); | |
| 185 | |
| 186 root_layer_.SetMasksToBounds(false); | |
| 187 root_layer_.SetBounds(gfx::Rect(large_size_)); | |
| 188 | |
| 189 gfx::Transform transform; | |
| 190 transform.Translate(center_point.x(), center_point.y()); | |
| 191 root_layer_.SetTransform(transform); | |
| 192 | |
| 193 SetStateToHidden(); | |
| 194 } | |
| 195 | |
| 196 SquareInkDropAnimation::~SquareInkDropAnimation() { | |
| 197 // Explicitly aborting all the animations ensures all callbacks are invoked | |
| 198 // while this instance still exists. | |
| 199 AbortAllAnimations(); | |
| 200 } | |
| 201 | |
| 202 void SquareInkDropAnimation::SnapToActivated() { | |
| 203 InkDropAnimation::SnapToActivated(); | |
| 204 SetOpacity(kVisibleOpacity); | |
| 205 InkDropTransforms transforms; | |
| 206 GetActivatedTargetTransforms(&transforms); | |
| 207 SetTransforms(transforms); | |
| 208 } | |
| 209 | |
| 210 ui::Layer* SquareInkDropAnimation::GetRootLayer() { | |
| 211 return &root_layer_; | |
| 212 } | |
| 213 | |
| 214 bool SquareInkDropAnimation::IsVisible() const { | |
| 215 return root_layer_.visible(); | |
| 216 } | |
| 217 | |
| 218 float SquareInkDropAnimation::GetCurrentOpacity() const { | |
| 219 return root_layer_.opacity(); | |
| 220 } | |
| 221 | |
| 222 std::string SquareInkDropAnimation::ToLayerName(PaintedShape painted_shape) { | |
| 223 switch (painted_shape) { | |
| 224 case TOP_LEFT_CIRCLE: | |
| 225 return "TOP_LEFT_CIRCLE"; | |
| 226 case TOP_RIGHT_CIRCLE: | |
| 227 return "TOP_RIGHT_CIRCLE"; | |
| 228 case BOTTOM_RIGHT_CIRCLE: | |
| 229 return "BOTTOM_RIGHT_CIRCLE"; | |
| 230 case BOTTOM_LEFT_CIRCLE: | |
| 231 return "BOTTOM_LEFT_CIRCLE"; | |
| 232 case HORIZONTAL_RECT: | |
| 233 return "HORIZONTAL_RECT"; | |
| 234 case VERTICAL_RECT: | |
| 235 return "VERTICAL_RECT"; | |
| 236 case PAINTED_SHAPE_COUNT: | |
| 237 NOTREACHED() << "The PAINTED_SHAPE_COUNT value should never be used."; | |
| 238 return "PAINTED_SHAPE_COUNT"; | |
| 239 } | |
| 240 return "UNKNOWN"; | |
| 241 } | |
| 242 | |
| 243 void SquareInkDropAnimation::AnimateStateChange( | |
| 244 InkDropState old_ink_drop_state, | |
| 245 InkDropState new_ink_drop_state, | |
| 246 ui::LayerAnimationObserver* animation_observer) { | |
| 247 InkDropTransforms transforms; | |
| 248 | |
| 249 switch (new_ink_drop_state) { | |
| 250 case InkDropState::HIDDEN: | |
| 251 if (!IsVisible()) { | |
| 252 SetStateToHidden(); | |
| 253 break; | |
| 254 } else { | |
| 255 AnimateToOpacity(kHiddenOpacity, GetAnimationDuration(HIDDEN_FADE_OUT), | |
| 256 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 257 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 258 CalculateCircleTransforms(small_size_, &transforms); | |
| 259 AnimateToTransforms( | |
| 260 transforms, GetAnimationDuration(HIDDEN_TRANSFORM), | |
| 261 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 262 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 263 } | |
| 264 break; | |
| 265 case InkDropState::ACTION_PENDING: | |
| 266 DCHECK(old_ink_drop_state == InkDropState::HIDDEN); | |
| 267 AnimateToOpacity(kVisibleOpacity, | |
| 268 GetAnimationDuration(ACTION_PENDING_FADE_IN), | |
| 269 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 270 gfx::Tween::EASE_IN, animation_observer); | |
| 271 AnimateToOpacity(kVisibleOpacity, | |
| 272 GetAnimationDuration(ACTION_PENDING_TRANSFORM), | |
| 273 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 274 gfx::Tween::EASE_IN, animation_observer); | |
| 275 CalculateCircleTransforms(large_size_, &transforms); | |
| 276 AnimateToTransforms(transforms, | |
| 277 GetAnimationDuration(ACTION_PENDING_TRANSFORM), | |
| 278 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 279 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 280 break; | |
| 281 case InkDropState::ACTION_TRIGGERED: { | |
| 282 DCHECK(old_ink_drop_state == InkDropState::HIDDEN || | |
| 283 old_ink_drop_state == InkDropState::ACTION_PENDING); | |
| 284 if (old_ink_drop_state == InkDropState::HIDDEN) { | |
| 285 AnimateStateChange(old_ink_drop_state, InkDropState::ACTION_PENDING, | |
| 286 animation_observer); | |
| 287 } | |
| 288 AnimateToOpacity(kHiddenOpacity, | |
| 289 GetAnimationDuration(ACTION_TRIGGERED_FADE_OUT), | |
| 290 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION, | |
| 291 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 292 gfx::Size s = ScaleToRoundedSize(large_size_, kQuickActionBurstScale); | |
| 293 CalculateCircleTransforms(s, &transforms); | |
| 294 AnimateToTransforms(transforms, | |
| 295 GetAnimationDuration(ACTION_TRIGGERED_TRANSFORM), | |
| 296 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION, | |
| 297 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 298 break; | |
| 299 } | |
| 300 case InkDropState::ALTERNATE_ACTION_PENDING: | |
| 301 DCHECK(old_ink_drop_state == InkDropState::ACTION_PENDING); | |
| 302 AnimateToOpacity(kVisibleOpacity, | |
| 303 GetAnimationDuration(ALTERNATE_ACTION_PENDING), | |
| 304 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 305 gfx::Tween::EASE_IN, animation_observer); | |
| 306 CalculateRectTransforms(small_size_, small_corner_radius_, &transforms); | |
| 307 AnimateToTransforms(transforms, | |
| 308 GetAnimationDuration(ALTERNATE_ACTION_PENDING), | |
| 309 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 310 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 311 break; | |
| 312 case InkDropState::ALTERNATE_ACTION_TRIGGERED: { | |
| 313 DCHECK(old_ink_drop_state == InkDropState::ALTERNATE_ACTION_PENDING); | |
| 314 base::TimeDelta visible_duration = | |
| 315 GetAnimationDuration(ALTERNATE_ACTION_TRIGGERED_TRANSFORM) - | |
| 316 GetAnimationDuration(ALTERNATE_ACTION_TRIGGERED_FADE_OUT); | |
| 317 AnimateToOpacity(kVisibleOpacity, visible_duration, | |
| 318 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 319 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 320 AnimateToOpacity(kHiddenOpacity, GetAnimationDuration( | |
| 321 ALTERNATE_ACTION_TRIGGERED_FADE_OUT), | |
| 322 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION, | |
| 323 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 324 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | |
| 325 AnimateToTransforms(transforms, GetAnimationDuration( | |
| 326 ALTERNATE_ACTION_TRIGGERED_TRANSFORM), | |
| 327 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 328 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 329 break; | |
| 330 } | |
| 331 case InkDropState::ACTIVATED: { | |
| 332 // Animate the opacity so that it cancels any opacity animations already | |
| 333 // in progress. | |
| 334 AnimateToOpacity(kVisibleOpacity, base::TimeDelta(), | |
| 335 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 336 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 337 | |
| 338 ui::LayerAnimator::PreemptionStrategy rect_transform_preemption_strategy = | |
| 339 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET; | |
| 340 if (old_ink_drop_state == InkDropState::HIDDEN) { | |
| 341 rect_transform_preemption_strategy = | |
| 342 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION; | |
| 343 CalculateCircleTransforms(large_size_, &transforms); | |
| 344 AnimateToTransforms( | |
| 345 transforms, GetAnimationDuration(ACTIVATED_CIRCLE_TRANSFORM), | |
| 346 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 347 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 348 } else if (old_ink_drop_state == InkDropState::ACTION_PENDING) { | |
| 349 rect_transform_preemption_strategy = | |
| 350 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION; | |
| 351 } | |
| 352 | |
| 353 GetActivatedTargetTransforms(&transforms); | |
| 354 AnimateToTransforms(transforms, | |
| 355 GetAnimationDuration(ACTIVATED_RECT_TRANSFORM), | |
| 356 rect_transform_preemption_strategy, | |
| 357 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 358 break; | |
| 359 } | |
| 360 case InkDropState::DEACTIVATED: { | |
| 361 base::TimeDelta visible_duration = | |
| 362 GetAnimationDuration(DEACTIVATED_TRANSFORM) - | |
| 363 GetAnimationDuration(DEACTIVATED_FADE_OUT); | |
| 364 AnimateToOpacity(kVisibleOpacity, visible_duration, | |
| 365 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 366 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 367 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | |
| 368 AnimateToOpacity(kHiddenOpacity, | |
| 369 GetAnimationDuration(DEACTIVATED_FADE_OUT), | |
| 370 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION, | |
| 371 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 372 CalculateRectTransforms(large_size_, large_corner_radius_, &transforms); | |
| 373 AnimateToTransforms(transforms, | |
| 374 GetAnimationDuration(DEACTIVATED_TRANSFORM), | |
| 375 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET, | |
| 376 gfx::Tween::EASE_IN_OUT, animation_observer); | |
| 377 break; | |
| 378 } | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 void SquareInkDropAnimation::SetStateToHidden() { | |
| 383 InkDropTransforms transforms; | |
| 384 // Use non-zero size to avoid visual anomalies. | |
| 385 CalculateCircleTransforms(gfx::Size(1, 1), &transforms); | |
| 386 SetTransforms(transforms); | |
| 387 root_layer_.SetOpacity(InkDropAnimation::kHiddenOpacity); | |
| 388 root_layer_.SetVisible(false); | |
| 389 } | |
| 390 | |
| 391 void SquareInkDropAnimation::AbortAllAnimations() { | |
| 392 root_layer_.GetAnimator()->AbortAllAnimations(); | |
| 393 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | |
| 394 painted_layers_[i]->GetAnimator()->AbortAllAnimations(); | |
| 395 } | |
| 396 | |
| 397 void SquareInkDropAnimation::AnimateToTransforms( | |
| 398 const InkDropTransforms transforms, | |
| 399 base::TimeDelta duration, | |
| 400 ui::LayerAnimator::PreemptionStrategy preemption_strategy, | |
| 401 gfx::Tween::Type tween, | |
| 402 ui::LayerAnimationObserver* animation_observer) { | |
| 403 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) { | |
| 404 ui::LayerAnimator* animator = painted_layers_[i]->GetAnimator(); | |
| 405 ui::ScopedLayerAnimationSettings animation(animator); | |
| 406 animation.SetPreemptionStrategy(preemption_strategy); | |
| 407 animation.SetTweenType(tween); | |
| 408 ui::LayerAnimationElement* element = | |
| 409 ui::LayerAnimationElement::CreateTransformElement(transforms[i], | |
| 410 duration); | |
| 411 ui::LayerAnimationSequence* sequence = | |
| 412 new ui::LayerAnimationSequence(element); | |
| 413 | |
| 414 if (animation_observer) | |
| 415 sequence->AddObserver(animation_observer); | |
| 416 | |
| 417 animator->StartAnimation(sequence); | |
| 418 } | |
| 419 } | |
| 420 | |
| 421 void SquareInkDropAnimation::SetTransforms(const InkDropTransforms transforms) { | |
| 422 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | |
| 423 painted_layers_[i]->SetTransform(transforms[i]); | |
| 424 } | |
| 425 | |
| 426 void SquareInkDropAnimation::SetOpacity(float opacity) { | |
| 427 root_layer_.SetOpacity(opacity); | |
| 428 } | |
| 429 | |
| 430 void SquareInkDropAnimation::AnimateToOpacity( | |
| 431 float opacity, | |
| 432 base::TimeDelta duration, | |
| 433 ui::LayerAnimator::PreemptionStrategy preemption_strategy, | |
| 434 gfx::Tween::Type tween, | |
| 435 ui::LayerAnimationObserver* animation_observer) { | |
| 436 ui::LayerAnimator* animator = root_layer_.GetAnimator(); | |
| 437 ui::ScopedLayerAnimationSettings animation_settings(animator); | |
| 438 animation_settings.SetPreemptionStrategy(preemption_strategy); | |
| 439 animation_settings.SetTweenType(tween); | |
| 440 ui::LayerAnimationElement* animation_element = | |
| 441 ui::LayerAnimationElement::CreateOpacityElement(opacity, duration); | |
| 442 ui::LayerAnimationSequence* animation_sequence = | |
| 443 new ui::LayerAnimationSequence(animation_element); | |
| 444 | |
| 445 if (animation_observer) | |
| 446 animation_sequence->AddObserver(animation_observer); | |
| 447 | |
| 448 animator->StartAnimation(animation_sequence); | |
| 449 } | |
| 450 | |
| 451 void SquareInkDropAnimation::CalculateCircleTransforms( | |
| 452 const gfx::Size& size, | |
| 453 InkDropTransforms* transforms_out) const { | |
| 454 CalculateRectTransforms(size, std::min(size.width(), size.height()) / 2.0f, | |
| 455 transforms_out); | |
| 456 } | |
| 457 | |
| 458 void SquareInkDropAnimation::CalculateRectTransforms( | |
| 459 const gfx::Size& size, | |
| 460 float corner_radius, | |
| 461 InkDropTransforms* transforms_out) const { | |
| 462 DCHECK_GE(size.width() / 2.0f, corner_radius) | |
| 463 << "The circle's diameter should not be greater than the total width."; | |
| 464 DCHECK_GE(size.height() / 2.0f, corner_radius) | |
| 465 << "The circle's diameter should not be greater than the total height."; | |
| 466 | |
| 467 // The shapes are drawn such that their center points are not at the origin. | |
| 468 // Thus we use the CalculateCircleTransform() and CalculateRectTransform() | |
| 469 // methods to calculate the complex Transforms. | |
| 470 | |
| 471 const float circle_scale = std::max( | |
| 472 kMinimumCircleScale, | |
| 473 corner_radius / static_cast<float>(circle_layer_delegate_->radius())); | |
| 474 | |
| 475 const float circle_target_x_offset = size.width() / 2.0f - corner_radius; | |
| 476 const float circle_target_y_offset = size.height() / 2.0f - corner_radius; | |
| 477 | |
| 478 (*transforms_out)[TOP_LEFT_CIRCLE] = CalculateCircleTransform( | |
| 479 ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale, | |
| 480 -circle_target_x_offset, -circle_target_y_offset); | |
| 481 | |
| 482 (*transforms_out)[TOP_RIGHT_CIRCLE] = CalculateCircleTransform( | |
| 483 ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale, | |
| 484 circle_target_x_offset, -circle_target_y_offset); | |
| 485 | |
| 486 (*transforms_out)[BOTTOM_RIGHT_CIRCLE] = CalculateCircleTransform( | |
| 487 ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale, | |
| 488 circle_target_x_offset, circle_target_y_offset); | |
| 489 | |
| 490 (*transforms_out)[BOTTOM_LEFT_CIRCLE] = CalculateCircleTransform( | |
| 491 ToRoundedPoint(circle_layer_delegate_->GetCenterPoint()), circle_scale, | |
| 492 -circle_target_x_offset, circle_target_y_offset); | |
| 493 | |
| 494 const float rect_delegate_width = | |
| 495 static_cast<float>(rect_layer_delegate_->size().width()); | |
| 496 const float rect_delegate_height = | |
| 497 static_cast<float>(rect_layer_delegate_->size().height()); | |
| 498 | |
| 499 (*transforms_out)[HORIZONTAL_RECT] = CalculateRectTransform( | |
| 500 ToRoundedPoint(rect_layer_delegate_->GetCenterPoint()), | |
| 501 std::max(kMinimumRectScale, size.width() / rect_delegate_width), | |
| 502 std::max(kMinimumRectScale, | |
| 503 (size.height() - 2.0f * corner_radius) / rect_delegate_height)); | |
| 504 | |
| 505 (*transforms_out)[VERTICAL_RECT] = CalculateRectTransform( | |
| 506 ToRoundedPoint(rect_layer_delegate_->GetCenterPoint()), | |
| 507 std::max(kMinimumRectScale, | |
| 508 (size.width() - 2.0f * corner_radius) / rect_delegate_width), | |
| 509 std::max(kMinimumRectScale, size.height() / rect_delegate_height)); | |
| 510 } | |
| 511 | |
| 512 void SquareInkDropAnimation::GetCurrentTransforms( | |
| 513 InkDropTransforms* transforms_out) const { | |
| 514 for (int i = 0; i < PAINTED_SHAPE_COUNT; ++i) | |
| 515 (*transforms_out)[i] = painted_layers_[i]->transform(); | |
| 516 } | |
| 517 | |
| 518 void SquareInkDropAnimation::GetActivatedTargetTransforms( | |
| 519 InkDropTransforms* transforms_out) const { | |
| 520 CalculateRectTransforms(small_size_, small_corner_radius_, transforms_out); | |
| 521 } | |
| 522 | |
| 523 void SquareInkDropAnimation::AddPaintLayer(PaintedShape painted_shape) { | |
| 524 ui::LayerDelegate* delegate = nullptr; | |
| 525 switch (painted_shape) { | |
| 526 case TOP_LEFT_CIRCLE: | |
| 527 case TOP_RIGHT_CIRCLE: | |
| 528 case BOTTOM_RIGHT_CIRCLE: | |
| 529 case BOTTOM_LEFT_CIRCLE: | |
| 530 delegate = circle_layer_delegate_.get(); | |
| 531 break; | |
| 532 case HORIZONTAL_RECT: | |
| 533 case VERTICAL_RECT: | |
| 534 delegate = rect_layer_delegate_.get(); | |
| 535 break; | |
| 536 case PAINTED_SHAPE_COUNT: | |
| 537 NOTREACHED() << "PAINTED_SHAPE_COUNT is not an actual shape type."; | |
| 538 break; | |
| 539 } | |
| 540 | |
| 541 ui::Layer* layer = new ui::Layer(); | |
| 542 root_layer_.Add(layer); | |
| 543 | |
| 544 layer->SetBounds(gfx::Rect(large_size_)); | |
| 545 layer->SetFillsBoundsOpaquely(false); | |
| 546 layer->set_delegate(delegate); | |
| 547 layer->SetVisible(true); | |
| 548 layer->SetOpacity(1.0); | |
| 549 layer->SetMasksToBounds(false); | |
| 550 layer->set_name("PAINTED_SHAPE_COUNT:" + ToLayerName(painted_shape)); | |
| 551 | |
| 552 painted_layers_[painted_shape].reset(layer); | |
| 553 } | |
| 554 | |
| 555 } // namespace views | |
| OLD | NEW |