Home | History | Annotate | Download | only in iron-range-behavior
      1 <!--
      2 @license
      3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
      4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
      5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
      6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
      7 Code distributed by Google as part of the polymer project is also
      8 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
      9 -->
     10 
     11 <link rel="import" href="../polymer/polymer.html">
     12 
     13 <script>
     14 
     15  /**
     16  * `iron-range-behavior` provides the behavior for something with a minimum to maximum range.
     17  *
     18  * @demo demo/index.html
     19  * @polymerBehavior
     20  */
     21  Polymer.IronRangeBehavior = {
     22 
     23   properties: {
     24 
     25     /**
     26      * The number that represents the current value.
     27      */
     28     value: {
     29       type: Number,
     30       value: 0,
     31       notify: true,
     32       reflectToAttribute: true
     33     },
     34 
     35     /**
     36      * The number that indicates the minimum value of the range.
     37      */
     38     min: {
     39       type: Number,
     40       value: 0,
     41       notify: true
     42     },
     43 
     44     /**
     45      * The number that indicates the maximum value of the range.
     46      */
     47     max: {
     48       type: Number,
     49       value: 100,
     50       notify: true
     51     },
     52 
     53     /**
     54      * Specifies the value granularity of the range's value.
     55      */
     56     step: {
     57       type: Number,
     58       value: 1,
     59       notify: true
     60     },
     61 
     62     /**
     63      * Returns the ratio of the value.
     64      */
     65     ratio: {
     66       type: Number,
     67       value: 0,
     68       readOnly: true,
     69       notify: true
     70     },
     71   },
     72 
     73   observers: [
     74     '_update(value, min, max, step)'
     75   ],
     76 
     77   _calcRatio: function(value) {
     78     return (this._clampValue(value) - this.min) / (this.max - this.min);
     79   },
     80 
     81   _clampValue: function(value) {
     82     return Math.min(this.max, Math.max(this.min, this._calcStep(value)));
     83   },
     84 
     85   _calcStep: function(value) {
     86     // polymer/issues/2493
     87     value = parseFloat(value);
     88 
     89     if (!this.step) {
     90       return value;
     91     }
     92 
     93     var numSteps = Math.round((value - this.min) / this.step);
     94     if (this.step < 1) {
     95      /**
     96       * For small values of this.step, if we calculate the step using
     97       * `Math.round(value / step) * step` we may hit a precision point issue
     98       * eg. 0.1 * 0.2 =  0.020000000000000004
     99       * http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
    100       *
    101       * as a work around we can divide by the reciprocal of `step`
    102       */
    103       return numSteps / (1 / this.step) + this.min;
    104     } else {
    105       return numSteps * this.step + this.min;
    106     }
    107   },
    108 
    109   _validateValue: function() {
    110     var v = this._clampValue(this.value);
    111     this.value = this.oldValue = isNaN(v) ? this.oldValue : v;
    112     return this.value !== v;
    113   },
    114 
    115   _update: function() {
    116     this._validateValue();
    117     this._setRatio(this._calcRatio(this.value) * 100);
    118   }
    119 
    120 };
    121 </script>
    122