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