Chromium Code Reviews| 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 /** | |
| 6 * @fileoverview | |
| 7 * cr-slider wraps a paper-slider. It maps the slider's values from a linear UI | |
| 8 * range to a range of real values. When |value| does not map exactly to a | |
| 9 * tick mark, it interpolates to the nearest tick. | |
| 10 * | |
| 11 * Unlike paper-slider, there is no distinction between value and | |
| 12 * immediateValue; when either changes, the |value| property is updated. | |
| 13 */ | |
| 14 Polymer({ | |
| 15 is: 'cr-slider', | |
| 16 | |
| 17 properties: { | |
| 18 /** The value the slider represents and controls. */ | |
| 19 value: { | |
| 20 type: Number, | |
| 21 notify: true, | |
| 22 }, | |
| 23 | |
| 24 /** @type {!Array<number>} Values corresponding to each tick. */ | |
| 25 tickValues: Array, | |
| 26 | |
| 27 disabled: { | |
| 28 type: Boolean, | |
| 29 value: false, | |
| 30 reflectToAttribute: true, | |
| 31 }, | |
| 32 | |
| 33 snaps: { | |
| 34 type: Boolean, | |
| 35 value: false, | |
| 36 }, | |
| 37 | |
| 38 maxMarkers: Number, | |
| 39 }, | |
| 40 | |
| 41 observers: [ | |
| 42 'valueChanged_(value, tickValues.*)', | |
| 43 ], | |
| 44 | |
| 45 /** | |
| 46 * Sets the |value| property to the value corresponding to the knob position | |
| 47 * after a user action. | |
| 48 * @private | |
| 49 */ | |
| 50 onSliderChange_: function() { | |
| 51 var index = this.$.slider.immediateValue; | |
| 52 this.value = this.tickValues[index]; | |
| 53 }, | |
| 54 | |
| 55 /** | |
| 56 * Updates the knob position when |value| changes. If the knob is still being | |
| 57 * dragged, this instead forces |value| back to the current position. | |
| 58 * @private | |
| 59 */ | |
| 60 valueChanged_: function() { | |
| 61 // First update the slider settings if |tickValues| was set. | |
| 62 this.$.slider.max = this.tickValues.length - 1; | |
| 63 | |
| 64 if (this.$.slider.dragging && | |
| 65 this.value != this.tickValues[this.$.slider.immediateValue]) { | |
| 66 // The value changed outside cr-slider but we're still holding the knob, | |
| 67 // so set the value back to where the knob was. | |
| 68 // Async so we don't confuse Polymer's data binding. | |
| 69 this.async(function() { | |
| 70 this.value = this.tickValues[this.$.slider.immediateValue]; | |
| 71 }); | |
| 72 return; | |
| 73 } | |
| 74 | |
| 75 // Convert from the public |value| to the slider index (where the knob | |
| 76 // should be positioned on the slider). | |
| 77 var sliderIndex = this.tickValues.indexOf(this.value); | |
| 78 if (sliderIndex == -1) { | |
| 79 // No exact match. | |
| 80 sliderIndex = this.findNearestIndex_(this.tickValues, this.value); | |
| 81 } | |
| 82 this.$.slider.value = sliderIndex; | |
| 83 }, | |
| 84 | |
| 85 /** | |
| 86 * Returns the index of the item in |arr| closest to |value|. | |
| 87 * @param {!Array<number>} arr | |
| 88 * @param {number} value | |
| 89 * @return {number} | |
| 90 * @private | |
| 91 */ | |
| 92 findNearestIndex_: function(arr, value) { | |
| 93 var closestIndex; | |
| 94 var minDifference = Number.MAX_VALUE; | |
| 95 for (var i = 0; i < arr.length; i++) { | |
| 96 var difference = Math.abs(arr[i] - value); | |
| 97 if (difference < minDifference) { | |
| 98 closestIndex = i; | |
| 99 minDifference = difference; | |
| 100 } | |
| 101 } | |
| 102 | |
| 103 assert(typeof closestIndex != 'undefined'); | |
|
michaelpg
2016/05/18 17:05:49
basically asserts the same thing, but closure-frie
| |
| 104 return closestIndex; | |
| 105 }, | |
| 106 }); | |
| OLD | NEW |