OLD | NEW |
| (Empty) |
1 | |
2 /** | |
3 * Fired when the slider's value changes. | |
4 * | |
5 * @event value-change | |
6 */ | |
7 | |
8 /** | |
9 * Fired when the slider's immediateValue changes. | |
10 * | |
11 * @event immediate-value-change | |
12 */ | |
13 | |
14 /** | |
15 * Fired when the slider's value changes due to user interaction. | |
16 * | |
17 * Changes to the slider's value due to changes in an underlying | |
18 * bound variable will not trigger this event. | |
19 * | |
20 * @event change | |
21 */ | |
22 | |
23 Polymer({ | |
24 is: 'paper-slider', | |
25 | |
26 behaviors: [ | |
27 Polymer.IronRangeBehavior, | |
28 Polymer.IronControlState | |
29 ], | |
30 | |
31 properties: { | |
32 | |
33 /** | |
34 * If true, the slider thumb snaps to tick marks evenly spaced based | |
35 * on the `step` property value. | |
36 */ | |
37 snaps: { | |
38 type: Boolean, | |
39 value: false, | |
40 notify: true | |
41 }, | |
42 | |
43 /** | |
44 * If true, a pin with numeric value label is shown when the slider thumb | |
45 * is pressed. Use for settings for which users need to know the exact | |
46 * value of the setting. | |
47 */ | |
48 pin: { | |
49 type: Boolean, | |
50 value: false, | |
51 notify: true | |
52 }, | |
53 | |
54 /** | |
55 * The number that represents the current secondary progress. | |
56 */ | |
57 secondaryProgress: { | |
58 type: Number, | |
59 value: 0, | |
60 notify: true, | |
61 observer: '_secondaryProgressChanged' | |
62 }, | |
63 | |
64 /** | |
65 * If true, an input is shown and user can use it to set the slider value. | |
66 */ | |
67 editable: { | |
68 type: Boolean, | |
69 value: false | |
70 }, | |
71 | |
72 /** | |
73 * The immediate value of the slider. This value is updated while the use
r | |
74 * is dragging the slider. | |
75 */ | |
76 immediateValue: { | |
77 type: Number, | |
78 value: 0, | |
79 readOnly: true | |
80 }, | |
81 | |
82 /** | |
83 * The maximum number of markers | |
84 */ | |
85 maxMarkers: { | |
86 type: Number, | |
87 value: 0, | |
88 notify: true, | |
89 observer: '_maxMarkersChanged' | |
90 }, | |
91 | |
92 /** | |
93 * If true, the knob is expanded | |
94 */ | |
95 expand: { | |
96 type: Boolean, | |
97 value: false, | |
98 readOnly: true | |
99 }, | |
100 | |
101 /** | |
102 * True when the user is dragging the slider. | |
103 */ | |
104 dragging: { | |
105 type: Boolean, | |
106 value: false, | |
107 readOnly: true | |
108 }, | |
109 | |
110 transiting: { | |
111 type: Boolean, | |
112 value: false, | |
113 readOnly: true | |
114 }, | |
115 | |
116 markers: { | |
117 readOnly: true, | |
118 value: [] | |
119 }, | |
120 }, | |
121 | |
122 observers: [ | |
123 '_updateKnob(value, min, max, snaps, step)', | |
124 '_minChanged(min)', | |
125 '_maxChanged(max)', | |
126 '_valueChanged(value)', | |
127 '_immediateValueChanged(immediateValue)' | |
128 ], | |
129 | |
130 ready: function() { | |
131 // issue polymer/polymer#1305 | |
132 this.async(function() { | |
133 this._updateKnob(this.value); | |
134 this._updateInputValue(); | |
135 }, 1); | |
136 }, | |
137 | |
138 /** | |
139 * Increases value by `step` but not above `max`. | |
140 * @method increment | |
141 */ | |
142 increment: function() { | |
143 this.value = this._clampValue(this.value + this.step); | |
144 }, | |
145 | |
146 /** | |
147 * Decreases value by `step` but not below `min`. | |
148 * @method decrement | |
149 */ | |
150 decrement: function() { | |
151 this.value = this._clampValue(this.value - this.step); | |
152 }, | |
153 | |
154 _updateKnob: function(value) { | |
155 this._positionKnob(this._calcRatio(value)); | |
156 }, | |
157 | |
158 _minChanged: function() { | |
159 this.setAttribute('aria-valuemin', this.min); | |
160 }, | |
161 | |
162 _maxChanged: function() { | |
163 this.setAttribute('aria-valuemax', this.max); | |
164 }, | |
165 | |
166 _valueChanged: function() { | |
167 this.setAttribute('aria-valuenow', this.value); | |
168 this.fire('value-change'); | |
169 }, | |
170 | |
171 _immediateValueChanged: function() { | |
172 if (!this.dragging) { | |
173 this.value = this.immediateValue; | |
174 } | |
175 this._updateInputValue(); | |
176 this.fire('immediate-value-change'); | |
177 }, | |
178 | |
179 _secondaryProgressChanged: function() { | |
180 this.secondaryProgress = this._clampValue(this.secondaryProgress); | |
181 }, | |
182 | |
183 _updateInputValue: function() { | |
184 if (this.editable) { | |
185 this.$$('#input').value = this.immediateValue; | |
186 } | |
187 }, | |
188 | |
189 _expandKnob: function() { | |
190 this._setExpand(true); | |
191 }, | |
192 | |
193 _resetKnob: function() { | |
194 this._expandJob && this._expandJob.stop(); | |
195 this._setExpand(false); | |
196 }, | |
197 | |
198 _positionKnob: function(ratio) { | |
199 this._setImmediateValue(this._calcStep(this._calcKnobPosition(ratio)) || 0
); | |
200 this._setRatio(this.snaps ? this._calcRatio(this.immediateValue) : ratio); | |
201 this.$.sliderKnob.style.left = this.ratio * 100 + '%'; | |
202 }, | |
203 | |
204 _inputChange: function() { | |
205 this.value = this.$$('#input').value; | |
206 this.fire('change'); | |
207 }, | |
208 | |
209 _calcKnobPosition: function(ratio) { | |
210 return (this.max - this.min) * ratio + this.min; | |
211 }, | |
212 | |
213 _onTrack: function(e) { | |
214 switch (event.detail.state) { | |
215 case 'end': | |
216 this._trackEnd(event); | |
217 break; | |
218 case 'track': | |
219 this._trackX(event); | |
220 break; | |
221 case 'start': | |
222 this._trackStart(event); | |
223 break; | |
224 } | |
225 }, | |
226 | |
227 _trackStart: function(e) { | |
228 this._w = this.$.sliderBar.offsetWidth; | |
229 this._x = this.ratio * this._w; | |
230 this._startx = this._x || 0; | |
231 this._minx = - this._startx; | |
232 this._maxx = this._w - this._startx; | |
233 this.$.sliderKnob.classList.add('dragging'); | |
234 this._setDragging(true); | |
235 e.preventDefault(); | |
236 }, | |
237 | |
238 _trackX: function(e) { | |
239 if (!this.dragging) { | |
240 this._trackStart(e); | |
241 } | |
242 var x = Math.min(this._maxx, Math.max(this._minx, e.detail.dx)); | |
243 this._x = this._startx + x; | |
244 this._setImmediateValue(this._calcStep( | |
245 this._calcKnobPosition(this._x / this._w)) || 0); | |
246 var s = this.$.sliderKnob.style; | |
247 s.transform = s.webkitTransform = 'translate3d(' + (this.snaps ? | |
248 (this._calcRatio(this.immediateValue) * this._w) - this._startx : x) +
'px, 0, 0)'; | |
249 }, | |
250 | |
251 _trackEnd: function() { | |
252 var s = this.$.sliderKnob.style; | |
253 s.transform = s.webkitTransform = ''; | |
254 this.$.sliderKnob.classList.remove('dragging'); | |
255 this._setDragging(false); | |
256 this._resetKnob(); | |
257 this.value = this.immediateValue; | |
258 this.fire('change'); | |
259 }, | |
260 | |
261 _knobdown: function(e) { | |
262 e.preventDefault(); | |
263 this._expandKnob(); | |
264 }, | |
265 | |
266 _bardown: function(e) { | |
267 e.preventDefault(); | |
268 this._setTransiting(true); | |
269 this._w = this.$.sliderBar.offsetWidth; | |
270 var rect = this.$.sliderBar.getBoundingClientRect(); | |
271 var ratio = (e.detail.x - rect.left) / this._w; | |
272 this._positionKnob(ratio); | |
273 this._expandJob = this.debounce(this._expandJob, this._expandKnob, 60); | |
274 | |
275 this.async(function() { | |
276 this.fire('change'); | |
277 }); | |
278 }, | |
279 | |
280 _knobTransitionEnd: function(e) { | |
281 if (e.target === this.$.sliderKnob) { | |
282 this._setTransiting(false); | |
283 } | |
284 }, | |
285 | |
286 _maxMarkersChanged: function(maxMarkers) { | |
287 var l = (this.max - this.min) / this.step; | |
288 if (!this.snaps && l > maxMarkers) { | |
289 this._setMarkers([]); | |
290 } else { | |
291 this._setMarkers(new Array(l)); | |
292 } | |
293 }, | |
294 | |
295 _getClassNames: function() { | |
296 var classes = {}; | |
297 | |
298 classes['disabled'] = this.disabled; | |
299 classes['pin'] = this.pin; | |
300 classes['snaps'] = this.snaps; | |
301 classes['ring'] = this.immediateValue <= this.min; | |
302 classes['expand'] = this.expand; | |
303 classes['dragging'] = this.dragging; | |
304 classes['transiting'] = this.transiting; | |
305 classes['editable'] = this.editable; | |
306 | |
307 return Object.keys(classes).filter( | |
308 function(className) { | |
309 return classes[className]; | |
310 }).join(' '); | |
311 }, | |
312 | |
313 _incrementKey: function(ev, keys) { | |
314 if (keys.key === 'end') { | |
315 this.value = this.max; | |
316 } else { | |
317 this.increment(); | |
318 } | |
319 this.fire('change'); | |
320 }, | |
321 | |
322 _decrementKey: function(ev, keys) { | |
323 if (keys.key === 'home') { | |
324 this.value = this.min; | |
325 } else { | |
326 this.decrement(); | |
327 } | |
328 this.fire('change'); | |
329 } | |
330 }) | |
OLD | NEW |