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

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

Powered by Google App Engine
This is Rietveld 408576698