diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1e501e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bower_components +node_modules \ No newline at end of file diff --git a/elements/base-controller.html b/elements/base-controller.html index 3dd2fc5..13d18e0 100644 --- a/elements/base-controller.html +++ b/elements/base-controller.html @@ -1,66 +1,3 @@ - - - - - - - - - - - - - - - - \ No newline at end of file + + \ No newline at end of file diff --git a/elements/base-controller.js b/elements/base-controller.js new file mode 100644 index 0000000..8f7bc15 --- /dev/null +++ b/elements/base-controller.js @@ -0,0 +1,87 @@ +Polymer('base-controller', { + + value: null, + object: null, + property: null, + + 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(); + + }, + + + // Observers + // ------------------------------- + + objectChanged: function( oldObject, newObject ) { + + if ( oldObject && this.property ) { + this.unbind( oldObject ); + } + + if ( newObject && this.property ) { + this.bind(); + } + + }, + + propertyChanged: function( oldProperty, newProperty ) { + + if ( oldProperty && this.object ) { + this.unbind( this.object ); + } + + if ( newProperty && this.object ) { + this.bind(); + } + + }, + + valueChanged: function() { + + if ( this.object && this.property ) { + this.object[ this.property ] = this.value; + } + + this.update(); + + }, + + 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 + // ------------------------------- + + map: function( x, a, b, c, d ) { + return ( x - a ) / ( b - a ) * ( d - c ) + c; + } + +}); \ No newline at end of file diff --git a/elements/gui-panel.css b/elements/gui-panel.css new file mode 100644 index 0000000..022e7de --- /dev/null +++ b/elements/gui-panel.css @@ -0,0 +1,6 @@ +:host { + position: absolute; + top: 0; + right: 20px; + width: 300px; +} diff --git a/elements/gui-panel.html b/elements/gui-panel.html index cfd4527..ce86945 100644 --- a/elements/gui-panel.html +++ b/elements/gui-panel.html @@ -1,17 +1,12 @@ - + - + @@ -21,14 +16,6 @@ - + \ No newline at end of file diff --git a/elements/gui-panel.js b/elements/gui-panel.js new file mode 100644 index 0000000..b9f0cd8 --- /dev/null +++ b/elements/gui-panel.js @@ -0,0 +1,7 @@ +Polymer('gui-panel', { + + ready: function() { + + } + +}); \ No newline at end of file diff --git a/elements/gui-panel.styl b/elements/gui-panel.styl new file mode 100644 index 0000000..368df8e --- /dev/null +++ b/elements/gui-panel.styl @@ -0,0 +1,6 @@ +:host { + position: absolute; + top: 0; + right: 20px; + width: 300px; +} diff --git a/elements/gui-row.css b/elements/gui-row.css new file mode 100644 index 0000000..672c368 --- /dev/null +++ b/elements/gui-row.css @@ -0,0 +1,18 @@ +#row { + -webkit-text-select: none; + background: #e74400; +} +#name { + font: 500 11px 'Roboto', sans-serif; + color: #fff; + -webkit-font-smoothing: antialiased; + -o-text-overflow: ellipsis; + text-overflow: ellipsis; + word-wrap: break-word; + overflow: hidden; + width: 33%; + padding: 0 10px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} diff --git a/elements/gui-row.html b/elements/gui-row.html index ee9c2fc..43d90bb 100644 --- a/elements/gui-row.html +++ b/elements/gui-row.html @@ -4,25 +4,7 @@ - + {{ name }} @@ -35,14 +17,6 @@ - + \ No newline at end of file diff --git a/elements/gui-row.js b/elements/gui-row.js new file mode 100644 index 0000000..cc7e58f --- /dev/null +++ b/elements/gui-row.js @@ -0,0 +1,7 @@ +Polymer('gui-row', { + + ready: function() { + + } + +}); \ No newline at end of file diff --git a/elements/gui-row.styl b/elements/gui-row.styl new file mode 100644 index 0000000..87a1844 --- /dev/null +++ b/elements/gui-row.styl @@ -0,0 +1,20 @@ +@import 'shared'; + +#row { + -webkit-text-select: none; + background: #e74400; +} + +#name { + + font(); + + text-overflow: ellipsis; + word-wrap: break-word; + overflow: hidden; + width: 33%; + padding: 0 10px; + box-sizing: border-box; +} + + diff --git a/elements/number-controller.css b/elements/number-controller.css index a83fdc1..adf73df 100644 --- a/elements/number-controller.css +++ b/elements/number-controller.css @@ -1,97 +1,87 @@ :host { - display: block; - -webkit-text-select: none; - font-size: 0; - height: 100%; + display: block; + text-select: none; + font-size: 0; + height: 100%; } - -:host * { - margin: 0; +#track-container { + height: 100%; + width: 100%; + height: 30px; } - -#track-container { - height: 100%; - width: 100%; - height: 30px; +#track { + width: 100%; + height: 1px; + -webkit-border-radius: 1px; + border-radius: 1px; + display: inline-block; + position: relative; + background: rgba(0,0,0,0.1); } - -#track { - width: 100%; - height: 11px; - display: inline-block; - position: relative; - border-radius: 20px; - background: rgba( 0, 0, 0, 0.1 ); - -} - #fill { - height: 9px; - margin-top: 1px; - margin-left: 1px; - border-radius: 10px; - position: absolute; - background: #fff; - pointer-events: none; + height: 1px; + margin-top: 0px; + margin-left: 1px; + -webkit-border-radius: 1px; + border-radius: 1px; + position: absolute; + background: #fff; + pointer-events: none; } - - -#container.transition #knob { - -webkit-transition: left 0.1s ease-out; +#knob { + width: 6px; + height: 6px; + margin-left: -3px; + margin-top: -3px; + -webkit-transition: -webkit-transform 0.2s cubic-bezier(0.25, 0.25, 0, 1); + -moz-transition: -moz-transform 0.2s cubic-bezier(0.25, 0.25, 0, 1); + -o-transition: -o-transform 0.2s cubic-bezier(0.25, 0.25, 0, 1); + -ms-transition: -ms-transform 0.2s cubic-bezier(0.25, 0.25, 0, 1); + transition: transform 0.2s cubic-bezier(0.25, 0.25, 0, 1); + pointer-events: none; + position: absolute; + background-color: #fff; + -webkit-border-radius: 100%; + border-radius: 100%; } - -#container.transition #fill { - -webkit-transition: width 0.1s ease-out; +#track-container:hover #knob { + -webkit-transform: scale(1.8); + -moz-transform: scale(1.8); + -o-transform: scale(1.8); + -ms-transform: scale(1.8); + transform: scale(1.8); } - -.straddle-zero #knob { - position: absolute; - pointer-events: none; - width: 9px; - height: 9px; - margin-top: 1px; - background-color: #fff; - border-radius: 100%; +#track-container:active #knob { + -webkit-transform: scale(1.4); + -moz-transform: scale(1.4); + -o-transform: scale(1.4); + -ms-transform: scale(1.4); + transform: scale(1.4); } - -.straddle-zero.negative #knob { - margin-left: -3px; +input { + font: 500 11px 'Roboto', sans-serif; + color: #fff; + -webkit-font-smoothing: antialiased; + height: 30px; + padding-left: 5px; + display: inline-block; + background: transparent; + border: 0; + text-align: center; + outline: none; + width: 20%; + -webkit-transition: width 0.2s cubic-bezier(0.25, 0.25, 0, 1); + -moz-transition: width 0.2s cubic-bezier(0.25, 0.25, 0, 1); + -o-transition: width 0.2s cubic-bezier(0.25, 0.25, 0, 1); + -ms-transition: width 0.2s cubic-bezier(0.25, 0.25, 0, 1); + transition: width 0.2s cubic-bezier(0.25, 0.25, 0, 1); } -.straddle-zero.positive #knob { - margin-left: -5px; -} - -/* -.negative #knob, -.negative #fill { - background: #333; -} -*/ -input { - - font: 11px 'Montserrat', sans-serif; - color: #fff; - -webkit-font-smoothing: antialiased; - - padding-left: 5px; - display: inline-block; - vertical-align: top; - background: transparent; - border-radius: 10px; - height: 30px; - border: 0; - text-align: center; - outline: none; - width: 20%; - -webkit-transition: width 0.24s cubic-bezier(.25,.25,0,1); -} - - input:hover { - width: 28%; -} - -input:focus { - width: 65%; + width: 28%; +} +input:focus { + width: 50%; +} +input::selection { + background-color: rgba(0,0,0,0.1); } - diff --git a/elements/number-controller.html b/elements/number-controller.html index 9d03404..8b3bf37 100644 --- a/elements/number-controller.html +++ b/elements/number-controller.html @@ -1,17 +1,30 @@ +[ ] only validate input box on blur, not on keydown +[ ] enter key blurs + +[x] dy to drag friction +[x] negative slider +[x] hover behavior + +--> + - + + + @@ -22,19 +35,15 @@ dy to drag friction - - - - - - - + + @@ -49,167 +58,4 @@ dy to drag friction - - - + \ No newline at end of file diff --git a/elements/number-controller.js b/elements/number-controller.js new file mode 100644 index 0000000..531104d --- /dev/null +++ b/elements/number-controller.js @@ -0,0 +1,136 @@ +Polymer('number-controller', { + + min: 0, + max: 100, + step: 1, + value: 50, + + 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(); + + }, + + + // Observers + // ------------------------------- + + valueChanged: function() { + this.value = Math.max( this.value, this.min ); + 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(); + }, + + down: function( e ) { + e.preventDefault(); + this._rect = this.$.track.getBoundingClientRect(); + if ( !this._alt ) this.setValueFromX( e.x ); + }, + + trackstart: function( e ) { + this._dragFriction = 1; + }, + + trackx: function( e ) { + var dv = this.setValueFromDX( e.ddx ); + if ( this._alt ) dv /= 10; + this.value += dv * this._dragFriction; + }, + + tracky: function( e ) { + this._dragFriction = Math.max( 0.01, Math.min( 1, this.map( e.dy, 50, 300, 1, 0.1 ) ) ); + }, + + // Helpers + // ------------------------------- + + setValueFromX: function( x ) { + this.value = this.map( x, this._rect.left, this._rect.right, this.min, this.max ); + }, + + setValueFromDX: function( dx ) { + return this.map( dx, 0, this._rect.width, 0, this.max - this.min ); + } + +}); \ No newline at end of file diff --git a/elements/number-controller.styl b/elements/number-controller.styl new file mode 100644 index 0000000..a000f10 --- /dev/null +++ b/elements/number-controller.styl @@ -0,0 +1,98 @@ +@import 'shared'; + +track-height = 30px +track-size = 1px; +fill-size = 1px; +knob-size = 6px + +:host { + display: block; + text-select: none; + font-size: 0; + height: 100%; +} + +#track-container { + height: 100%; + width: 100%; + height: track-height; +} + +#track { + width: 100%; + height: track-size; + border-radius: track-size; + display: inline-block; + position: relative; + background: dark; +} + +#fill { + height: fill-size; + margin-top: ( ( track-size - fill-size ) / 2 ); + margin-left: 1px; + border-radius: fill-size; + position: absolute; + background: #fff; + pointer-events: none; +} + + +#knob { + + width: knob-size; + height: knob-size; + + margin-left: -( knob-size / 2 ); + margin-top: -( knob-size / 2 ); + + transition: transform 0.2s ease; + + pointer-events: none; + position: absolute; + + background-color: #fff; + border-radius: 100%; + +} + +#track-container:hover #knob { + + transform: scale( 1.8 ) + +} + +#track-container:active #knob { + + transform: scale( 1.4 ) + +} + +input { + + font(); + + height: track-height; + + padding-left: 5px; + display: inline-block; + background: transparent; + border: 0; + text-align: center; + outline: none; + width: 20%; + transition: width 0.2s ease; + +} + +input:hover { + width: 28%; +} + +input:focus { + width: 50%; +} + +input::selection { + background-color: dark; +} diff --git a/elements/shared.css b/elements/shared.css new file mode 100644 index 0000000..e69de29 diff --git a/elements/shared.styl b/elements/shared.styl new file mode 100644 index 0000000..a49555b --- /dev/null +++ b/elements/shared.styl @@ -0,0 +1,9 @@ +@import 'nib'; + +ease = cubic-bezier( .25, .25, 0, 1 ) +dark = rgba( 0, 0, 0, 0.1 ); + +font() + font: 500 11px 'Roboto', sans-serif; + color: #fff; + -webkit-font-smoothing: antialiased; \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..843f00b --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,33 @@ +/* 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; +} + +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(); + } +}); diff --git a/index.html b/index.html index 3f67441..6b1c9b3 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - + @@ -20,23 +20,23 @@ - + - - + + - + - + - + @@ -44,30 +44,36 @@