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

Side by Side Diff: chrome/browser/resources/settings/settings_page/settings_section.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: Refactor Created 4 years, 4 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview 6 * @fileoverview
7 * 'settings-section' shows a paper material themed section with a header 7 * 'settings-section' shows a paper material themed section with a header
8 * which shows its page title. 8 * which shows its page title.
9
dschuyler 2016/08/04 18:36:51 Maybe remove blank line or add an '*'?
10 * The section can expand vertically to to its container's padding edge.
9 * 11 *
10 * Example: 12 * Example:
11 * 13 *
12 * <settings-section page-title="[[pageTitle]]" section="privacy"> 14 * <settings-section page-title="[[pageTitle]]" section="privacy">
13 * <!-- Insert your section controls here --> 15 * <!-- Insert your section controls here -->
14 * </settings-section> 16 * </settings-section>
15 */ 17 */
16 Polymer({ 18 Polymer({
17 is: 'settings-section', 19 is: 'settings-section',
18 20
19 properties: { 21 properties: {
20 /** 22 /**
21 * The current active route. 23 * The current active route.
22 */ 24 */
23 currentRoute: Object, 25 currentRoute: Object,
24 26
25 /** 27 /**
26 * The section is expanded to a full-page view when this property matches 28 * The section name should match a name specified in route.js. The
29 * MainPageBehavior will expand this section if this section name matches
27 * currentRoute.section. 30 * currentRoute.section.
28 *
29 * The section name must match the name specified in settings_router.js.
30 */ 31 */
31 section: { 32 section: String,
32 type: String, 33
33 }, 34 /** Title for the section header. */
35 pageTitle: String,
34 36
35 /** 37 /**
36 * Title for the page header and navigation menu. 38 * Original height of the collapsed section, used as the target height when
39 * collapsing after being expanded.
40 * TODO(michaelpg): Get the height dynamically when collapsing using the
41 * card's main page.
42 * @private
37 */ 43 */
38 pageTitle: String, 44 collapsedHeight_: {
45 type: Number,
46 value: NaN,
47 },
48 },
49
50 /**
51 * @return {boolean} True if the section is currently rendered and not
52 * already expanded or transitioning.
53 */
54 canAnimateExpand: function() {
55 return !this.classList.contains('expanding') &&
56 !this.classList.contains('expanded') && this.$.card.clientHeight > 0;
57 },
58
59 /**
60 * Animates the section expanding to fill the container. The section is fixed
61 * in the viewport during the animation, making it safe to adjust the rest of
62 * the DOM after calling this. The section adds the 'expanding' class while
63 * the animation plays and 'expanded' after it finishes.
64 *
65 * The animation does not "last", so the parent must properly position it
66 * afterwards in its container.
67 *
68 * @param {!HTMLElement} container The scrolling container to fill.
69 * @return {!settings.animation.Animation}
70 */
71 animateExpand: function(container) {
72 // Set the section's height so its card can be removed from the flow
73 // without affecting the surrounding sections during the animation.
74 this.collapsedHeight_ = this.clientHeight;
75 this.style.height = this.collapsedHeight_ + 'px';
76
77 this.classList.add('expanding');
78
79 // Start the card in place, at its distance from the container's padding.
80 var startTop = this.$.card.getBoundingClientRect().top + 'px';
81 var startHeight = this.$.card.clientHeight + 'px';
82
83 // Target position is the container's top edge in the viewport.
84 var containerTop = container.getBoundingClientRect().top;
85 var endTop = containerTop + 'px';
86 // The card should stretch from the bottom of the toolbar to the bottom of
87 // the page. calc(100% - top) lets the card resize if the window resizes.
88 var endHeight = 'calc(100% - ' + containerTop + 'px)';
89
90 var animation =
91 this.animateCard_('fixed', startTop, endTop, startHeight, endHeight);
92
93 // Whether the animation fails or succeeds, clean up the properties we set.
94 animation.finished.catch(function() {}).then(function() {
95 this.classList.remove('expanding');
96 this.style.height = '';
97 }.bind(this));
98 return animation;
99 },
100
101 /** @return {boolean} True if the section is currently expanded. */
102 canAnimateCollapse: function() {
103 return this.classList.contains('expanded') && this.clientHeight > 0 &&
104 !Number.isNaN(this.collapsedHeight_);
105 },
106
107 /**
108 * Prepares for the animation before the other sections become visible.
109 * Call before animateCollapse().
110 */
111 setUpAnimateCollapse: function(container) {
112 // Prepare the dimensions and set position: fixed.
113 this.$.card.style.width = this.$.card.clientWidth + 'px';
114 this.$.card.style.height = this.$.card.clientHeight + 'px';
115 this.$.card.style.top = container.getBoundingClientRect().top + 'px';
116 this.$.card.style.position = 'fixed';
117
118 // The section can now collapse back into its original height the page so
119 // the other sections appear in the right places.
120 this.classList.add('collapsing');
121 this.style.height = this.collapsedHeight_ + 'px';
122 },
123
124 /**
125 * Collapses an expanded section's card back into position in the main page.
126 * Call after calling animateCollapse(), unhiding other content and scrolling.
127 * @param {!HTMLElement} container The scrolling container the card fills.
128 * @return {!settings.animation.Animation}
129 */
130 animateCollapse: function(container) {
131 // Make the card position: absolute, so scrolling is less of a crapshoot.
132 // First find the current distance between this section and the card using
133 // fixed coordinates; the absolute distance will be the same.
134 var fixedCardTop = this.$.card.getBoundingClientRect().top;
135 var fixedSectionTop = this.getBoundingClientRect().top;
136 var distance = fixedCardTop - fixedSectionTop;
137
138 // The target position is right below our header.
139 var headerStyle = getComputedStyle(this.$.header);
140 var cardTargetTop = this.$.header.offsetHeight +
141 parseFloat(headerStyle.marginBottom) +
142 parseFloat(headerStyle.marginTop);
143
144 // Start the card at its current height and distance from our top.
145 var startTop = distance + 'px';
146 var startHeight = this.$.card.style.height;
147
148 // End at the bottom of our header.
149 var endTop = cardTargetTop + 'px';
150 var endHeight = (this.collapsedHeight_ - cardTargetTop) + 'px';
151
152 // The card no longer needs position: fixed.
153 this.$.card.style.position = '';
154
155 // Collapse this section, animate the card into place, and remove its
156 // other properties.
157 var animation =
158 this.animateCard_('absolute', startTop, endTop, startHeight, endHeight);
159 this.$.card.style.width = '';
160 this.$.card.style.height = '';
161 this.$.card.style.top = '';
162
163 // Whether the animation fails or succeeds, clean up the properties we set.
164 animation.finished.catch(function() {}).then(function() {
165 // The card now determines the section's height automatically.
166 this.style.height = '';
167 this.classList.remove('collapsing');
168 }.bind(this));
169 return animation;
170 },
171
172 /**
173 * Helper function to animate the card's position and height.
174 * @param {string} position CSS position property.
175 * @param {string} startTop Initial top value.
176 * @param {string} endTop Target top value.
177 * @param {string} startHeight Initial height value.
178 * @param {string} endHeight Target height value.
179 * @return {!settings.animation.Animation}
180 * @private
181 */
182 animateCard_: function(position, startTop, endTop, startHeight, endHeight) {
183 // Width does not change.
184 var width = this.$.card.clientWidth + 'px';
185
186 var startFrame = {
187 position: position,
188 width: width,
189 top: startTop,
190 height: startHeight,
191 };
192
193 var endFrame = {
194 position: position,
195 width: width,
196 top: endTop,
197 height: endHeight,
198 };
199
200 var options = /** @type {!KeyframeEffectOptions} */({
201 duration: settings.animation.Timing.DURATION,
202 easing: settings.animation.Timing.EASING,
203 });
204
205 return new settings.animation.Animation(
206 this.$.card, [startFrame, endFrame], options);
39 }, 207 },
40 }); 208 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698