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

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

Issue 1937103003: Rename of InkDropAnimation classes to InkDropRipple. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed test_ink_drop_animation_observer.h from views.gyp and doc update. Created 4 years, 7 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
(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/flood_fill_ink_drop_animation.h"
6
7 #include <algorithm>
8
9 #include "base/logging.h"
10 #include "third_party/skia/include/core/SkColor.h"
11 #include "ui/compositor/layer.h"
12 #include "ui/compositor/layer_animation_sequence.h"
13 #include "ui/compositor/scoped_layer_animation_settings.h"
14 #include "ui/gfx/geometry/point_conversions.h"
15 #include "ui/gfx/geometry/vector2d_f.h"
16
17 namespace {
18
19 // The minimum radius to use when scaling the painted layers. Smaller values
20 // were causing visual anomalies.
21 const float kMinRadius = 1.f;
22
23 // All the sub animations that are used to animate each of the InkDropStates.
24 // These are used to get time durations with
25 // GetAnimationDuration(InkDropSubAnimations). Note that in general a sub
26 // animation defines the duration for either a transformation animation or an
27 // opacity animation but there are some exceptions where an entire InkDropState
28 // animation consists of only 1 sub animation and it defines the duration for
29 // both the transformation and opacity animations.
30 enum InkDropSubAnimations {
31 // HIDDEN sub animations.
32
33 // The HIDDEN sub animation that is fading out to a hidden opacity.
34 HIDDEN_FADE_OUT,
35
36 // The HIDDEN sub animation that transform the circle to a small one.
37 HIDDEN_TRANSFORM,
38
39 // ACTION_PENDING sub animations.
40
41 // The ACTION_PENDING sub animation that fades in to the visible opacity.
42 ACTION_PENDING_FADE_IN,
43
44 // The ACTION_PENDING sub animation that transforms the circle to fill the
45 // bounds.
46 ACTION_PENDING_TRANSFORM,
47
48 // ACTION_TRIGGERED sub animations.
49
50 // The ACTION_TRIGGERED sub animation that is fading out to a hidden opacity.
51 ACTION_TRIGGERED_FADE_OUT,
52
53 // ALTERNATE_ACTION_PENDING sub animations.
54
55 // The ALTERNATE_ACTION_PENDING animation has only one sub animation which
56 // animates
57 // the circleto fill the bounds at visible opacity.
58 ALTERNATE_ACTION_PENDING,
59
60 // ALTERNATE_ACTION_TRIGGERED sub animations.
61
62 // The ALTERNATE_ACTION_TRIGGERED sub animation that is fading out to a hidden
63 // opacity.
64 ALTERNATE_ACTION_TRIGGERED_FADE_OUT,
65
66 // ACTIVATED sub animations.
67
68 // The ACTIVATED sub animation that is fading in to the visible opacity.
69 ACTIVATED_FADE_IN,
70
71 // The ACTIVATED sub animation that transforms the circle to fill the entire
72 // bounds.
73 ACTIVATED_TRANSFORM,
74
75 // DEACTIVATED sub animations.
76
77 // The DEACTIVATED sub animation that is fading out to a hidden opacity.
78 DEACTIVATED_FADE_OUT,
79 };
80
81 // Duration constants for InkDropStateSubAnimations. See the
82 // InkDropStateSubAnimations enum documentation for more info.
83 int kAnimationDurationInMs[] = {
84 200, // HIDDEN_FADE_OUT
85 300, // HIDDEN_TRANSFORM
86 0, // ACTION_PENDING_FADE_IN
87 240, // ACTION_PENDING_TRANSFORM
88 300, // ACTION_TRIGGERED_FADE_OUT
89 200, // ALTERNATE_ACTION_PENDING
90 300, // ALTERNATE_ACTION_TRIGGERED_FADE_OUT
91 150, // ACTIVATED_FADE_IN
92 200, // ACTIVATED_TRANSFORM
93 300, // DEACTIVATED_FADE_OUT
94 };
95
96 // Returns the InkDropState sub animation duration for the given |state|.
97 base::TimeDelta GetAnimationDuration(InkDropSubAnimations state) {
98 return base::TimeDelta::FromMilliseconds(
99 (views::InkDropAnimation::UseFastAnimations()
100 ? 1
101 : views::InkDropAnimation::kSlowAnimationDurationFactor) *
102 kAnimationDurationInMs[state]);
103 }
104
105 } // namespace
106
107 namespace views {
108
109 FloodFillInkDropAnimation::FloodFillInkDropAnimation(
110 const gfx::Rect& clip_bounds,
111 const gfx::Point& center_point,
112 SkColor color)
113 : clip_bounds_(clip_bounds),
114 center_point_(center_point),
115 root_layer_(ui::LAYER_NOT_DRAWN),
116 circle_layer_delegate_(
117 color,
118 std::max(clip_bounds_.width(), clip_bounds_.height()) / 2.f),
119 ink_drop_state_(InkDropState::HIDDEN) {
120 root_layer_.set_name("FloodFillInkDropAnimation:ROOT_LAYER");
121 root_layer_.SetMasksToBounds(true);
122 root_layer_.SetBounds(clip_bounds);
123
124 const int painted_size_length =
125 2 * std::max(clip_bounds_.width(), clip_bounds_.height());
126
127 painted_layer_.SetBounds(gfx::Rect(painted_size_length, painted_size_length));
128 painted_layer_.SetFillsBoundsOpaquely(false);
129 painted_layer_.set_delegate(&circle_layer_delegate_);
130 painted_layer_.SetVisible(true);
131 painted_layer_.SetOpacity(1.0);
132 painted_layer_.SetMasksToBounds(false);
133 painted_layer_.set_name("FloodFillInkDropAnimation:PAINTED_LAYER");
134
135 root_layer_.Add(&painted_layer_);
136
137 SetStateToHidden();
138 }
139
140 FloodFillInkDropAnimation::~FloodFillInkDropAnimation() {
141 // Explicitly aborting all the animations ensures all callbacks are invoked
142 // while this instance still exists.
143 AbortAllAnimations();
144 }
145
146 void FloodFillInkDropAnimation::SnapToActivated() {
147 InkDropAnimation::SnapToActivated();
148 SetOpacity(kVisibleOpacity);
149 painted_layer_.SetTransform(GetMaxSizeTargetTransform());
150 }
151
152 ui::Layer* FloodFillInkDropAnimation::GetRootLayer() {
153 return &root_layer_;
154 }
155
156 bool FloodFillInkDropAnimation::IsVisible() const {
157 return root_layer_.visible();
158 }
159
160 void FloodFillInkDropAnimation::AnimateStateChange(
161 InkDropState old_ink_drop_state,
162 InkDropState new_ink_drop_state,
163 ui::LayerAnimationObserver* animation_observer) {
164 switch (new_ink_drop_state) {
165 case InkDropState::HIDDEN:
166 if (!IsVisible()) {
167 SetStateToHidden();
168 } else {
169 AnimateToOpacity(kHiddenOpacity, GetAnimationDuration(HIDDEN_FADE_OUT),
170 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
171 gfx::Tween::EASE_IN_OUT, animation_observer);
172 const gfx::Transform transform = CalculateTransform(kMinRadius);
173 AnimateToTransform(transform, GetAnimationDuration(HIDDEN_TRANSFORM),
174 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
175 gfx::Tween::EASE_IN_OUT, animation_observer);
176 }
177 break;
178 case InkDropState::ACTION_PENDING: {
179 DCHECK(old_ink_drop_state == InkDropState::HIDDEN);
180
181 AnimateToOpacity(kVisibleOpacity,
182 GetAnimationDuration(ACTION_PENDING_FADE_IN),
183 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
184 gfx::Tween::EASE_IN, animation_observer);
185 AnimateToOpacity(kVisibleOpacity,
186 GetAnimationDuration(ACTION_PENDING_TRANSFORM) -
187 GetAnimationDuration(ACTION_PENDING_FADE_IN),
188 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION,
189 gfx::Tween::EASE_IN, animation_observer);
190
191 AnimateToTransform(GetMaxSizeTargetTransform(),
192 GetAnimationDuration(ACTION_PENDING_TRANSFORM),
193 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
194 gfx::Tween::FAST_OUT_SLOW_IN, animation_observer);
195 break;
196 }
197 case InkDropState::ACTION_TRIGGERED: {
198 DCHECK(old_ink_drop_state == InkDropState::HIDDEN ||
199 old_ink_drop_state == InkDropState::ACTION_PENDING);
200 if (old_ink_drop_state == InkDropState::HIDDEN) {
201 AnimateStateChange(old_ink_drop_state, InkDropState::ACTION_PENDING,
202 animation_observer);
203 }
204 AnimateToOpacity(kHiddenOpacity,
205 GetAnimationDuration(ACTION_TRIGGERED_FADE_OUT),
206 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION,
207 gfx::Tween::EASE_IN_OUT, animation_observer);
208 break;
209 }
210 case InkDropState::ALTERNATE_ACTION_PENDING: {
211 DCHECK(old_ink_drop_state == InkDropState::ACTION_PENDING);
212 AnimateToOpacity(kVisibleOpacity,
213 GetAnimationDuration(ALTERNATE_ACTION_PENDING),
214 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
215 gfx::Tween::EASE_IN, animation_observer);
216 AnimateToTransform(GetMaxSizeTargetTransform(),
217 GetAnimationDuration(ALTERNATE_ACTION_PENDING),
218 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
219 gfx::Tween::EASE_IN_OUT, animation_observer);
220 break;
221 }
222 case InkDropState::ALTERNATE_ACTION_TRIGGERED:
223 DCHECK(old_ink_drop_state == InkDropState::ALTERNATE_ACTION_PENDING);
224 AnimateToOpacity(kHiddenOpacity, GetAnimationDuration(
225 ALTERNATE_ACTION_TRIGGERED_FADE_OUT),
226 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION,
227 gfx::Tween::EASE_IN_OUT, animation_observer);
228 break;
229 case InkDropState::ACTIVATED: {
230 AnimateToOpacity(kVisibleOpacity, GetAnimationDuration(ACTIVATED_FADE_IN),
231 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
232 gfx::Tween::EASE_IN, animation_observer);
233 AnimateToTransform(GetMaxSizeTargetTransform(),
234 GetAnimationDuration(ACTIVATED_TRANSFORM),
235 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET,
236 gfx::Tween::EASE_IN_OUT, animation_observer);
237 break;
238 }
239 case InkDropState::DEACTIVATED:
240 AnimateToOpacity(kHiddenOpacity,
241 GetAnimationDuration(DEACTIVATED_FADE_OUT),
242 ui::LayerAnimator::ENQUEUE_NEW_ANIMATION,
243 gfx::Tween::EASE_IN_OUT, animation_observer);
244 break;
245 }
246 }
247
248 void FloodFillInkDropAnimation::SetStateToHidden() {
249 painted_layer_.SetTransform(CalculateTransform(kMinRadius));
250 root_layer_.SetOpacity(InkDropAnimation::kHiddenOpacity);
251 root_layer_.SetVisible(false);
252 }
253
254 void FloodFillInkDropAnimation::AbortAllAnimations() {
255 root_layer_.GetAnimator()->AbortAllAnimations();
256 painted_layer_.GetAnimator()->AbortAllAnimations();
257 }
258
259 void FloodFillInkDropAnimation::AnimateToTransform(
260 const gfx::Transform& transform,
261 base::TimeDelta duration,
262 ui::LayerAnimator::PreemptionStrategy preemption_strategy,
263 gfx::Tween::Type tween,
264 ui::LayerAnimationObserver* animation_observer) {
265 ui::LayerAnimator* animator = painted_layer_.GetAnimator();
266 ui::ScopedLayerAnimationSettings animation(animator);
267 animation.SetPreemptionStrategy(preemption_strategy);
268 animation.SetTweenType(tween);
269 ui::LayerAnimationElement* element =
270 ui::LayerAnimationElement::CreateTransformElement(transform, duration);
271 ui::LayerAnimationSequence* sequence =
272 new ui::LayerAnimationSequence(element);
273
274 if (animation_observer)
275 sequence->AddObserver(animation_observer);
276
277 animator->StartAnimation(sequence);
278 }
279
280 void FloodFillInkDropAnimation::SetOpacity(float opacity) {
281 root_layer_.SetOpacity(opacity);
282 }
283
284 void FloodFillInkDropAnimation::AnimateToOpacity(
285 float opacity,
286 base::TimeDelta duration,
287 ui::LayerAnimator::PreemptionStrategy preemption_strategy,
288 gfx::Tween::Type tween,
289 ui::LayerAnimationObserver* animation_observer) {
290 ui::LayerAnimator* animator = root_layer_.GetAnimator();
291 ui::ScopedLayerAnimationSettings animation_settings(animator);
292 animation_settings.SetPreemptionStrategy(preemption_strategy);
293 animation_settings.SetTweenType(tween);
294 ui::LayerAnimationElement* animation_element =
295 ui::LayerAnimationElement::CreateOpacityElement(opacity, duration);
296 ui::LayerAnimationSequence* animation_sequence =
297 new ui::LayerAnimationSequence(animation_element);
298
299 if (animation_observer)
300 animation_sequence->AddObserver(animation_observer);
301
302 animator->StartAnimation(animation_sequence);
303 }
304
305 gfx::Transform FloodFillInkDropAnimation::CalculateTransform(
306 float target_radius) const {
307 const float target_scale = target_radius / circle_layer_delegate_.radius();
308 const gfx::Point drawn_center_point =
309 ToRoundedPoint(circle_layer_delegate_.GetCenterPoint());
310
311 gfx::Transform transform = gfx::Transform();
312 transform.Translate(center_point_.x(), center_point_.y());
313 transform.Scale(target_scale, target_scale);
314 transform.Translate(-drawn_center_point.x() - root_layer_.bounds().x(),
315 -drawn_center_point.y() - root_layer_.bounds().y());
316
317 return transform;
318 }
319
320 gfx::Transform FloodFillInkDropAnimation::GetMaxSizeTargetTransform() const {
321 // TODO(estade): get rid of this 2, but make the fade out start before the
322 // active/action transform is done.
323 return CalculateTransform(
324 gfx::Vector2dF(clip_bounds_.width(), clip_bounds_.height()).Length() / 2);
325 }
326
327 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/animation/flood_fill_ink_drop_animation.h ('k') | ui/views/animation/flood_fill_ink_drop_ripple.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698