diff --git a/.gitignore b/.gitignore index 1e501e3..37102db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -bower_components -node_modules \ No newline at end of file +components +node_modules +*.css \ No newline at end of file diff --git a/build/index.html b/build/index.html new file mode 100644 index 0000000..dd46b43 --- /dev/null +++ b/build/index.html @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/elements/base-controller.js b/elements/base-controller.js index 8f7bc15..808b4db 100644 --- a/elements/base-controller.js +++ b/elements/base-controller.js @@ -1,3 +1,10 @@ +/* + +[ ] onChange( ) +[ ] onFinishChange( ) + +*/ + Polymer('base-controller', { value: null, @@ -7,31 +14,45 @@ Polymer('base-controller', { ready: function() { var _this = this; - this._observer = function( changes ) { - - changes.forEach( function( c ) { - - if ( c.name == _this.property ) { - _this.value = _this.object[ _this.property ]; - } - - } ); - - }; - this.update(); }, + bind: function() { + + if ( this._observer ) { + this._observer.close(); + delete this._observer; + } + + var _this = this; + + this._observer = new PathObserver( this.object, this.property ); + this._observer.open( function( newValue ) { + + _this.value = newValue; + + } ); + + + this.value = this.object[ this.property ]; + + }, + + update: function() {}, + + listen: function() { + + console.warn( 'controller.listen() is deprecated. All controllers are listened for free.' ); + + }, + // Observers // ------------------------------- objectChanged: function( oldObject, newObject ) { - if ( oldObject && this.property ) { - this.unbind( oldObject ); - } if ( newObject && this.property ) { this.bind(); @@ -41,10 +62,6 @@ Polymer('base-controller', { propertyChanged: function( oldProperty, newProperty ) { - if ( oldProperty && this.object ) { - this.unbind( this.object ); - } - if ( newProperty && this.object ) { this.bind(); } @@ -61,22 +78,7 @@ Polymer('base-controller', { }, - bind: function() { - Object.observe( this.object, this._observer ); - this.value = this.object[ this.property ]; - - }, - - unbind: function( object ) { - - Object.unobserve( object, this._observer ); - - }, - - update: function() {}, - - // Helpers // ------------------------------- diff --git a/elements/gui-panel.js b/elements/gui-panel.js index b9f0cd8..9333293 100644 --- a/elements/gui-panel.js +++ b/elements/gui-panel.js @@ -2,6 +2,45 @@ Polymer('gui-panel', { ready: function() { + document.body.appendChild( this ); + + }, + + add: function( object, property ) { + + var row = document.createElement( 'gui-row' ); + row.name = property; + + var controller; + + if ( typeof object[ property ] == 'number' ) { + + controller = document.createElement( 'number-controller' ); + + if ( arguments[ 2 ] !== undefined ) controller.min = arguments[ 2 ]; + if ( arguments[ 3 ] !== undefined ) controller.max = arguments[ 3 ]; + if ( arguments[ 4 ] !== undefined ) controller.step = arguments[ 4 ]; + + } + + controller.object = object; + controller.property = property; + + controller.name = function( name ) { + row.name = name; + }; + + row.appendChild( controller ); + this.appendChild( row ); + + return controller; + + }, + + listenAll: function() { + + console.warn( 'controller.listenAll() is deprecated. All controllers are listened for free.' ); + } }); \ No newline at end of file diff --git a/elements/gui-row.css b/elements/gui-row.css index 672c368..9351f7f 100644 --- a/elements/gui-row.css +++ b/elements/gui-row.css @@ -1,6 +1,6 @@ #row { -webkit-text-select: none; - background: #e74400; + background: #1a1a1a; } #name { font: 500 11px 'Roboto', sans-serif; diff --git a/elements/gui-row.html b/elements/gui-row.html index 43d90bb..ff5f55c 100644 --- a/elements/gui-row.html +++ b/elements/gui-row.html @@ -1,6 +1,9 @@ - + diff --git a/elements/number-controller.js b/elements/number-controller.js index 531104d..df0dbdd 100644 --- a/elements/number-controller.js +++ b/elements/number-controller.js @@ -1,8 +1,26 @@ +/* + +[ ] arrow keys + +[ ] only validate input box on blur, not on keydown +[ ] enter key blurs + +[ ] min( ) max( ) step( ) commands of yore + +[x] sig figs +[x] step +[x] dy to drag friction +[x] negative slider +[x] hover behavior + +*/ + Polymer('number-controller', { min: 0, max: 100, - step: 1, + step: null, + decimals: 3, value: 50, ready: function() { @@ -28,6 +46,9 @@ Polymer('number-controller', { valueChanged: function() { this.value = Math.max( this.value, this.min ); this.value = Math.min( this.value, this.max ); + if ( this.step !== null ) { + this.value = Math.round( this.value / this.step ) * this.step; + } this.super(); }, @@ -105,31 +126,75 @@ Polymer('number-controller', { down: function( e ) { e.preventDefault(); this._rect = this.$.track.getBoundingClientRect(); - if ( !this._alt ) this.setValueFromX( e.x ); + if ( !this._alt ) this.value = this.valueFromX( e.x ); + }, + + up: function( e ) { + // this.$.container.classList.add( 'transition' ); }, trackstart: function( e ) { + // this.$.container.classList.remove( 'transition' ); this._dragFriction = 1; }, trackx: function( e ) { - var dv = this.setValueFromDX( e.ddx ); - if ( this._alt ) dv /= 10; - this.value += dv * this._dragFriction; + + if ( this.step == null ) { + + 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 ) { + this.value = parseFloat( this.$.input.value ); + }, + + keydown: function( e ) { + if ( e.keyCode == 13 ) { + this.$.input.blur(); + } + }, + + + // Filters + // ------------------------------- + + truncate: function( v ) { + + if ( v % 1 !== 0 && this.decimals !== null ) { + + var s = v.toString(); + var numDecimals = s.substring( s.indexOf( '.' ) ).length; + + return v.toFixed( Math.min( numDecimals, this.decimals ) ); + + } else { + return v; + } + + }, + + // Helpers // ------------------------------- - setValueFromX: function( x ) { - this.value = this.map( x, this._rect.left, this._rect.right, this.min, this.max ); + valueFromX: function( x ) { + return this.map( x, this._rect.left, this._rect.right, this.min, this.max ); }, - setValueFromDX: function( dx ) { + valueFromDX: function( dx ) { return this.map( dx, 0, this._rect.width, 0, this.max - this.min ); } diff --git a/elements/number-controller.styl b/elements/number-controller.styl index a000f10..0eccd5f 100644 --- a/elements/number-controller.styl +++ b/elements/number-controller.styl @@ -1,5 +1,8 @@ @import 'shared'; +fill-color = number-color +track-color = light + track-height = 30px track-size = 1px; fill-size = 1px; @@ -7,13 +10,13 @@ knob-size = 6px :host { display: block; - text-select: none; font-size: 0; height: 100%; + user-select: none; } + #track-container { - height: 100%; width: 100%; height: track-height; } @@ -24,7 +27,7 @@ knob-size = 6px border-radius: track-size; display: inline-block; position: relative; - background: dark; + background: track-color; } #fill { @@ -33,7 +36,7 @@ knob-size = 6px margin-left: 1px; border-radius: fill-size; position: absolute; - background: #fff; + background: fill-color; pointer-events: none; } @@ -46,35 +49,39 @@ knob-size = 6px margin-left: -( knob-size / 2 ); margin-top: -( knob-size / 2 ); - transition: transform 0.2s ease; + transition: transform 0.1s ease; pointer-events: none; position: absolute; - background-color: #fff; + background-color: fill-color; border-radius: 100%; } #track-container:hover #knob { - - transform: scale( 1.8 ) - + transform: scale( 2 ) } #track-container:active #knob { - - transform: scale( 1.4 ) - + transform: scale( 1.5 ) } +// .transition #knob { +// transition: left 0.2s ease, transform 0.1s ease; +// } + +// .transition #fill { +// transition: left 0.2s ease, right 0.2s ease, width 0.2s ease; +// } + input { font(); height: track-height; - padding-left: 5px; + margin-left: 5px; display: inline-block; background: transparent; border: 0; @@ -94,5 +101,5 @@ input:focus { } input::selection { - background-color: dark; + background-color: light; } diff --git a/elements/shared.styl b/elements/shared.styl index a49555b..a86f435 100644 --- a/elements/shared.styl +++ b/elements/shared.styl @@ -1,8 +1,13 @@ @import 'nib'; +number-color = #25a0d8 + ease = cubic-bezier( .25, .25, 0, 1 ) + +light = rgba( 255, 255, 255, 0.25 ) dark = rgba( 0, 0, 0, 0.1 ); + font() font: 500 11px 'Roboto', sans-serif; color: #fff; diff --git a/gulpfile.js b/gulpfile.js index 843f00b..f9cf209 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,33 +1,37 @@ -/* jshint node: true */ -"use strict"; - -var gulp = require("gulp"), - stylus = require("gulp-stylus"), - nib = require("nib"), - watch = require("gulp-watch"), - argv = require("yargs").argv - -function compileCss() { - var deferred = Q.defer(); - - gulp.src("elements/*.styl") - .pipe(stylus({use: [nib()]})) - .pipe(gulp.dest("elements")) - .on("end", function() { - deferred.resolve(); - }); - - return deferred.promise; +var gulp = require( 'gulp' ), + stylus = require( 'gulp-stylus' ), + nib = require( 'nib' ), + watch = require( 'gulp-watch' ), + vulcan = require( 'gulp-vulcanize' ); + +var paths = { + style: './elements/*.styl' } -gulp.task("stylus", function () { - if (argv.watch) { - watch({glob: "elements/*.styl"}, function(files) { - return files - .pipe(stylus({use: [nib()]})) - .pipe(gulp.dest("elements")); - }); - } else { - return compileCss(); - } -}); +function compileCSS( files ) { + return files + .pipe( stylus( { use: [ nib() ] } ) ) + .pipe( gulp.dest( './elements/' ) ); +} + +// gulp.task( 'stylus', function() { +// watch( { glob: "./elements/*.styl" }, compileCSS ); +// }); + +gulp.task( 'default', function() { + + compileCSS( gulp.src( paths.style ) ); + + gulp.src( './index.html' ) + .pipe( vulcan( { + dest: 'build', + inline: true, + strip: true + } ) ); + + +} ); + +gulp.task( 'watch', function() { + watch( { glob: paths.style }, compileCSS ); +} ); \ No newline at end of file diff --git a/index-built.html b/index-built.html new file mode 100644 index 0000000..5f86cb7 --- /dev/null +++ b/index-built.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/index.html b/index.html index 6b1c9b3..1922857 100644 --- a/index.html +++ b/index.html @@ -1,86 +1,17 @@ - - + + - - - - - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..22eece4 --- /dev/null +++ b/index.js @@ -0,0 +1,21 @@ +var object = { + "listen4Free": 25, + "step": 10, + "straddleZero": 0, + "maxIsNegative": -2, +}; + +// How do we kill polymer-ready ... +document.addEventListener( 'polymer-ready', function() { + + var gui = new GUI(); + gui.add( object, 'listen4Free' ); + gui.add( object, 'listen4Free' ); + gui.add( object, 'listen4Free' ); + gui.add( object, 'listen4Free' ).name( 'customName' ); + gui.add( object, 'step', 0, 50, 5 ); + gui.add( object, 'straddleZero', -5, 5 ); + + var c = gui.add( object, 'maxIsNegative', -5, -2 ); + +}); \ No newline at end of file diff --git a/package.json b/package.json index c2b0b78..0bb8c14 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "devDependencies": { "gulp": "^3.8.7", "gulp-stylus": "^1.3.0", + "gulp-vulcanize": "^1.0.0", "gulp-watch": "^0.6.9", - "nib": "^1.0.3", - "yargs": "^1.3.1" + "nib": "^1.0.3" } }