/* globals Gui, Polymer */ // [ ] arrow keys // [ ] min() max() step() commands of yore Gui.register( 'dat-gui-number', function( value ) { return typeof value == 'number'; } ); Polymer( 'dat-gui-number', { value: 0, decimals: 3, computed: { slider: 'min !== undefined && max !== undefined' }, ready: function() { var _this = this; window.addEventListener( 'keydown', function( e ) { if ( e.keyCode == 18 ) { _this._alt = true; } }, false ); window.addEventListener( 'keyup', function( e ) { if ( e.keyCode == 18 ) { _this._alt = false; } }, false ); // this.super(); }, init: function( min, max, step ) { this.min = min; this.max = max; this.step = step; }, // Observers // ------------------------------- valueChanged: function( newValue ) { if ( this.step !== undefined ) { this.value = Math.round( this.value / this.step ) * this.step; } if ( this.min !== undefined ) { this.value = Math.max( this.value, this.min ); } if ( this.max !== undefined ) { this.value = Math.min( this.value, this.max ); } this.super(); }, minChanged: function() { this.value = Math.max( this.value, this.min ); this.update(); }, maxChanged: function() { this.value = Math.min( this.value, this.max ); this.update(); }, update: function() { var ratio = this.map( this.value, this.min, this.max, 0, 1 ); if ( this.min < 0 && this.max > 0 ) { this.$.container.classList.add( 'straddle-zero' ); var zero = this.map( 0, this.min, this.max, 0, 1 ); if ( this.value >= 0 ) { this.$.fill.style.left = zero * 100 + '%'; this.$.fill.style.width = ( ratio - zero ) * 100 + '%'; this.$.fill.style.right = ''; } else { this.$.fill.style.left = ''; this.$.fill.style.width = ( zero - ratio ) * 100 + '%'; this.$.fill.style.right = ( 1 - zero ) * 100 + '%'; } } else { this.$.container.classList.remove( 'straddle-zero' ); if ( this.max > 0 ) { this.$.fill.style.left = 0; this.$.fill.style.width = ratio * 100 + '%'; this.$.fill.style.right = ''; } else { this.$.fill.style.left = ''; this.$.fill.style.width = ( 1 - ratio ) * 100 + '%'; this.$.fill.style.right = 0; } } this.$.knob.style.left = ratio * 100 + '%'; this.$.container.classList.toggle( 'positive', this.value >= 0 ); this.$.container.classList.toggle( 'negative', this.value < 0 ); this.super(); }, // Events // ------------------------------- click: function( e ) { this.$.input.select(); }, keydown: function( e ) { if ( e.keyCode == 13 ) { this.$.input.blur(); } }, down: function( e ) { e.preventDefault(); this._rect = this.$.track.getBoundingClientRect(); if ( !this._alt ) { this.value = this.valueFromX( e.x ); } this.fire( 'sliderDown' ); }, up: function( e ) { // this.$.container.classList.add( 'transition' ); this.fire( 'sliderUp' ); }, trackstart: function( e ) { // this.$.container.classList.remove( 'transition' ); this._dragFriction = 1; }, trackx: function( e ) { if ( this.step === undefined ) { var dv = this.valueFromDX( e.ddx ); if ( this._alt ) { dv /= 10; } this.value += dv * this._dragFriction; } else { this.value = this.valueFromX( e.pageX ); } }, tracky: function( e ) { this._dragFriction = Math.max( 0.01, Math.min( 1, this.map( e.dy, 50, 300, 1, 0.1 ) ) ); }, blur: function( e ) { var v = parseFloat( this.$.input.value ); if ( v === v ) { this.value = v; } }, // Filters // ------------------------------- truncate: function( v ) { if ( v % 1 !== 0 && this.decimals !== undefined ) { return this.limitDecimals( v, this.decimals ); } else { return v; } }, // Helpers // ------------------------------- limitDecimals: function( v, maxDecimals ) { var str = v.toString(); var numDecimals = str.substring( str.indexOf( '.' ) + 1 ).length; str = v.toFixed( Math.min( numDecimals, this.decimals ) ); for ( var z, i = 0, l = str.length; i < l; i++ ) { if ( str.charAt( i ) !== '0' ) { z = i; } } return str.substring( 0, z + 1 ); }, valueFromX: function( x ) { return this.map( x, this._rect.left, this._rect.right, this.min, this.max ); }, valueFromDX: function( dx ) { return this.map( dx, 0, this._rect.width, 0, this.max - this.min ); } } );