dat.gui/elements/controller-number/controller-number.js

271 lines
4.7 KiB
JavaScript
Raw Normal View History

/* globals Gui, Polymer */
2014-09-04 04:14:36 +00:00
'use strict';
2014-08-27 00:01:15 +00:00
/*
[ ] arrow keys
[ ] min() max() step() commands of yore
2014-08-27 00:01:15 +00:00
[x] only validate input box on blur, not on keydown
[x] enter key blurs
[x] decimals
[x] step
[x] dy to drag friction
[x] negative slider
[x] hover behavior
*/
Gui.register('controller-number', function(value) {
2014-08-27 00:01:15 +00:00
return typeof value == 'number';
2014-08-27 00:01:15 +00:00
});
2014-08-27 00:01:15 +00:00
Polymer('controller-number', {
2014-08-27 00:01:15 +00:00
value: 0,
decimals: 3,
computed: {
2014-08-27 00:01:15 +00:00
slider: 'min !== undefined && max !== undefined'
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
ready: function() {
2014-08-27 00:01:15 +00:00
var _this = this;
2014-08-27 00:01:15 +00:00
window.addEventListener('keydown', function(e) {
2014-09-04 04:14:36 +00:00
if (e.keyCode == 18) {
_this._alt = true;
}
}, false);
2014-08-27 00:01:15 +00:00
window.addEventListener('keyup', function(e) {
2014-09-04 04:14:36 +00:00
if (e.keyCode == 18) {
_this._alt = false;
}
}, false);
2014-08-27 00:01:15 +00:00
// this.super();
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
init: function(min, max, step) {
2014-08-27 00:01:15 +00:00
this.min = min;
this.max = max;
this.step = step;
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
// Observers
// -------------------------------
2014-08-27 00:01:15 +00:00
valueChanged: function(newValue) {
2014-08-27 00:01:15 +00:00
if (this.step !== undefined) {
this.value = Math.round(this.value / this.step) * this.step;
}
2014-08-27 00:01:15 +00:00
if (this.min !== undefined) {
this.value = Math.max(this.value, this.min);
}
2014-08-27 00:01:15 +00:00
if (this.max !== undefined) {
this.value = Math.min(this.value, this.max);
}
2014-08-27 00:01:15 +00:00
this.super();
},
2014-08-27 00:01:15 +00:00
minChanged: function() {
2014-08-27 00:01:15 +00:00
this.value = Math.max(this.value, this.min);
this.update();
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
maxChanged: function() {
2014-08-27 00:01:15 +00:00
this.value = Math.min(this.value, this.max);
this.update();
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
update: function() {
2014-08-27 00:01:15 +00:00
var ratio = this.map(this.value, this.min, this.max, 0, 1);
2014-08-27 00:01:15 +00:00
if (this.min < 0 && this.max > 0) {
2014-08-27 00:01:15 +00:00
this.$.container.classList.add('straddle-zero');
2014-08-27 00:01:15 +00:00
var zero = this.map(0, this.min, this.max, 0, 1);
2014-08-27 00:01:15 +00:00
if (this.value >= 0) {
2014-08-27 00:01:15 +00:00
this.$.fill.style.left = zero * 100 + '%';
this.$.fill.style.width = (ratio - zero) * 100 + '%';
this.$.fill.style.right = '';
2014-08-27 00:01:15 +00:00
} else {
2014-08-27 00:01:15 +00:00
this.$.fill.style.left = '';
this.$.fill.style.width = (zero - ratio) * 100 + '%';
this.$.fill.style.right = (1 - zero) * 100 + '%';
2014-08-27 00:01:15 +00:00
}
2014-08-27 00:01:15 +00:00
} else {
2014-08-27 00:01:15 +00:00
this.$.container.classList.remove('straddle-zero');
2014-08-27 00:01:15 +00:00
if (this.max > 0) {
2014-08-27 00:01:15 +00:00
this.$.fill.style.left = 0;
this.$.fill.style.width = ratio * 100 + '%';
this.$.fill.style.right = '';
2014-08-27 00:01:15 +00:00
} else {
2014-08-27 00:01:15 +00:00
this.$.fill.style.left = '';
this.$.fill.style.width = (1 - ratio) * 100 + '%';
this.$.fill.style.right = 0;
2014-08-27 00:01:15 +00:00
}
2014-08-27 00:01:15 +00:00
}
2014-08-27 00:01:15 +00:00
this.$.knob.style.left = ratio * 100 + '%';
2014-08-27 00:01:15 +00:00
this.$.container.classList.toggle('positive', this.value >= 0);
this.$.container.classList.toggle('negative', this.value < 0);
2014-08-27 00:01:15 +00:00
this.super();
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
// Events
// -------------------------------
2014-08-27 00:01:15 +00:00
click: function(e) {
2014-08-27 00:01:15 +00:00
this.$.input.select();
2014-08-27 00:01:15 +00:00
},
keydown: function(e) {
2014-08-27 00:01:15 +00:00
if (e.keyCode == 13) {
this.$.input.blur();
}
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
down: function(e) {
2014-09-03 16:52:28 +00:00
e.preventDefault();
this._rect = this.$.track.getBoundingClientRect();
2014-09-04 04:14:36 +00:00
if (!this._alt) { this.value = this.valueFromX(e.x); }
2014-09-03 16:52:28 +00:00
this.fire( 'sliderDown' );
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
up: function(e) {
2014-09-07 23:55:40 +00:00
// this.$.container.classList.add( 'transition');
this.fire( 'sliderUp' );
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
trackstart: function(e) {
2014-08-27 00:01:15 +00:00
// this.$.container.classList.remove( 'transition');
this._dragFriction = 1;
2014-09-07 23:55:40 +00:00
},
2014-08-27 00:01:15 +00:00
trackx: function(e) {
2014-08-27 00:01:15 +00:00
if (this.step === undefined) {
2014-08-27 00:01:15 +00:00
var dv = this.valueFromDX(e.ddx);
2014-08-27 00:01:15 +00:00
2014-09-04 04:14:36 +00:00
if (this._alt) { dv /= 10; }
2014-08-27 00:01:15 +00:00
this.value += dv * this._dragFriction;
2014-08-27 00:01:15 +00:00
} else {
2014-08-27 00:01:15 +00:00
this.value = this.valueFromX(e.pageX);
2014-08-27 00:01:15 +00:00
}
},
2014-08-27 00:01:15 +00:00
tracky: function(e) {
2014-08-27 00:01:15 +00:00
this._dragFriction = Math.max(0.01,
Math.min(1, this.map(e.dy, 50, 300, 1, 0.1)));
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
blur: function(e) {
2014-08-27 00:01:15 +00:00
var v = parseFloat(this.$.input.value);
2014-08-27 00:01:15 +00:00
if (v === v) {
this.value = v;
}
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
// Filters
// -------------------------------
2014-08-27 00:01:15 +00:00
truncate: function(v) {
2014-08-27 00:01:15 +00:00
if (v % 1 !== 0 && this.decimals !== undefined) {
return this.limitDecimals(v, this.decimals);
} else {
return v;
}
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
// Helpers
// -------------------------------
2014-08-27 00:01:15 +00:00
limitDecimals: function(v, maxDecimals) {
2014-08-27 00:01:15 +00:00
var str = v.toString();
var numDecimals = str.substring(str.indexOf('.') + 1).length;
2014-08-27 00:01:15 +00:00
str = v.toFixed(Math.min(numDecimals, this.decimals));
2014-08-27 00:01:15 +00:00
for (var z, i = 0, l = str.length; i < l; i++) {
if (str.charAt(i) !== '0') {
z = i;
}
2014-08-27 00:01:15 +00:00
}
return str.substring(0, z + 1);
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
valueFromX: function(x) {
2014-08-27 00:01:15 +00:00
return this.map(x, this._rect.left, this._rect.right, this.min, this.max);
2014-08-27 00:01:15 +00:00
},
2014-08-27 00:01:15 +00:00
valueFromDX: function(dx) {
2014-08-27 00:01:15 +00:00
return this.map(dx, 0, this._rect.width, 0, this.max - this.min);
2014-08-27 00:01:15 +00:00
}
2014-08-27 00:01:15 +00:00
});