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

Side by Side Diff: chrome/browser/resources/settings/settings_page/expand_card_transition.js

Issue 2106013002: Move settings-section animations into setting-section, make better (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@Transitions
Patch Set: rebase, minor fix Created 4 years, 5 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 cr.define('settings', function() {
6 /**
7 * Expands a card to fill its container's client height, so it covers the
8 * container from the top padding edge to the bottom padding edge.
9 * @see https://www.w3.org/TR/cssom-view-1/#terminology
10 * @constructor
11 * @implements {settings.animation.AnimationGroup}
12 * @param {!HTMLElement} card Card to expand.
13 * @param {!HTMLElement} container Container whose height the card will span.
14 */
15 function ExpandCardTransition(card, container) {
16 this.card = card;
17 this.container = container;
18
19 /** @type {?settings.animation.Animation} */
20 this.animation_ = null;
Dan Beam 2016/07/07 18:27:54 why not just put this @type when initializing?
michaelpg 2016/07/08 00:19:02 Done.
21 }
22
23 ExpandCardTransition.prototype = {
24 __proto__: settings.animation.AnimationGroup.prototype,
25
26 /** @override */
27 play: function() {
28 // If we're running this transition before anything else, we won't have
29 // the information we need, so just expand immediately and finish.
30 if (typeof this.card.origHeight_ == 'undefined' ||
31 this.card.style.top == '' || this.card.style.height == '') {
32 this.finished = Promise.resolve();
33 return this.finished;
34 }
35
36 // Align the card with the container's padding edge.
37 var startingTop = this.card.getBoundingClientRect().top;
38
39 // Target position is the container's top edge in the viewport.
40 var targetTop = this.container.getBoundingClientRect().top;
41
42 // The target height shouldn't use the container's current height, because
43 // the container may resize when the window resizes. And height: 100%
44 // wouldn't use the container's height because we're position: fixed.
45 //
46 // Instead, find the part of the window height *not* used by the container
47 // (e.g., for a toolbar) and calc the height dynamically. This assumes the
48 // excluded height stays constant.
49 var excludedHeight = window.innerHeight - this.container.clientHeight;
50 var targetHeight = 'calc(100% - ' + excludedHeight + 'px)';
51
52 // Expand the card. The card's height must be 100% of the container's
53 // height or taller, so we use minHeight rather than height.
54 var keyframes = [{
55 top: startingTop + 'px',
56 minHeight: this.card.style.height,
57 easing: settings.animation.Timing.EASING,
58 }, {
59 top: targetTop + 'px',
60 minHeight: 'calc(100% - ' + targetTop + 'px)',
61 }];
62 var options = /** @type {!KeyframeEffectOptions} */({
63 duration: settings.animation.Timing.DURATION,
64 });
65
Dan Beam 2016/07/07 18:27:54 as in here: /** @type {?settings.animation.Animat
michaelpg 2016/07/08 00:19:02 Done.
66 this.animation_ =
67 new settings.animation.Animation(this.card, keyframes, options);
68 this.finished = this.animation_.finished;
69 return this.finished;
70 },
71
72 /** @override */
73 finish: function() {
74 if (!this.animation_)
75 return;
76 this.animation_.finish();
77 this.animation_ = null;
78 },
79
80 /** @override */
81 cancel: function() {
82 if (!this.animation_)
83 return;
84 this.animation_.cancel();
85 this.animation_ = null;
86 },
87
88 /** @override */
89 finished: null,
Dan Beam 2016/07/07 18:27:54 why is this necessary?
michaelpg 2016/07/08 00:19:02 it's required. otherwise: ## /foo/src/chrome/brow
90 };
91
92 /**
93 * Collapses an expanded card back into its original section.
94 * @constructor
95 * @implements {settings.animation.AnimationGroup}
96 * @param {!SettingsSectionElement} section Section that contains the card.
97 * @param {!HTMLElement} container Container the card currently spans.
98 */
99 function CollapseCardTransition(section, container) {
100 /** @type {!HTMLElement} */
101 this.card = section.$['card'];
Dan Beam 2016/07/07 18:27:54 should card be @private (i.e. card_)?
Dan Beam 2016/07/07 18:27:54 this.card = assert(section.$['card']);
michaelpg 2016/07/08 00:19:02 Done.
michaelpg 2016/07/08 00:19:02 Done.
102 /** @type {!SettingsSectionElement} */
103 this.section = section;
104 this.container = container;
105
106 /** @type {?settings.animation.Animation} */
107 this.animation_ = null;
108 }
109
110 CollapseCardTransition.prototype = {
111 __proto__: settings.animation.AnimationGroup.prototype,
112
113 /** Sets up the transition before other page content has been unhidden. */
114 setUp: function() {
115 this.card.style.width = this.card.clientWidth + 'px';
116 this.card.style.height = this.card.clientHeight + 'px';
117 },
118
119 /** @override */
120 play: function() {
121 var startingTop = this.container.getBoundingClientRect().top;
122
123 // The card is unpositioned, so use its position as the ending state,
124 // but account for scroll.
125 var targetTop = this.card.getBoundingClientRect().top -
126 this.container.scrollTop;
127
128 // Account for the section header.
129 var headerStyle = getComputedStyle(this.section.$['header']);
130 targetTop += this.section.$['header'].offsetHeight +
131 parseFloat(headerStyle.marginBottom) +
132 parseFloat(headerStyle.marginTop);
133
134 var keyframes = [{
135 top: startingTop + 'px',
136 minHeight: this.card.style.height,
137 easing: settings.animation.Timing.EASING,
138 }, {
139 top: targetTop + 'px',
140 minHeight:
141 /** @type {{origHeight_: number}} */(this.card).origHeight_ + 'px',
142 }];
143 var options = /** @type {!KeyframeEffectOptions} */({
144 duration: settings.animation.Timing.DURATION,
145 });
146
147 this.card.style.height = '';
148 this.animation_ =
149 new settings.animation.Animation(this.card, keyframes, options);
150 this.finished = this.animation_.finished;
151 // Clean up after the animation finishes or cancels.
152 this.finished.catch(function() {}).then(function() {
153 this.card.style.width = '';
154 }.bind(this));
155 return this.finished;
156 },
157
158 /** @override */
159 finish: function() {
160 if (!this.animation_)
161 return;
162 this.animation_.finish();
163 this.animation_ = null;
164 },
165
166 /** @override */
167 cancel: function() {
168 if (!this.animation_)
169 return;
170 this.animation_.cancel();
171 this.animation_ = null;
172 },
Dan Beam 2016/07/07 18:27:54 why can't we make a @protected |this.animation| in
michaelpg 2016/07/08 00:19:02 the base interface is AnimationGroup; it doesn't r
173
174 /** @override */
175 finished: null,
176 };
177
178 return {
179 CollapseCardTransition: CollapseCardTransition,
180 ExpandCardTransition: ExpandCardTransition,
181 };
182 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698