Migrateed to commonjs format

This build makes dat.gui commonjs friendly and allows it to be consumed
as a regular commonjs package.

All tests are passing, API is backward compatible.
This commit is contained in:
anvaka 2015-04-16 23:15:24 -07:00
parent a65c4f9b38
commit 97adbace4d
35 changed files with 4841 additions and 5045 deletions

18
.gitignore vendored
View File

@ -1,3 +1,15 @@
.DS_Store lib-cov
.sass-cache *.seed
.idea *.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
npm-debug.log
node_modules

View File

@ -1,68 +1,65 @@
#dat.GUI # UI Controller (dat.gui ported to commonjs)
A lightweight graphical user interface for changing variables in JavaScript. A lightweight graphical user interface for changing variables in JavaScript.
Get started with dat.GUI by reading the tutorial at http://workshop.chromeexperiments.com/examples/gui. Get started with dat.GUI by reading the tutorial at http://workshop.chromeexperiments.com/examples/gui.
---- ## Packaged Builds
##Packaged Builds
The easiest way to use dat.GUI in your code is by using the built source at `build/dat.gui.min.js`. These built JavaScript files bundle all the necessary dependencies to run dat.GUI. The easiest way to use dat.GUI in your code is by using the built source at `build/dat.gui.min.js`. These built JavaScript files bundle all the necessary dependencies to run dat.GUI.
In your `head` tag, include the following code: In your `head` tag, include the following code:
```
``` html
<script type="text/javascript" src="dat.gui.min.js"></script> <script type="text/javascript" src="dat.gui.min.js"></script>
``` ```
---- ## As commonjs module
##Using dat.GUI with require.js Install the module:
Internally, dat.GUI uses [require.js](http://requirejs.org/) to handle dependency management. If you're making changes to the source and want to see the effects of your changes without building, use require js.
In your `head` tag, include the following code:
``` ```
<script data-main="path/to/main" src="path/to/requirejs/require.js"></script> npm install dat.gui
``` ```
Then, in `path/to/main.js`: Use it:
```
require([
'path/to/gui/module/GUI'
], function(GUI) {
// No namespace necessary ``` js
var gui = new GUI(); var dat = require('dat.gui');
var obj = { x: 5 };
var gui = new dat.GUI();
gui.add(obj, 'x').onChange(function() {
// obj.x will now have updated value
}); });
``` ```
----
##Directory Contents
* build: Concatenated source code. ## Directory Contents
* src: Modular code in [require.js](http://requirejs.org/) format. Also includes css, [scss](http://sass-lang.com/), and html, some of which is included during build.
* build: Concatenated source code for browsers.
* src: source code in commonjs format.
* tests: [QUnit](https://github.com/jquery/qunit) test suite. * tests: [QUnit](https://github.com/jquery/qunit) test suite.
* utils: [node.js](http://nodejs.org/) utility scripts for compiling source.
---- ## Building your own dat.GUI
##Building your own dat.GUI
In the terminal, enter the following: In the terminal, enter the following:
``` ```
$ cd utils npm start
$ node build_gui.js
``` ```
This will create a namespaced, unminified build of dat.GUI at `build/dat.gui.js` This will create a browserified build of dat.GUI at `build/dat.gui.js` and its
minified version at `build/dat.gui.min.js`.
_To export minified source using Closure Compiler, open `utils/build_gui.js` and set the `minify` parameter to `true`._ ## Change log
---- ### Pending version number
* Moved to commonjs, made it browserify friendly.
* Back to GitHub.
##Change log ### 0.5
###0.5
* Moved to requirejs for dependency management. * Moved to requirejs for dependency management.
* Changed global namespace from *DAT* to *dat* (lowercase). * Changed global namespace from *DAT* to *dat* (lowercase).
* Added support for color controllers. See [Color Controllers](http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers). * Added support for color controllers. See [Color Controllers](http://workshop.chromeexperiments.com/examples/gui/#4--Color-Controllers).
@ -81,9 +78,10 @@ _To export minified source using Closure Compiler, open `utils/build_gui.js` and
---- ----
##Thanks ## Thanks
The following libraries / open-source projects were used in the development of dat.GUI: The following libraries / open-source projects were used in the development of dat.GUI:
* [require.js](http://requirejs.org/)
* [browserify](http://browserify.org/)
* [Sass](http://sass-lang.com/) * [Sass](http://sass-lang.com/)
* [node.js](http://nodejs.org/) * [node.js](http://nodejs.org/)
* [QUnit](https://github.com/jquery/qunit) / [jquery](http://jquery.com/) * [QUnit](https://github.com/jquery/qunit) / [jquery](http://jquery.com/)

View File

@ -1,9 +1,10 @@
{ {
"name": "dat-gui", "name": "dat-gui",
"version": "0.5.0", "version": "0.5.1",
"homepage": "https://github.com/dataarts/dat.gui", "homepage": "https://github.com/dataarts/dat.gui",
"authors": [ "authors": [
"Google Data Arts Team <dataarts@google.com>" "Google Data Arts Team <dataarts@google.com>",
"Andrei Kashcha <anvaka@gmail.com>"
], ],
"description": "dat.gui is a lightweight controller library for JavaScript.", "description": "dat.gui is a lightweight controller library for JavaScript.",
"main": "/build/dat.gui.js", "main": "/build/dat.gui.js",

File diff suppressed because one or more lines are too long

89
build/dat.gui.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,7 @@
<script type="text/javascript"> <script type="text/javascript">
var obj = { x: 5 }; var obj = { x: 5 };
var gui = new dat.GUI(); var gui = new dat.GUI();
gui.add(obj, 'x'); gui.add(obj, 'x');
</script> </script>
</body> </body>
</html> </html>

32
package.json Normal file
View File

@ -0,0 +1,32 @@
{
"name": "dat.gui",
"version": "0.5.1",
"main": "src/index.js",
"scripts": {
"browser": "browserify -s dat src/index.js > build/dat.gui.js",
"minify": "uglifyjs --comments -- ./build/dat.gui.js > ./build/dat.gui.min.js",
"release": "npm run browser && npm run minify",
"start": "npm run release"
},
"browserify": {
"transform": [
"brfs"
]
},
"repository": {
"type": "git",
"url": "https://github.com/dataarts/dat.gui"
},
"author": [
"Data Arts Team, Google Creative Lab",
"Andrei Kashcha"
],
"license": "Apache 2.0",
"dependencies": {
"brfs": "^1.4.0"
},
"devDependencies": {
"browserify": "^9.0.8",
"uglify-js": "^2.4.20"
}
}

View File

@ -11,179 +11,171 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var common = require('../utils/common.js');
'dat/color/interpret', var toString = require('./toString.js');
'dat/color/math', var math = require('./math.js');
'dat/color/toString', var interpret = require('./interpret.js');
'dat/utils/common'
], function(interpret, math, toString, common) {
var Color = function() { module.exports = Color;
this.__state = interpret.apply(this, arguments); function Color() {
if (this.__state === false) { this.__state = interpret.apply(this, arguments);
throw 'Failed to interpret color arguments';
}
this.__state.a = this.__state.a || 1;
};
Color.COMPONENTS = ['r','g','b','h','s','v','hex','a'];
common.extend(Color.prototype, {
toString: function() {
return toString(this);
},
toOriginal: function() {
return this.__state.conversion.write(this);
}
});
defineRGBComponent(Color.prototype, 'r', 2);
defineRGBComponent(Color.prototype, 'g', 1);
defineRGBComponent(Color.prototype, 'b', 0);
defineHSVComponent(Color.prototype, 'h');
defineHSVComponent(Color.prototype, 's');
defineHSVComponent(Color.prototype, 'v');
Object.defineProperty(Color.prototype, 'a', {
get: function() {
return this.__state.a;
},
set: function(v) {
this.__state.a = v;
}
});
Object.defineProperty(Color.prototype, 'hex', {
get: function() {
if (!this.__state.space !== 'HEX') {
this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);
}
return this.__state.hex;
},
set: function(v) {
this.__state.space = 'HEX';
this.__state.hex = v;
}
});
function defineRGBComponent(target, component, componentHexIndex) {
Object.defineProperty(target, component, {
get: function() {
if (this.__state.space === 'RGB') {
return this.__state[component];
}
recalculateRGB(this, component, componentHexIndex);
return this.__state[component];
},
set: function(v) {
if (this.__state.space !== 'RGB') {
recalculateRGB(this, component, componentHexIndex);
this.__state.space = 'RGB';
}
this.__state[component] = v;
}
});
if (this.__state === false) {
throw 'Failed to interpret color arguments';
} }
function defineHSVComponent(target, component) { this.__state.a = this.__state.a || 1;
}
Object.defineProperty(target, component, { Color.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a'];
get: function() { common.extend(Color.prototype, {
if (this.__state.space === 'HSV') toString: function() {
return this.__state[component]; return toString(this);
},
recalculateHSV(this);
return this.__state[component];
},
set: function(v) {
if (this.__state.space !== 'HSV') {
recalculateHSV(this);
this.__state.space = 'HSV';
}
this.__state[component] = v;
}
});
toOriginal: function() {
return this.__state.conversion.write(this);
} }
function recalculateRGB(color, component, componentHexIndex) {
if (color.__state.space === 'HEX') {
color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);
} else if (color.__state.space === 'HSV') {
common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));
} else {
throw 'Corrupted color state';
}
}
function recalculateHSV(color) {
var result = math.rgb_to_hsv(color.r, color.g, color.b);
common.extend(color.__state,
{
s: result.s,
v: result.v
}
);
if (!common.isNaN(result.h)) {
color.__state.h = result.h;
} else if (common.isUndefined(color.__state.h)) {
color.__state.h = 0;
}
}
return Color;
}); });
defineRGBComponent(Color.prototype, 'r', 2);
defineRGBComponent(Color.prototype, 'g', 1);
defineRGBComponent(Color.prototype, 'b', 0);
defineHSVComponent(Color.prototype, 'h');
defineHSVComponent(Color.prototype, 's');
defineHSVComponent(Color.prototype, 'v');
Object.defineProperty(Color.prototype, 'a', {
get: function() {
return this.__state.a;
},
set: function(v) {
this.__state.a = v;
}
});
Object.defineProperty(Color.prototype, 'hex', {
get: function() {
if (!this.__state.space !== 'HEX') {
this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b);
}
return this.__state.hex;
},
set: function(v) {
this.__state.space = 'HEX';
this.__state.hex = v;
}
});
function defineRGBComponent(target, component, componentHexIndex) {
Object.defineProperty(target, component, {
get: function() {
if (this.__state.space === 'RGB') {
return this.__state[component];
}
recalculateRGB(this, component, componentHexIndex);
return this.__state[component];
},
set: function(v) {
if (this.__state.space !== 'RGB') {
recalculateRGB(this, component, componentHexIndex);
this.__state.space = 'RGB';
}
this.__state[component] = v;
}
});
}
function defineHSVComponent(target, component) {
Object.defineProperty(target, component, {
get: function() {
if (this.__state.space === 'HSV')
return this.__state[component];
recalculateHSV(this);
return this.__state[component];
},
set: function(v) {
if (this.__state.space !== 'HSV') {
recalculateHSV(this);
this.__state.space = 'HSV';
}
this.__state[component] = v;
}
});
}
function recalculateRGB(color, component, componentHexIndex) {
if (color.__state.space === 'HEX') {
color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex);
} else if (color.__state.space === 'HSV') {
common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));
} else {
throw 'Corrupted color state';
}
}
function recalculateHSV(color) {
var result = math.rgb_to_hsv(color.r, color.g, color.b);
common.extend(color.__state, {
s: result.s,
v: result.v
});
if (!common.isNaN(result.h)) {
color.__state.h = result.h;
} else if (common.isUndefined(color.__state.h)) {
color.__state.h = 0;
}
}

View File

@ -11,10 +11,11 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ module.exports = createInterpert();
'dat/color/toString',
'dat/utils/common' function createInterpert() {
], function(toString, common) { var common = require('../utils/common.js');
var toString = require('./toString.js');
var result, toReturn; var result, toReturn;
@ -337,4 +338,4 @@ define([
return interpret; return interpret;
}); }

View File

@ -11,9 +11,9 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ module.exports = math();
], function() { function math() {
var tmpComponent; var tmpComponent;
@ -47,9 +47,9 @@ define([
rgb_to_hsv: function(r, g, b) { rgb_to_hsv: function(r, g, b) {
var min = Math.min(r, g, b), var min = Math.min(r, g, b),
max = Math.max(r, g, b), max = Math.max(r, g, b),
delta = max - min, delta = max - min,
h, s; h, s;
if (max != 0) { if (max != 0) {
s = delta / max; s = delta / max;
@ -92,9 +92,8 @@ define([
}, },
hex_with_component: function(hex, componentIndex, value) { hex_with_component: function(hex, componentIndex, value) {
return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent)); return value << (tmpComponent = componentIndex * 8) | (hex & ~(0xFF << tmpComponent));
} }
} };
}
});

View File

@ -11,27 +11,25 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var common = require('../utils/common.js');
'dat/utils/common'
], function(common) {
return function(color) { module.exports = toString;
if (color.a == 1 || common.isUndefined(color.a)) { function toString(color) {
var s = color.hex.toString(16); if (color.a == 1 || common.isUndefined(color.a)) {
while (s.length < 6) {
s = '0' + s;
}
return '#' + s;
} else {
return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';
var s = color.hex.toString(16);
while (s.length < 6) {
s = '0' + s;
} }
return '#' + s;
} else {
return 'rgba(' + Math.round(color.r) + ',' + Math.round(color.g) + ',' + Math.round(color.b) + ',' + color.a + ')';
} }
}); }

View File

@ -11,81 +11,77 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var Controller = require('./Controller.js');
'dat/controllers/Controller', var common = require('../utils/common.js');
'dat/dom/dom', var dom = require('../dom/dom.js');
'dat/utils/common'
], function(Controller, dom, common) {
/** module.exports = BooleanController;
* @class Provides a checkbox input to alter the boolean property of an object.
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var BooleanController = function(object, property) {
BooleanController.superclass.call(this, object, property); /**
* @class Provides a checkbox input to alter the boolean property of an object.
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
function BooleanController(object, property) {
var _this = this; BooleanController.superclass.call(this, object, property);
this.__prev = this.getValue();
this.__checkbox = document.createElement('input'); var _this = this;
this.__checkbox.setAttribute('type', 'checkbox'); this.__prev = this.getValue();
this.__checkbox = document.createElement('input');
this.__checkbox.setAttribute('type', 'checkbox');
dom.bind(this.__checkbox, 'change', onChange, false); dom.bind(this.__checkbox, 'change', onChange, false);
this.domElement.appendChild(this.__checkbox); this.domElement.appendChild(this.__checkbox);
// Match original value // Match original value
this.updateDisplay(); this.updateDisplay();
function onChange() { function onChange() {
_this.setValue(!_this.__prev); _this.setValue(!_this.__prev);
} }
}; }
BooleanController.superclass = Controller; BooleanController.superclass = Controller;
common.extend( common.extend(
BooleanController.prototype, BooleanController.prototype,
Controller.prototype, Controller.prototype,
{ {
setValue: function(v) { setValue: function(v) {
var toReturn = BooleanController.superclass.prototype.setValue.call(this, v); var toReturn = BooleanController.superclass.prototype.setValue.call(this, v);
if (this.__onFinishChange) { if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue()); this.__onFinishChange.call(this, this.getValue());
} }
this.__prev = this.getValue(); this.__prev = this.getValue();
return toReturn; return toReturn;
}, },
updateDisplay: function() {
if (this.getValue() === true) {
this.__checkbox.setAttribute('checked', 'checked');
this.__checkbox.checked = true;
} else {
this.__checkbox.checked = false;
}
return BooleanController.superclass.prototype.updateDisplay.call(this);
}
updateDisplay: function() {
if (this.getValue() === true) {
this.__checkbox.setAttribute('checked', 'checked');
this.__checkbox.checked = true;
} else {
this.__checkbox.checked = false;
} }
); return BooleanController.superclass.prototype.updateDisplay.call(this);
return BooleanController; }
});
}
);

View File

@ -11,314 +11,309 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var Controller = require('./Controller.js');
'dat/controllers/Controller', var common = require('../utils/common.js');
'dat/dom/dom', var dom = require('../dom/dom.js');
'dat/color/Color', var Color = require('../color/Color.js');
'dat/color/interpret', var interpret = require('../color/interpret.js');
'dat/utils/common'
], function(Controller, dom, Color, interpret, common) {
var ColorController = function(object, property) { module.exports = ColorController;
ColorController.superclass.call(this, object, property); function ColorController(object, property) {
this.__color = new Color(this.getValue()); ColorController.superclass.call(this, object, property);
this.__temp = new Color(0);
var _this = this; this.__color = new Color(this.getValue());
this.__temp = new Color(0);
this.domElement = document.createElement('div'); var _this = this;
dom.makeSelectable(this.domElement, false); this.domElement = document.createElement('div');
this.__selector = document.createElement('div'); dom.makeSelectable(this.domElement, false);
this.__selector.className = 'selector';
this.__saturation_field = document.createElement('div'); this.__selector = document.createElement('div');
this.__saturation_field.className = 'saturation-field'; this.__selector.className = 'selector';
this.__field_knob = document.createElement('div'); this.__saturation_field = document.createElement('div');
this.__field_knob.className = 'field-knob'; this.__saturation_field.className = 'saturation-field';
this.__field_knob_border = '2px solid ';
this.__hue_knob = document.createElement('div'); this.__field_knob = document.createElement('div');
this.__hue_knob.className = 'hue-knob'; this.__field_knob.className = 'field-knob';
this.__field_knob_border = '2px solid ';
this.__hue_field = document.createElement('div'); this.__hue_knob = document.createElement('div');
this.__hue_field.className = 'hue-field'; this.__hue_knob.className = 'hue-knob';
this.__input = document.createElement('input'); this.__hue_field = document.createElement('div');
this.__input.type = 'text'; this.__hue_field.className = 'hue-field';
this.__input_textShadow = '0 1px 1px ';
dom.bind(this.__input, 'keydown', function(e) { this.__input = document.createElement('input');
if (e.keyCode === 13) { // on enter this.__input.type = 'text';
onBlur.call(this); this.__input_textShadow = '0 1px 1px ';
}
});
dom.bind(this.__input, 'blur', onBlur); dom.bind(this.__input, 'keydown', function(e) {
if (e.keyCode === 13) { // on enter
dom.bind(this.__selector, 'mousedown', function(e) { onBlur.call(this);
dom
.addClass(this, 'drag')
.bind(window, 'mouseup', function(e) {
dom.removeClass(_this.__selector, 'drag');
});
});
var value_field = document.createElement('div');
common.extend(this.__selector.style, {
width: '122px',
height: '102px',
padding: '3px',
backgroundColor: '#222',
boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'
});
common.extend(this.__field_knob.style, {
position: 'absolute',
width: '12px',
height: '12px',
border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),
boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',
borderRadius: '12px',
zIndex: 1
});
common.extend(this.__hue_knob.style, {
position: 'absolute',
width: '15px',
height: '2px',
borderRight: '4px solid #fff',
zIndex: 1
});
common.extend(this.__saturation_field.style, {
width: '100px',
height: '100px',
border: '1px solid #555',
marginRight: '3px',
display: 'inline-block',
cursor: 'pointer'
});
common.extend(value_field.style, {
width: '100%',
height: '100%',
background: 'none'
});
linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');
common.extend(this.__hue_field.style, {
width: '15px',
height: '100px',
display: 'inline-block',
border: '1px solid #555',
cursor: 'ns-resize'
});
hueGradient(this.__hue_field);
common.extend(this.__input.style, {
outline: 'none',
// width: '120px',
textAlign: 'center',
// padding: '4px',
// marginBottom: '6px',
color: '#fff',
border: 0,
fontWeight: 'bold',
textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'
});
dom.bind(this.__saturation_field, 'mousedown', fieldDown);
dom.bind(this.__field_knob, 'mousedown', fieldDown);
dom.bind(this.__hue_field, 'mousedown', function(e) {
setH(e);
dom.bind(window, 'mousemove', setH);
dom.bind(window, 'mouseup', unbindH);
});
function fieldDown(e) {
setSV(e);
// document.body.style.cursor = 'none';
dom.bind(window, 'mousemove', setSV);
dom.bind(window, 'mouseup', unbindSV);
} }
});
function unbindSV() { dom.bind(this.__input, 'blur', onBlur);
dom.unbind(window, 'mousemove', setSV);
dom.unbind(window, 'mouseup', unbindSV); dom.bind(this.__selector, 'mousedown', function(e) {
// document.body.style.cursor = 'default';
dom
.addClass(this, 'drag')
.bind(window, 'mouseup', function(e) {
dom.removeClass(_this.__selector, 'drag');
});
});
var value_field = document.createElement('div');
common.extend(this.__selector.style, {
width: '122px',
height: '102px',
padding: '3px',
backgroundColor: '#222',
boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'
});
common.extend(this.__field_knob.style, {
position: 'absolute',
width: '12px',
height: '12px',
border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'),
boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',
borderRadius: '12px',
zIndex: 1
});
common.extend(this.__hue_knob.style, {
position: 'absolute',
width: '15px',
height: '2px',
borderRight: '4px solid #fff',
zIndex: 1
});
common.extend(this.__saturation_field.style, {
width: '100px',
height: '100px',
border: '1px solid #555',
marginRight: '3px',
display: 'inline-block',
cursor: 'pointer'
});
common.extend(value_field.style, {
width: '100%',
height: '100%',
background: 'none'
});
linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000');
common.extend(this.__hue_field.style, {
width: '15px',
height: '100px',
display: 'inline-block',
border: '1px solid #555',
cursor: 'ns-resize'
});
hueGradient(this.__hue_field);
common.extend(this.__input.style, {
outline: 'none',
// width: '120px',
textAlign: 'center',
// padding: '4px',
// marginBottom: '6px',
color: '#fff',
border: 0,
fontWeight: 'bold',
textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)'
});
dom.bind(this.__saturation_field, 'mousedown', fieldDown);
dom.bind(this.__field_knob, 'mousedown', fieldDown);
dom.bind(this.__hue_field, 'mousedown', function(e) {
setH(e);
dom.bind(window, 'mousemove', setH);
dom.bind(window, 'mouseup', unbindH);
});
function fieldDown(e) {
setSV(e);
// document.body.style.cursor = 'none';
dom.bind(window, 'mousemove', setSV);
dom.bind(window, 'mouseup', unbindSV);
}
function unbindSV() {
dom.unbind(window, 'mousemove', setSV);
dom.unbind(window, 'mouseup', unbindSV);
// document.body.style.cursor = 'default';
}
function onBlur() {
var i = interpret(this.value);
if (i !== false) {
_this.__color.__state = i;
_this.setValue(_this.__color.toOriginal());
} else {
this.value = _this.__color.toString();
} }
}
function unbindH() {
dom.unbind(window, 'mousemove', setH);
dom.unbind(window, 'mouseup', unbindH);
}
this.__saturation_field.appendChild(value_field);
this.__selector.appendChild(this.__field_knob);
this.__selector.appendChild(this.__saturation_field);
this.__selector.appendChild(this.__hue_field);
this.__hue_field.appendChild(this.__hue_knob);
this.domElement.appendChild(this.__input);
this.domElement.appendChild(this.__selector);
this.updateDisplay();
function setSV(e) {
e.preventDefault();
var w = dom.getWidth(_this.__saturation_field);
var o = dom.getOffset(_this.__saturation_field);
var s = (e.clientX - o.left + document.body.scrollLeft) / w;
var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;
if (v > 1) v = 1;
else if (v < 0) v = 0;
if (s > 1) s = 1;
else if (s < 0) s = 0;
_this.__color.v = v;
_this.__color.s = s;
_this.setValue(_this.__color.toOriginal());
return false;
}
function setH(e) {
e.preventDefault();
var s = dom.getHeight(_this.__hue_field);
var o = dom.getOffset(_this.__hue_field);
var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;
if (h > 1) h = 1;
else if (h < 0) h = 0;
_this.__color.h = h * 360;
_this.setValue(_this.__color.toOriginal());
return false;
}
};
ColorController.superclass = Controller;
common.extend(
ColorController.prototype,
Controller.prototype,
{
updateDisplay: function() {
var i = interpret(this.getValue());
function onBlur() {
var i = interpret(this.value);
if (i !== false) { if (i !== false) {
_this.__color.__state = i;
_this.setValue(_this.__color.toOriginal());
} else {
this.value = _this.__color.toString();
}
}
function unbindH() { var mismatch = false;
dom.unbind(window, 'mousemove', setH);
dom.unbind(window, 'mouseup', unbindH);
}
this.__saturation_field.appendChild(value_field); // Check for mismatch on the interpreted value.
this.__selector.appendChild(this.__field_knob);
this.__selector.appendChild(this.__saturation_field);
this.__selector.appendChild(this.__hue_field);
this.__hue_field.appendChild(this.__hue_knob);
this.domElement.appendChild(this.__input);
this.domElement.appendChild(this.__selector);
this.updateDisplay();
function setSV(e) {
e.preventDefault();
var w = dom.getWidth(_this.__saturation_field);
var o = dom.getOffset(_this.__saturation_field);
var s = (e.clientX - o.left + document.body.scrollLeft) / w;
var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w;
if (v > 1) v = 1;
else if (v < 0) v = 0;
if (s > 1) s = 1;
else if (s < 0) s = 0;
_this.__color.v = v;
_this.__color.s = s;
_this.setValue(_this.__color.toOriginal());
return false;
}
function setH(e) {
e.preventDefault();
var s = dom.getHeight(_this.__hue_field);
var o = dom.getOffset(_this.__hue_field);
var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s;
if (h > 1) h = 1;
else if (h < 0) h = 0;
_this.__color.h = h * 360;
_this.setValue(_this.__color.toOriginal());
return false;
}
};
ColorController.superclass = Controller;
common.extend(
ColorController.prototype,
Controller.prototype,
{
updateDisplay: function() {
var i = interpret(this.getValue());
if (i !== false) {
var mismatch = false;
// Check for mismatch on the interpreted value.
common.each(Color.COMPONENTS, function(component) {
if (!common.isUndefined(i[component]) &&
!common.isUndefined(this.__color.__state[component]) &&
i[component] !== this.__color.__state[component]) {
mismatch = true;
return {}; // break
}
}, this);
// If nothing diverges, we keep our previous values
// for statefulness, otherwise we recalculate fresh
if (mismatch) {
common.extend(this.__color.__state, i);
}
common.each(Color.COMPONENTS, function(component) {
if (!common.isUndefined(i[component]) &&
!common.isUndefined(this.__color.__state[component]) &&
i[component] !== this.__color.__state[component]) {
mismatch = true;
return {}; // break
} }
}, this);
common.extend(this.__temp.__state, this.__color.__state); // If nothing diverges, we keep our previous values
// for statefulness, otherwise we recalculate fresh
this.__temp.a = 1; if (mismatch) {
common.extend(this.__color.__state, i);
var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;
var _flip = 255 - flip;
common.extend(this.__field_knob.style, {
marginLeft: 100 * this.__color.s - 7 + 'px',
marginTop: 100 * (1 - this.__color.v) - 7 + 'px',
backgroundColor: this.__temp.toString(),
border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')'
});
this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'
this.__temp.s = 1;
this.__temp.v = 1;
linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());
common.extend(this.__input.style, {
backgroundColor: this.__input.value = this.__color.toString(),
color: 'rgb(' + flip + ',' + flip + ',' + flip +')',
textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)'
});
} }
} }
); common.extend(this.__temp.__state, this.__color.__state);
var vendors = ['-moz-','-o-','-webkit-','-ms-','']; this.__temp.a = 1;
var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0;
var _flip = 255 - flip;
common.extend(this.__field_knob.style, {
marginLeft: 100 * this.__color.s - 7 + 'px',
marginTop: 100 * (1 - this.__color.v) - 7 + 'px',
backgroundColor: this.__temp.toString(),
border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip + ')'
});
this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px'
this.__temp.s = 1;
this.__temp.v = 1;
linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString());
common.extend(this.__input.style, {
backgroundColor: this.__input.value = this.__color.toString(),
color: 'rgb(' + flip + ',' + flip + ',' + flip + ')',
textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip + ',.7)'
});
}
function linearGradient(elem, x, a, b) {
elem.style.background = '';
common.each(vendors, function(vendor) {
elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); ';
});
} }
function hueGradient(elem) { );
elem.style.background = '';
elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'
elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
}
var vendors = ['-moz-', '-o-', '-webkit-', '-ms-', ''];
return ColorController; function linearGradient(elem, x, a, b) {
elem.style.background = '';
common.each(vendors, function(vendor) {
elem.style.cssText += 'background: ' + vendor + 'linear-gradient(' + x + ', ' + a + ' 0%, ' + b + ' 100%); ';
});
}
}); function hueGradient(elem) {
elem.style.background = '';
elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);'
elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);'
}

View File

@ -11,134 +11,128 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var common = require('../utils/common.js');
'dat/utils/common' module.exports = Controller;
], function(common) {
/**
* @class An "abstract" class that represents a given property of an object.
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
function Controller(object, property) {
this.initialValue = object[property];
/** /**
* @class An "abstract" class that represents a given property of an object. * Those who extend this class will put their DOM elements in here.
* * @type {DOMElement}
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/ */
var Controller = function(object, property) { this.domElement = document.createElement('div');
this.initialValue = object[property]; /**
* The object to manipulate
* @type {Object}
*/
this.object = object;
/**
* The name of the property to manipulate
* @type {String}
*/
this.property = property;
/**
* The function to be called on change.
* @type {Function}
* @ignore
*/
this.__onChange = undefined;
/**
* The function to be called on finishing change.
* @type {Function}
* @ignore
*/
this.__onFinishChange = undefined;
}
common.extend(
Controller.prototype,
/** @lends dat.controllers.Controller.prototype */
{
/** /**
* Those who extend this class will put their DOM elements in here. * Specify that a function fire every time someone changes the value with
* @type {DOMElement} * this Controller.
*
* @param {Function} fnc This function will be called whenever the value
* is modified via this Controller.
* @returns {dat.controllers.Controller} this
*/ */
this.domElement = document.createElement('div'); onChange: function(fnc) {
this.__onChange = fnc;
return this;
},
/** /**
* The object to manipulate * Specify that a function fire every time someone "finishes" changing
* @type {Object} * the value wih this Controller. Useful for values that change
* incrementally like numbers or strings.
*
* @param {Function} fnc This function will be called whenever
* someone "finishes" changing the value via this Controller.
* @returns {dat.controllers.Controller} this
*/ */
this.object = object; onFinishChange: function(fnc) {
this.__onFinishChange = fnc;
return this;
},
/** /**
* The name of the property to manipulate * Change the value of <code>object[property]</code>
* @type {String} *
* @param {Object} newValue The new value of <code>object[property]</code>
*/ */
this.property = property; setValue: function(newValue) {
this.object[this.property] = newValue;
/** if (this.__onChange) {
* The function to be called on change. this.__onChange.call(this, newValue);
* @type {Function}
* @ignore
*/
this.__onChange = undefined;
/**
* The function to be called on finishing change.
* @type {Function}
* @ignore
*/
this.__onFinishChange = undefined;
};
common.extend(
Controller.prototype,
/** @lends dat.controllers.Controller.prototype */
{
/**
* Specify that a function fire every time someone changes the value with
* this Controller.
*
* @param {Function} fnc This function will be called whenever the value
* is modified via this Controller.
* @returns {dat.controllers.Controller} this
*/
onChange: function(fnc) {
this.__onChange = fnc;
return this;
},
/**
* Specify that a function fire every time someone "finishes" changing
* the value wih this Controller. Useful for values that change
* incrementally like numbers or strings.
*
* @param {Function} fnc This function will be called whenever
* someone "finishes" changing the value via this Controller.
* @returns {dat.controllers.Controller} this
*/
onFinishChange: function(fnc) {
this.__onFinishChange = fnc;
return this;
},
/**
* Change the value of <code>object[property]</code>
*
* @param {Object} newValue The new value of <code>object[property]</code>
*/
setValue: function(newValue) {
this.object[this.property] = newValue;
if (this.__onChange) {
this.__onChange.call(this, newValue);
}
this.updateDisplay();
return this;
},
/**
* Gets the value of <code>object[property]</code>
*
* @returns {Object} The current value of <code>object[property]</code>
*/
getValue: function() {
return this.object[this.property];
},
/**
* Refreshes the visual display of a Controller in order to keep sync
* with the object's current value.
* @returns {dat.controllers.Controller} this
*/
updateDisplay: function() {
return this;
},
/**
* @returns {Boolean} true if the value has deviated from initialValue
*/
isModified: function() {
return this.initialValue !== this.getValue()
}
} }
this.updateDisplay();
return this;
},
); /**
* Gets the value of <code>object[property]</code>
*
* @returns {Object} The current value of <code>object[property]</code>
*/
getValue: function() {
return this.object[this.property];
},
return Controller; /**
* Refreshes the visual display of a Controller in order to keep sync
* with the object's current value.
* @returns {dat.controllers.Controller} this
*/
updateDisplay: function() {
return this;
},
/**
* @returns {Boolean} true if the value has deviated from initialValue
*/
isModified: function() {
return this.initialValue !== this.getValue();
}
}); }
);

View File

@ -11,64 +11,58 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var Controller = require('./Controller.js');
'dat/controllers/Controller', var common = require('../utils/common.js');
'dat/dom/dom', var dom = require('../dom/dom.js');
'dat/utils/common'
], function(Controller, dom, common) {
/** module.exports = FunctionController;
* @class Provides a GUI interface to fire a specified method, a property of an object.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var FunctionController = function(object, property, text) {
FunctionController.superclass.call(this, object, property); /**
* @class Provides a GUI interface to fire a specified method, a property of an object.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
function FunctionController(object, property, text) {
var _this = this; FunctionController.superclass.call(this, object, property);
this.__button = document.createElement('div'); var _this = this;
this.__button.innerHTML = text === undefined ? 'Fire' : text;
dom.bind(this.__button, 'click', function(e) {
e.preventDefault();
_this.fire();
return false;
});
dom.addClass(this.__button, 'button'); this.__button = document.createElement('div');
this.__button.innerHTML = text === undefined ? 'Fire' : text;
dom.bind(this.__button, 'click', function(e) {
e.preventDefault();
_this.fire();
return false;
});
this.domElement.appendChild(this.__button); dom.addClass(this.__button, 'button');
this.domElement.appendChild(this.__button);
}; }
FunctionController.superclass = Controller; FunctionController.superclass = Controller;
common.extend( common.extend(
FunctionController.prototype, FunctionController.prototype,
Controller.prototype, Controller.prototype, {
{
fire: function() { fire: function() {
if (this.__onChange) { if (this.__onChange) {
this.__onChange.call(this); this.__onChange.call(this);
}
this.getValue().call(this.object);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
}
} }
this.getValue().call(this.object);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
}
}
); );
return FunctionController;
});

View File

@ -11,135 +11,130 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var Controller = require('./Controller.js');
'dat/controllers/Controller', var common = require('../utils/common.js');
'dat/utils/common' module.exports = NumberController;
], function(Controller, common) {
/** /**
* @class Represents a given property of an object that is a number. * @class Represents a given property of an object that is a number.
* *
* @extends dat.controllers.Controller * @extends dat.controllers.Controller
* *
* @param {Object} object The object to be manipulated * @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated * @param {string} property The name of the property to be manipulated
* @param {Object} [params] Optional parameters * @param {Object} [params] Optional parameters
* @param {Number} [params.min] Minimum allowed value * @param {Number} [params.min] Minimum allowed value
* @param {Number} [params.max] Maximum allowed value * @param {Number} [params.max] Maximum allowed value
* @param {Number} [params.step] Increment by which to change value * @param {Number} [params.step] Increment by which to change value
* *
* @member dat.controllers * @member dat.controllers
*/ */
var NumberController = function(object, property, params) { function NumberController(object, property, params) {
NumberController.superclass.call(this, object, property); NumberController.superclass.call(this, object, property);
params = params || {}; params = params || {};
this.__min = params.min; this.__min = params.min;
this.__max = params.max; this.__max = params.max;
this.__step = params.step; this.__step = params.step;
if (common.isUndefined(this.__step)) { if (common.isUndefined(this.__step)) {
if (this.initialValue == 0) {
this.__impliedStep = 1; // What are we, psychics?
} else {
// Hey Doug, check this out.
this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue)/Math.LN10))/10;
}
if (this.initialValue == 0) {
this.__impliedStep = 1; // What are we, psychics?
} else { } else {
// Hey Doug, check this out.
this.__impliedStep = this.__step; this.__impliedStep = Math.pow(10, Math.floor(Math.log(this.initialValue) / Math.LN10)) / 10;
} }
this.__precision = numDecimals(this.__impliedStep); } else {
this.__impliedStep = this.__step;
};
NumberController.superclass = Controller;
common.extend(
NumberController.prototype,
Controller.prototype,
/** @lends dat.controllers.NumberController.prototype */
{
setValue: function(v) {
if (this.__min !== undefined && v < this.__min) {
v = this.__min;
} else if (this.__max !== undefined && v > this.__max) {
v = this.__max;
}
if (this.__step !== undefined && v % this.__step != 0) {
v = Math.round(v / this.__step) * this.__step;
}
return NumberController.superclass.prototype.setValue.call(this, v);
},
/**
* Specify a minimum value for <code>object[property]</code>.
*
* @param {Number} minValue The minimum value for
* <code>object[property]</code>
* @returns {dat.controllers.NumberController} this
*/
min: function(v) {
this.__min = v;
return this;
},
/**
* Specify a maximum value for <code>object[property]</code>.
*
* @param {Number} maxValue The maximum value for
* <code>object[property]</code>
* @returns {dat.controllers.NumberController} this
*/
max: function(v) {
this.__max = v;
return this;
},
/**
* Specify a step value that dat.controllers.NumberController
* increments by.
*
* @param {Number} stepValue The step value for
* dat.controllers.NumberController
* @default if minimum and maximum specified increment is 1% of the
* difference otherwise stepValue is 1
* @returns {dat.controllers.NumberController} this
*/
step: function(v) {
this.__step = v;
this.__impliedStep = v;
this.__precision = numDecimals(v);
return this;
}
}
);
function numDecimals(x) {
x = x.toString();
if (x.indexOf('.') > -1) {
return x.length - x.indexOf('.') - 1;
} else {
return 0;
}
} }
return NumberController; this.__precision = numDecimals(this.__impliedStep);
});
}
NumberController.superclass = Controller;
common.extend(
NumberController.prototype,
Controller.prototype,
/** @lends dat.controllers.NumberController.prototype */
{
setValue: function(v) {
if (this.__min !== undefined && v < this.__min) {
v = this.__min;
} else if (this.__max !== undefined && v > this.__max) {
v = this.__max;
}
if (this.__step !== undefined && v % this.__step != 0) {
v = Math.round(v / this.__step) * this.__step;
}
return NumberController.superclass.prototype.setValue.call(this, v);
},
/**
* Specify a minimum value for <code>object[property]</code>.
*
* @param {Number} minValue The minimum value for
* <code>object[property]</code>
* @returns {dat.controllers.NumberController} this
*/
min: function(v) {
this.__min = v;
return this;
},
/**
* Specify a maximum value for <code>object[property]</code>.
*
* @param {Number} maxValue The maximum value for
* <code>object[property]</code>
* @returns {dat.controllers.NumberController} this
*/
max: function(v) {
this.__max = v;
return this;
},
/**
* Specify a step value that dat.controllers.NumberController
* increments by.
*
* @param {Number} stepValue The step value for
* dat.controllers.NumberController
* @default if minimum and maximum specified increment is 1% of the
* difference otherwise stepValue is 1
* @returns {dat.controllers.NumberController} this
*/
step: function(v) {
this.__step = v;
this.__impliedStep = v;
this.__precision = numDecimals(v);
return this;
}
}
);
function numDecimals(x) {
x = x.toString();
if (x.indexOf('.') > -1) {
return x.length - x.indexOf('.') - 1;
} else {
return 0;
}
}

View File

@ -11,124 +11,119 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var NumberController = require('./NumberController.js');
'dat/controllers/NumberController', var common = require('../utils/common.js');
'dat/dom/dom', var dom = require('../dom/dom.js');
'dat/utils/common'
], function(NumberController, dom, common) { module.exports = NumberControllerBox;
/**
* @class Represents a given property of an object that is a number and
* provides an input element with which to manipulate it.
*
* @extends dat.controllers.Controller
* @extends dat.controllers.NumberController
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object} [params] Optional parameters
* @param {Number} [params.min] Minimum allowed value
* @param {Number} [params.max] Maximum allowed value
* @param {Number} [params.step] Increment by which to change value
*
* @member dat.controllers
*/
function NumberControllerBox(object, property, params) {
this.__truncationSuspended = false;
NumberControllerBox.superclass.call(this, object, property, params);
var _this = this;
/** /**
* @class Represents a given property of an object that is a number and * {Number} Previous mouse y position
* provides an input element with which to manipulate it. * @ignore
*
* @extends dat.controllers.Controller
* @extends dat.controllers.NumberController
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object} [params] Optional parameters
* @param {Number} [params.min] Minimum allowed value
* @param {Number} [params.max] Maximum allowed value
* @param {Number} [params.step] Increment by which to change value
*
* @member dat.controllers
*/ */
var NumberControllerBox = function(object, property, params) { var prev_y;
this.__truncationSuspended = false; this.__input = document.createElement('input');
this.__input.setAttribute('type', 'text');
NumberControllerBox.superclass.call(this, object, property, params); // Makes it so manually specified values are not truncated.
var _this = this; dom.bind(this.__input, 'change', onChange);
dom.bind(this.__input, 'blur', onBlur);
dom.bind(this.__input, 'mousedown', onMouseDown);
dom.bind(this.__input, 'keydown', function(e) {
/** // When pressing entire, you can be as precise as you want.
* {Number} Previous mouse y position if (e.keyCode === 13) {
* @ignore _this.__truncationSuspended = true;
*/ this.blur();
var prev_y; _this.__truncationSuspended = false;
this.__input = document.createElement('input');
this.__input.setAttribute('type', 'text');
// Makes it so manually specified values are not truncated.
dom.bind(this.__input, 'change', onChange);
dom.bind(this.__input, 'blur', onBlur);
dom.bind(this.__input, 'mousedown', onMouseDown);
dom.bind(this.__input, 'keydown', function(e) {
// When pressing entire, you can be as precise as you want.
if (e.keyCode === 13) {
_this.__truncationSuspended = true;
this.blur();
_this.__truncationSuspended = false;
}
});
function onChange() {
var attempted = parseFloat(_this.__input.value);
if (!common.isNaN(attempted)) _this.setValue(attempted);
} }
function onBlur() { });
onChange();
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
function onMouseDown(e) { function onChange() {
dom.bind(window, 'mousemove', onMouseDrag); var attempted = parseFloat(_this.__input.value);
dom.bind(window, 'mouseup', onMouseUp); if (!common.isNaN(attempted)) _this.setValue(attempted);
prev_y = e.clientY;
}
function onMouseDrag(e) {
var diff = prev_y - e.clientY;
_this.setValue(_this.getValue() + diff * _this.__impliedStep);
prev_y = e.clientY;
}
function onMouseUp() {
dom.unbind(window, 'mousemove', onMouseDrag);
dom.unbind(window, 'mouseup', onMouseUp);
}
this.updateDisplay();
this.domElement.appendChild(this.__input);
};
NumberControllerBox.superclass = NumberController;
common.extend(
NumberControllerBox.prototype,
NumberController.prototype,
{
updateDisplay: function() {
this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);
return NumberControllerBox.superclass.prototype.updateDisplay.call(this);
}
}
);
function roundToDecimal(value, decimals) {
var tenTo = Math.pow(10, decimals);
return Math.round(value * tenTo) / tenTo;
} }
return NumberControllerBox; function onBlur() {
onChange();
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
}); function onMouseDown(e) {
dom.bind(window, 'mousemove', onMouseDrag);
dom.bind(window, 'mouseup', onMouseUp);
prev_y = e.clientY;
}
function onMouseDrag(e) {
var diff = prev_y - e.clientY;
_this.setValue(_this.getValue() + diff * _this.__impliedStep);
prev_y = e.clientY;
}
function onMouseUp() {
dom.unbind(window, 'mousemove', onMouseDrag);
dom.unbind(window, 'mouseup', onMouseUp);
}
this.updateDisplay();
this.domElement.appendChild(this.__input);
}
NumberControllerBox.superclass = NumberController;
common.extend(
NumberControllerBox.prototype,
NumberController.prototype,
{
updateDisplay: function() {
this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);
return NumberControllerBox.superclass.prototype.updateDisplay.call(this);
}
}
);
function roundToDecimal(value, decimals) {
var tenTo = Math.pow(10, decimals);
return Math.round(value * tenTo) / tenTo;
}

View File

@ -11,119 +11,118 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var NumberController = require('./NumberController.js');
'dat/controllers/NumberController', var common = require('../utils/common.js');
'dat/dom/dom', var dom = require('../dom/dom.js');
'dat/utils/css', var css = require('../utils/css.js');
'dat/utils/common', var fs = require('fs');
'text!dat/controllers/NumberControllerSlider.css' var styleSheet = fs.readFileSync(__dirname + '/NumberControllerSlider.css', 'utf8');
], module.exports = NumberControllerSlider;
function(NumberController, dom, css, common, styleSheet) {
/** /**
* @class Represents a given property of an object that is a number, contains * @class Represents a given property of an object that is a number, contains
* a minimum and maximum, and provides a slider element with which to * a minimum and maximum, and provides a slider element with which to
* manipulate it. It should be noted that the slider element is made up of * manipulate it. It should be noted that the slider element is made up of
* <code>&lt;div&gt;</code> tags, <strong>not</strong> the html5 * <code>&lt;div&gt;</code> tags, <strong>not</strong> the html5
* <code>&lt;slider&gt;</code> element. * <code>&lt;slider&gt;</code> element.
* *
* @extends dat.controllers.Controller * @extends dat.controllers.Controller
* @extends dat.controllers.NumberController * @extends dat.controllers.NumberController
* *
* @param {Object} object The object to be manipulated * @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated * @param {string} property The name of the property to be manipulated
* @param {Number} minValue Minimum allowed value * @param {Number} minValue Minimum allowed value
* @param {Number} maxValue Maximum allowed value * @param {Number} maxValue Maximum allowed value
* @param {Number} stepValue Increment by which to change value * @param {Number} stepValue Increment by which to change value
* *
* @member dat.controllers * @member dat.controllers
*/ */
var NumberControllerSlider = function(object, property, min, max, step) { function NumberControllerSlider(object, property, min, max, step) {
NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step }); NumberControllerSlider.superclass.call(this, object, property, {
min: min,
max: max,
step: step
});
var _this = this; var _this = this;
this.__background = document.createElement('div'); this.__background = document.createElement('div');
this.__foreground = document.createElement('div'); this.__foreground = document.createElement('div');
dom.bind(this.__background, 'mousedown', onMouseDown); dom.bind(this.__background, 'mousedown', onMouseDown);
dom.addClass(this.__background, 'slider'); dom.addClass(this.__background, 'slider');
dom.addClass(this.__foreground, 'slider-fg'); dom.addClass(this.__foreground, 'slider-fg');
function onMouseDown(e) { function onMouseDown(e) {
dom.bind(window, 'mousemove', onMouseDrag); dom.bind(window, 'mousemove', onMouseDrag);
dom.bind(window, 'mouseup', onMouseUp); dom.bind(window, 'mouseup', onMouseUp);
onMouseDrag(e); onMouseDrag(e);
}
function onMouseDrag(e) {
e.preventDefault();
var offset = dom.getOffset(_this.__background);
var width = dom.getWidth(_this.__background);
_this.setValue(
map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)
);
return false;
}
function onMouseUp() {
dom.unbind(window, 'mousemove', onMouseDrag);
dom.unbind(window, 'mouseup', onMouseUp);
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
this.updateDisplay();
this.__background.appendChild(this.__foreground);
this.domElement.appendChild(this.__background);
}
NumberControllerSlider.superclass = NumberController;
/**
* Injects default stylesheet for slider elements.
*/
NumberControllerSlider.useDefaultStyles = function() {
css.inject(styleSheet);
};
common.extend(
NumberControllerSlider.prototype,
NumberController.prototype,
{
updateDisplay: function() {
var pct = (this.getValue() - this.__min) / (this.__max - this.__min);
this.__foreground.style.width = pct * 100 + '%';
return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);
} }
function onMouseDrag(e) { }
e.preventDefault();
var offset = dom.getOffset(_this.__background);
var width = dom.getWidth(_this.__background);
_this.setValue(
map(e.clientX, offset.left, offset.left + width, _this.__min, _this.__max)
);
return false;
}
function onMouseUp() {
dom.unbind(window, 'mousemove', onMouseDrag);
dom.unbind(window, 'mouseup', onMouseUp);
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
this.updateDisplay();
this.__background.appendChild(this.__foreground);
this.domElement.appendChild(this.__background);
};
NumberControllerSlider.superclass = NumberController;
/**
* Injects default stylesheet for slider elements.
*/
NumberControllerSlider.useDefaultStyles = function() {
css.inject(styleSheet);
};
common.extend(
NumberControllerSlider.prototype,
NumberController.prototype,
{
updateDisplay: function() {
var pct = (this.getValue() - this.__min)/(this.__max - this.__min);
this.__foreground.style.width = pct*100+'%';
return NumberControllerSlider.superclass.prototype.updateDisplay.call(this);
}
}
); );
function map(v, i1, i2, o1, o2) { function map(v, i1, i2, o1, o2) {
return o1 + (o2 - o1) * ((v - i1) / (i2 - i1)); return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
} }
return NumberControllerSlider;
});

View File

@ -11,93 +11,88 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var Controller = require('./Controller.js');
'dat/controllers/Controller', var dom = require('../dom/dom.js');
'dat/dom/dom', var common = require('../utils/common.js');
'dat/utils/common'
], module.exports = OptionController;
function(Controller, dom, common) {
/**
* @class Provides a select input to alter the property of an object, using a
* list of accepted values.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object|string[]} options A map of labels to acceptable values, or
* a list of acceptable string values.
*
* @member dat.controllers
*/
function OptionController(object, property, options) {
OptionController.superclass.call(this, object, property);
var _this = this;
/** /**
* @class Provides a select input to alter the property of an object, using a * The drop down menu
* list of accepted values. * @ignore
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object|string[]} options A map of labels to acceptable values, or
* a list of acceptable string values.
*
* @member dat.controllers
*/ */
var OptionController = function(object, property, options) { this.__select = document.createElement('select');
OptionController.superclass.call(this, object, property); if (common.isArray(options)) {
var map = {};
common.each(options, function(element) {
map[element] = element;
});
options = map;
}
var _this = this; common.each(options, function(value, key) {
/** var opt = document.createElement('option');
* The drop down menu opt.innerHTML = key;
* @ignore opt.setAttribute('value', value);
*/ _this.__select.appendChild(opt);
this.__select = document.createElement('select');
if (common.isArray(options)) { });
var map = {};
common.each(options, function(element) { // Acknowledge original value
map[element] = element; this.updateDisplay();
});
options = map; dom.bind(this.__select, 'change', function() {
var desiredValue = this.options[this.selectedIndex].value;
_this.setValue(desiredValue);
});
this.domElement.appendChild(this.__select);
}
OptionController.superclass = Controller;
common.extend(
OptionController.prototype,
Controller.prototype,
{
setValue: function(v) {
var toReturn = OptionController.superclass.prototype.setValue.call(this, v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
return toReturn;
},
updateDisplay: function() {
this.__select.value = this.getValue();
return OptionController.superclass.prototype.updateDisplay.call(this);
} }
common.each(options, function(value, key) { }
var opt = document.createElement('option'); );
opt.innerHTML = key;
opt.setAttribute('value', value);
_this.__select.appendChild(opt);
});
// Acknowledge original value
this.updateDisplay();
dom.bind(this.__select, 'change', function() {
var desiredValue = this.options[this.selectedIndex].value;
_this.setValue(desiredValue);
});
this.domElement.appendChild(this.__select);
};
OptionController.superclass = Controller;
common.extend(
OptionController.prototype,
Controller.prototype,
{
setValue: function(v) {
var toReturn = OptionController.superclass.prototype.setValue.call(this, v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
return toReturn;
},
updateDisplay: function() {
this.__select.value = this.getValue();
return OptionController.superclass.prototype.updateDisplay.call(this);
}
}
);
return OptionController;
});

View File

@ -11,79 +11,75 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var Controller = require('./Controller.js');
'dat/controllers/Controller', var dom = require('../dom/dom.js');
'dat/dom/dom', var common = require('../utils/common.js');
'dat/utils/common'
], function(Controller, dom, common) {
/** module.exports = StringController;
* @class Provides a text input to alter the string property of an object.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var StringController = function(object, property) {
StringController.superclass.call(this, object, property); /**
* @class Provides a text input to alter the string property of an object.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
function StringController(object, property) {
var _this = this; StringController.superclass.call(this, object, property);
this.__input = document.createElement('input'); var _this = this;
this.__input.setAttribute('type', 'text');
dom.bind(this.__input, 'keyup', onChange); this.__input = document.createElement('input');
dom.bind(this.__input, 'change', onChange); this.__input.setAttribute('type', 'text');
dom.bind(this.__input, 'blur', onBlur);
dom.bind(this.__input, 'keydown', function(e) { dom.bind(this.__input, 'keyup', onChange);
if (e.keyCode === 13) { dom.bind(this.__input, 'change', onChange);
this.blur(); dom.bind(this.__input, 'blur', onBlur);
dom.bind(this.__input, 'keydown', function(e) {
if (e.keyCode === 13) {
this.blur();
}
});
function onChange() {
_this.setValue(_this.__input.value);
}
function onBlur() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
this.updateDisplay();
this.domElement.appendChild(this.__input);
};
StringController.superclass = Controller;
common.extend(
StringController.prototype,
Controller.prototype,
{
updateDisplay: function() {
// Stops the caret from moving on account of:
// keyup -> setValue -> updateDisplay
if (!dom.isActive(this.__input)) {
this.__input.value = this.getValue();
} }
}); return StringController.superclass.prototype.updateDisplay.call(this);
function onChange() {
_this.setValue(_this.__input.value);
} }
function onBlur() { }
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
this.updateDisplay(); );
this.domElement.appendChild(this.__input);
};
StringController.superclass = Controller;
common.extend(
StringController.prototype,
Controller.prototype,
{
updateDisplay: function() {
// Stops the caret from moving on account of:
// keyup -> setValue -> updateDisplay
if (!dom.isActive(this.__input)) {
this.__input.value = this.getValue();
}
return StringController.superclass.prototype.updateDisplay.call(this);
}
}
);
return StringController;
});

View File

@ -10,56 +10,55 @@
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
var OptionController = require('./OptionController.js');
var NumberControllerBox = require('./NumberControllerBox.js');
var NumberControllerSlider = require('./NumberControllerSlider.js');
var StringController = require('./StringController.js');
var FunctionController = require('./FunctionController.js');
var BooleanController = require('./BooleanController.js');
var common = require('../utils/common.js');
define([ module.exports = factory;
'dat/controllers/OptionController',
'dat/controllers/NumberControllerBox',
'dat/controllers/NumberControllerSlider',
'dat/controllers/StringController',
'dat/controllers/FunctionController',
'dat/controllers/BooleanController',
'dat/utils/common'
],
function(OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) {
return function(object, property) { function factory(object, property) {
var initialValue = object[property]; var initialValue = object[property];
// Providing options? // Providing options?
if (common.isArray(arguments[2]) || common.isObject(arguments[2])) { if (common.isArray(arguments[2]) || common.isObject(arguments[2])) {
return new OptionController(object, property, arguments[2]); return new OptionController(object, property, arguments[2]);
} }
// Providing a map? // Providing a map?
if (common.isNumber(initialValue)) { if (common.isNumber(initialValue)) {
if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) { if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) {
// Has min and max. // Has min and max.
return new NumberControllerSlider(object, property, arguments[2], arguments[3]); return new NumberControllerSlider(object, property, arguments[2], arguments[3]);
} else { } else {
return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] }); return new NumberControllerBox(object, property, {
min: arguments[2],
max: arguments[3]
});
} }
} }
if (common.isString(initialValue)) { if (common.isString(initialValue)) {
return new StringController(object, property); return new StringController(object, property);
} }
if (common.isFunction(initialValue)) { if (common.isFunction(initialValue)) {
return new FunctionController(object, property, ''); return new FunctionController(object, property, '');
} }
if (common.isBoolean(initialValue)) { if (common.isBoolean(initialValue)) {
return new BooleanController(object, property); return new BooleanController(object, property);
} }
} }
});

View File

@ -11,107 +11,102 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var common = require('../utils/common.js');
'dat/dom/dom', var dom = require('./dom.js');
'dat/utils/common'
], function(dom, common) { module.exports = CenteredDiv;
function CenteredDiv() {
this.backgroundElement = document.createElement('div');
common.extend(this.backgroundElement.style, {
backgroundColor: 'rgba(0,0,0,0.8)',
top: 0,
left: 0,
display: 'none',
zIndex: '1000',
opacity: 0,
WebkitTransition: 'opacity 0.2s linear',
transition: 'opacity 0.2s linear'
});
dom.makeFullscreen(this.backgroundElement);
this.backgroundElement.style.position = 'fixed';
this.domElement = document.createElement('div');
common.extend(this.domElement.style, {
position: 'fixed',
display: 'none',
zIndex: '1001',
opacity: 0,
WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear',
transition: 'transform 0.2s ease-out, opacity 0.2s linear'
});
var CenteredDiv = function() { document.body.appendChild(this.backgroundElement);
document.body.appendChild(this.domElement);
this.backgroundElement = document.createElement('div'); var _this = this;
common.extend(this.backgroundElement.style, { dom.bind(this.backgroundElement, 'click', function() {
backgroundColor: 'rgba(0,0,0,0.8)', _this.hide();
top: 0, });
left: 0,
display: 'none',
zIndex: '1000',
opacity: 0,
WebkitTransition: 'opacity 0.2s linear',
transition: 'opacity 0.2s linear'
});
dom.makeFullscreen(this.backgroundElement);
this.backgroundElement.style.position = 'fixed';
this.domElement = document.createElement('div');
common.extend(this.domElement.style, {
position: 'fixed',
display: 'none',
zIndex: '1001',
opacity: 0,
WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear',
transition: 'transform 0.2s ease-out, opacity 0.2s linear'
});
document.body.appendChild(this.backgroundElement); };
document.body.appendChild(this.domElement);
var _this = this; CenteredDiv.prototype.show = function() {
dom.bind(this.backgroundElement, 'click', function() {
_this.hide();
});
var _this = this;
this.backgroundElement.style.display = 'block';
this.domElement.style.display = 'block';
this.domElement.style.opacity = 0;
// this.domElement.style.top = '52%';
this.domElement.style.webkitTransform = 'scale(1.1)';
this.layout();
common.defer(function() {
_this.backgroundElement.style.opacity = 1;
_this.domElement.style.opacity = 1;
_this.domElement.style.webkitTransform = 'scale(1)';
});
};
CenteredDiv.prototype.hide = function() {
var _this = this;
var hide = function() {
_this.domElement.style.display = 'none';
_this.backgroundElement.style.display = 'none';
dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);
dom.unbind(_this.domElement, 'transitionend', hide);
dom.unbind(_this.domElement, 'oTransitionEnd', hide);
}; };
CenteredDiv.prototype.show = function() { dom.bind(this.domElement, 'webkitTransitionEnd', hide);
dom.bind(this.domElement, 'transitionend', hide);
dom.bind(this.domElement, 'oTransitionEnd', hide);
var _this = this; this.backgroundElement.style.opacity = 0;
// this.domElement.style.top = '48%';
this.domElement.style.opacity = 0;
this.domElement.style.webkitTransform = 'scale(1.1)';
this.backgroundElement.style.display = 'block'; };
this.domElement.style.display = 'block'; CenteredDiv.prototype.layout = function() {
this.domElement.style.opacity = 0; this.domElement.style.left = window.innerWidth / 2 - dom.getWidth(this.domElement) / 2 + 'px';
// this.domElement.style.top = '52%'; this.domElement.style.top = window.innerHeight / 2 - dom.getHeight(this.domElement) / 2 + 'px';
this.domElement.style.webkitTransform = 'scale(1.1)'; };
this.layout(); function lockScroll(e) {
console.log(e);
common.defer(function() { }
_this.backgroundElement.style.opacity = 1;
_this.domElement.style.opacity = 1;
_this.domElement.style.webkitTransform = 'scale(1)';
});
};
CenteredDiv.prototype.hide = function() {
var _this = this;
var hide = function() {
_this.domElement.style.display = 'none';
_this.backgroundElement.style.display = 'none';
dom.unbind(_this.domElement, 'webkitTransitionEnd', hide);
dom.unbind(_this.domElement, 'transitionend', hide);
dom.unbind(_this.domElement, 'oTransitionEnd', hide);
};
dom.bind(this.domElement, 'webkitTransitionEnd', hide);
dom.bind(this.domElement, 'transitionend', hide);
dom.bind(this.domElement, 'oTransitionEnd', hide);
this.backgroundElement.style.opacity = 0;
// this.domElement.style.top = '48%';
this.domElement.style.opacity = 0;
this.domElement.style.webkitTransform = 'scale(1.1)';
};
CenteredDiv.prototype.layout = function() {
this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px';
this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px';
};
function lockScroll(e) {
console.log(e);
}
return CenteredDiv;
});

View File

@ -11,277 +11,275 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ var common = require('../utils/common.js');
'dat/utils/common'
], function(common) {
var EVENT_MAP = { var EVENT_MAP = {
'HTMLEvents': ['change'], 'HTMLEvents': ['change'],
'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'], 'MouseEvents': ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'],
'KeyboardEvents': ['keydown'] 'KeyboardEvents': ['keydown']
}; };
var EVENT_MAP_INV = {}; var EVENT_MAP_INV = {};
common.each(EVENT_MAP, function(v, k) { common.each(EVENT_MAP, function(v, k) {
common.each(v, function(e) { common.each(v, function(e) {
EVENT_MAP_INV[e] = k; EVENT_MAP_INV[e] = k;
});
}); });
});
var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/; var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/;
function cssValueToPixels(val) { function cssValueToPixels(val) {
if (val === '0' || common.isUndefined(val)) return 0; if (val === '0' || common.isUndefined(val)) return 0;
var match = val.match(CSS_VALUE_PIXELS); var match = val.match(CSS_VALUE_PIXELS);
if (!common.isNull(match)) {
return parseFloat(match[1]);
}
// TODO ...ems? %?
return 0;
if (!common.isNull(match)) {
return parseFloat(match[1]);
} }
// TODO ...ems? %?
return 0;
}
/**
* @namespace
* @member dat.dom
*/
var dom = {
/** /**
* @namespace *
* @member dat.dom * @param elem
* @param selectable
*/ */
var dom = { makeSelectable: function(elem, selectable) {
/** if (elem === undefined || elem.style === undefined) return;
*
* @param elem
* @param selectable
*/
makeSelectable: function(elem, selectable) {
if (elem === undefined || elem.style === undefined) return; elem.onselectstart = selectable ? function() {
return false;
} : function() {};
elem.onselectstart = selectable ? function() { elem.style.MozUserSelect = selectable ? 'auto' : 'none';
return false; elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';
} : function() { elem.unselectable = selectable ? 'on' : 'off';
};
elem.style.MozUserSelect = selectable ? 'auto' : 'none'; },
elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';
elem.unselectable = selectable ? 'on' : 'off';
}, /**
*
* @param elem
* @param horizontal
* @param vertical
*/
makeFullscreen: function(elem, horizontal, vertical) {
/** if (common.isUndefined(horizontal)) horizontal = true;
* if (common.isUndefined(vertical)) vertical = true;
* @param elem
* @param horizontal
* @param vertical
*/
makeFullscreen: function(elem, horizontal, vertical) {
if (common.isUndefined(horizontal)) horizontal = true; elem.style.position = 'absolute';
if (common.isUndefined(vertical)) vertical = true;
elem.style.position = 'absolute'; if (horizontal) {
elem.style.left = 0;
if (horizontal) { elem.style.right = 0;
elem.style.left = 0; }
elem.style.right = 0; if (vertical) {
} elem.style.top = 0;
if (vertical) { elem.style.bottom = 0;
elem.style.top = 0;
elem.style.bottom = 0;
}
},
/**
*
* @param elem
* @param eventType
* @param params
*/
fakeEvent: function(elem, eventType, params, aux) {
params = params || {};
var className = EVENT_MAP_INV[eventType];
if (!className) {
throw new Error('Event type ' + eventType + ' not supported.');
}
var evt = document.createEvent(className);
switch (className) {
case 'MouseEvents':
var clientX = params.x || params.clientX || 0;
var clientY = params.y || params.clientY || 0;
evt.initMouseEvent(eventType, params.bubbles || false,
params.cancelable || true, window, params.clickCount || 1,
0, //screen X
0, //screen Y
clientX, //client X
clientY, //client Y
false, false, false, false, 0, null);
break;
case 'KeyboardEvents':
var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz
common.defaults(params, {
cancelable: true,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
keyCode: undefined,
charCode: undefined
});
init(eventType, params.bubbles || false,
params.cancelable, window,
params.ctrlKey, params.altKey,
params.shiftKey, params.metaKey,
params.keyCode, params.charCode);
break;
default:
evt.initEvent(eventType, params.bubbles || false,
params.cancelable || true);
break;
}
common.defaults(evt, aux);
elem.dispatchEvent(evt);
},
/**
*
* @param elem
* @param event
* @param func
* @param bool
*/
bind: function(elem, event, func, bool) {
bool = bool || false;
if (elem.addEventListener)
elem.addEventListener(event, func, bool);
else if (elem.attachEvent)
elem.attachEvent('on' + event, func);
return dom;
},
/**
*
* @param elem
* @param event
* @param func
* @param bool
*/
unbind: function(elem, event, func, bool) {
bool = bool || false;
if (elem.removeEventListener)
elem.removeEventListener(event, func, bool);
else if (elem.detachEvent)
elem.detachEvent('on' + event, func);
return dom;
},
/**
*
* @param elem
* @param className
*/
addClass: function(elem, className) {
if (elem.className === undefined) {
elem.className = className;
} else if (elem.className !== className) {
var classes = elem.className.split(/ +/);
if (classes.indexOf(className) == -1) {
classes.push(className);
elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, '');
}
}
return dom;
},
/**
*
* @param elem
* @param className
*/
removeClass: function(elem, className) {
if (className) {
if (elem.className === undefined) {
// elem.className = className;
} else if (elem.className === className) {
elem.removeAttribute('class');
} else {
var classes = elem.className.split(/ +/);
var index = classes.indexOf(className);
if (index != -1) {
classes.splice(index, 1);
elem.className = classes.join(' ');
}
}
} else {
elem.className = undefined;
}
return dom;
},
hasClass: function(elem, className) {
return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false;
},
/**
*
* @param elem
*/
getWidth: function(elem) {
var style = getComputedStyle(elem);
return cssValueToPixels(style['border-left-width']) +
cssValueToPixels(style['border-right-width']) +
cssValueToPixels(style['padding-left']) +
cssValueToPixels(style['padding-right']) +
cssValueToPixels(style['width']);
},
/**
*
* @param elem
*/
getHeight: function(elem) {
var style = getComputedStyle(elem);
return cssValueToPixels(style['border-top-width']) +
cssValueToPixels(style['border-bottom-width']) +
cssValueToPixels(style['padding-top']) +
cssValueToPixels(style['padding-bottom']) +
cssValueToPixels(style['height']);
},
/**
*
* @param elem
*/
getOffset: function(elem) {
var offset = {left: 0, top:0};
if (elem.offsetParent) {
do {
offset.left += elem.offsetLeft;
offset.top += elem.offsetTop;
} while (elem = elem.offsetParent);
}
return offset;
},
// http://stackoverflow.com/posts/2684561/revisions
/**
*
* @param elem
*/
isActive: function(elem) {
return elem === document.activeElement && ( elem.type || elem.href );
} }
}; },
return dom; /**
*
* @param elem
* @param eventType
* @param params
*/
fakeEvent: function(elem, eventType, params, aux) {
params = params || {};
var className = EVENT_MAP_INV[eventType];
if (!className) {
throw new Error('Event type ' + eventType + ' not supported.');
}
var evt = document.createEvent(className);
switch (className) {
case 'MouseEvents':
var clientX = params.x || params.clientX || 0;
var clientY = params.y || params.clientY || 0;
evt.initMouseEvent(eventType, params.bubbles || false,
params.cancelable || true, window, params.clickCount || 1,
0, //screen X
0, //screen Y
clientX, //client X
clientY, //client Y
false, false, false, false, 0, null);
break;
case 'KeyboardEvents':
var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz
common.defaults(params, {
cancelable: true,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
keyCode: undefined,
charCode: undefined
});
init(eventType, params.bubbles || false,
params.cancelable, window,
params.ctrlKey, params.altKey,
params.shiftKey, params.metaKey,
params.keyCode, params.charCode);
break;
default:
evt.initEvent(eventType, params.bubbles || false,
params.cancelable || true);
break;
}
common.defaults(evt, aux);
elem.dispatchEvent(evt);
},
}); /**
*
* @param elem
* @param event
* @param func
* @param bool
*/
bind: function(elem, event, func, bool) {
bool = bool || false;
if (elem.addEventListener)
elem.addEventListener(event, func, bool);
else if (elem.attachEvent)
elem.attachEvent('on' + event, func);
return dom;
},
/**
*
* @param elem
* @param event
* @param func
* @param bool
*/
unbind: function(elem, event, func, bool) {
bool = bool || false;
if (elem.removeEventListener)
elem.removeEventListener(event, func, bool);
else if (elem.detachEvent)
elem.detachEvent('on' + event, func);
return dom;
},
/**
*
* @param elem
* @param className
*/
addClass: function(elem, className) {
if (elem.className === undefined) {
elem.className = className;
} else if (elem.className !== className) {
var classes = elem.className.split(/ +/);
if (classes.indexOf(className) == -1) {
classes.push(className);
elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, '');
}
}
return dom;
},
/**
*
* @param elem
* @param className
*/
removeClass: function(elem, className) {
if (className) {
if (elem.className === undefined) {
// elem.className = className;
} else if (elem.className === className) {
elem.removeAttribute('class');
} else {
var classes = elem.className.split(/ +/);
var index = classes.indexOf(className);
if (index != -1) {
classes.splice(index, 1);
elem.className = classes.join(' ');
}
}
} else {
elem.className = undefined;
}
return dom;
},
hasClass: function(elem, className) {
return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false;
},
/**
*
* @param elem
*/
getWidth: function(elem) {
var style = getComputedStyle(elem);
return cssValueToPixels(style['border-left-width']) +
cssValueToPixels(style['border-right-width']) +
cssValueToPixels(style['padding-left']) +
cssValueToPixels(style['padding-right']) +
cssValueToPixels(style['width']);
},
/**
*
* @param elem
*/
getHeight: function(elem) {
var style = getComputedStyle(elem);
return cssValueToPixels(style['border-top-width']) +
cssValueToPixels(style['border-bottom-width']) +
cssValueToPixels(style['padding-top']) +
cssValueToPixels(style['padding-bottom']) +
cssValueToPixels(style['height']);
},
/**
*
* @param elem
*/
getOffset: function(elem) {
var offset = {
left: 0,
top: 0
};
if (elem.offsetParent) {
do {
offset.left += elem.offsetLeft;
offset.top += elem.offsetTop;
} while (elem = elem.offsetParent);
}
return offset;
},
// http://stackoverflow.com/posts/2684561/revisions
/**
*
* @param elem
*/
isActive: function(elem) {
return elem === document.activeElement && (elem.type || elem.href);
}
};
module.exports = dom;

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,9 @@
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
define([ module.exports = common();
], function() {
function common() {
var ARR_EACH = Array.prototype.forEach; var ARR_EACH = Array.prototype.forEach;
var ARR_SLICE = Array.prototype.slice; var ARR_SLICE = Array.prototype.slice;
@ -63,7 +64,7 @@ define([
args = [toCall[i].apply(this, args)]; args = [toCall[i].apply(this, args)];
} }
return args[0]; return args[0];
} };
}, },
each: function(obj, itr, scope) { each: function(obj, itr, scope) {
@ -136,5 +137,4 @@ define([
} }
}; };
}
});

View File

@ -10,9 +10,9 @@
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
module.exports = css();
define([], function css() {
function() {
return { return {
load: function (url, doc) { load: function (url, doc) {
doc = doc || document; doc = doc || document;
@ -29,5 +29,5 @@ function() {
injected.innerHTML = css; injected.innerHTML = css;
doc.getElementsByTagName('head')[0].appendChild(injected); doc.getElementsByTagName('head')[0].appendChild(injected);
} }
} };
}); }

View File

@ -10,9 +10,9 @@
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
*/ */
module.exports = raf();
define([ function raf() {
], function() {
/** /**
* requirejs version of Paul Irish's RequestAnimationFrame * requirejs version of Paul Irish's RequestAnimationFrame
@ -28,4 +28,4 @@ define([
window.setTimeout(callback, 1000 / 60); window.setTimeout(callback, 1000 / 60);
}; };
}); }

38
src/index.js Normal file
View File

@ -0,0 +1,38 @@
/** @license
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
* Copyright 2015 Andrei Kashcha
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
module.exports = {
color: {
math: require('./dat/color/math.js'),
interpret: require('./dat/color/interpret.js'),
Color: require('./dat/color/Color.js')
},
dom: {
dom: require('./dat/dom/dom.js')
},
controllers: {
Controller: require('./dat/controllers/Controller.js'),
BooleanController: require('./dat/controllers/BooleanController.js'),
OptionController: require('./dat/controllers/OptionController.js'),
StringController: require('./dat/controllers/StringController.js'),
NumberController: require('./dat/controllers/NumberController.js'),
NumberControllerBox: require('./dat/controllers/NumberControllerBox.js'),
NumberControllerSlider: require('./dat/controllers/NumberControllerSlider.js'),
FunctionController: require('./dat/controllers/FunctionController.js'),
ColorController: require('./dat/controllers/ColorController.js'),
},
gui: {
GUI: require('./dat/gui/GUI.js')
},
GUI: require('./dat/gui/GUI.js')
};

View File

@ -1,19 +0,0 @@
var builder = require('./builder.js');
builder.build({
"baseUrl": "../src/",
"main": "dat/gui/GUI",
"out": "../build/dat.gui.js",
"minify": false,
"shortcut": "dat.GUI",
"paths": {}
});
builder.build({
"baseUrl": "../src/",
"main": "dat/gui/GUI",
"out": "../build/dat.gui.min.js",
"minify": true,
"shortcut": "dat.GUI",
"paths": {}
});

View File

@ -1,8 +0,0 @@
require('./builder.js').build({
"baseUrl": "../src/",
"main": "dat/color/Color",
"out": "../build/dat.color.js",
"minify": false,
"shortcut": "dat.Color",
"paths": {}
});

View File

@ -1,8 +0,0 @@
require('./builder.js').build({
"baseUrl": "../src/",
"main": "dat/gui/GUI",
"out": "../build/dat.gui.js",
"minify": false,
"shortcut": "dat.GUI",
"paths": {}
});

View File

@ -1,284 +0,0 @@
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var fs = require('fs'),
closure = require('./closure'),
params,
defined,
third_party,
request_counts,
namespaces,
next_load = '',
next_path = '';
exports.build = build;
exports.file_exists = file_exists;
exports.read_file = read_file;
exports.tab = tab;
exports.license = read_file('license.txt');
function build(_params) {
params = _params;
defined = {};
third_party = {};
request_counts = {};
namespaces = {};
var deps = [];
load_module(params.baseUrl + params.main + '.js', params.main);
for (var i in defined) {
if (params.verbose) console.log('Loaded: ' + defined[i].path);
deps.push(defined[i].path);
if (defined[i].module) {
var namespace = i.substr(0, i.lastIndexOf('/'));
namespaces[namespace] = true;
}
}
var to_write = '';
var ensured = {};
for (var name in params.paths) {
var path = params.baseUrl + params.paths[name] + '.js';
var str = read_file(path);
if (str === false) {
console.log('Failed to locate dependency \'' + name + '\' at ' + path);
fail();
}
third_party[name] = str;
to_write += third_party[name] + "\n\n";
if (params.verbose) console.log('Loaded: ' + path);
//deps.push(path);
}
// Ensure namespaces
for (i in namespaces) {
var split = i.split('/');
for (var j = 0; j < split.length; j++) {
var cur = [];
if (j == 0 && !ensured[split[j]]) {
to_write += '/** @namespace */\n';
to_write += 'var ' + split[j] + ' = ' + split[j] + ' || {};\n\n';
ensured[split[j]] = true;
} else {
for (var k = 0; k <= j; k++) {
cur.push(split[k]);
}
var curn = cur.join('.');
if (!ensured[curn]) {
to_write += '/** @namespace */\n';
to_write += curn + ' = ' + curn + ' || {};\n\n';
}
ensured[curn] = true;
}
}
}
var shared_count = 0;
for (i in request_counts) {
var count = request_counts[i];
if (count > 1) {
if (i in defined) {
var new_shared = i.replace(/\//g, '.');
var v = new_shared + ' = ' + defined[i].getClosure() + ';\n';
to_write += v + "\n\n";
defined[i].shared = new_shared;
shared_count++;
}
}
}
to_write += params.shortcut + ' = ' + params.main.replace(/\//g, '.') + ' = ' + defined[params.main].getClosure() + ';';
if (params.verbose) console.log('Exported: ' + params.main + ' to window.' + params.shortcut);
if (params.minify) {
console.log('Compiling minified source ...');
closure.compile(to_write, function(error, code) {
if (error) {
console.log(error);
} else {
write(exports.license + code);
}
if (params.on_compile) {
params.on_compile();
}
});
} else {
write(exports.license + "\n" + to_write);
}
return deps;
}
function define(deps, callback) {
this.name = next_load;
this.path = next_path;
this.shared = false;
defined[this.name] = this;
if (Array.isArray(deps)) {
this.deps = deps;
this.callback = callback.toString();
this.module = true;
// Simple define call, just an object
} else if (typeof deps === 'object') {
var props = [];
for (var i in deps) {
props.push(i + ':' + deps[i].toString())
}
this.callback = '{' + props.join(',') + '}';
this.module = true;
} else {
this.deps = deps;
this.callback = callback;
}
this.getClosure = function() {
if (this.shared) return this.shared;
if (!this.deps || this.text) return this.callback;
var arg_string = '(';
var args = [];
for (var i in this.deps) {
var dep = this.deps[i];
if (dep in defined) {
var closure = defined[dep].getClosure();
if (!defined[dep].shared && !defined[dep].text) {
closure = defined[dep].name.replace(/\//g, '.') + ' = ' + closure;
}
args.push(closure);
}
}
arg_string += args.join(',\n');
arg_string += ')';
return '(' + this.callback + ')' + arg_string;
};
this.recurseDeps = function() {
if (!this.deps) return;
for (var i in this.deps) {
var dep = this.deps[i];
if (dep in params.paths) continue;
var path = params.baseUrl + dep;
// Define module?
if (file_exists(path + '.js')) {
load_module(path + '.js', dep);
// Text module?
} else if (path.match(/text!/) != null) {
load_text(path.replace('text!', ''), dep);
}
// up the request count
if (dep in request_counts) {
request_counts[dep]++
} else {
request_counts[dep] = 1;
}
}
};
this.recurseDeps();
}
function file_exists(path) {
try {
var stats = fs.lstatSync(path)
return stats.isFile();
} catch (e) {
return false;
}
}
function read_file(path) {
try {
return fs.readFileSync(path).toString();
} catch (e) {
return false;
}
}
function load_module(path, name) {
name = name || path;
if (name in defined) return;
next_load = name;
next_path = path;
eval('new ' + read_file(path));
}
function load_text(path, name) {
name = name || path;
if (name in defined) return;
var text = read_file(path);
text = text.replace(/\r/g, "\\r");
text = text.replace(/\n/g, "\\n");
text = text.replace(/"/g, "\\\"");
next_load = name;
next_path = path;
var d = new define([], '"' + text + '"');
d.text = true;
d.module = false;
}
function tab(str, tabs) {
var lines = str.split("\n");
for (var i in lines) {
lines[i] = tabs + lines[i];
}
return lines.join("\n");
}
function write(str) {
fs.writeFile(params.out, str);
console.log('Saved to ' + params.out);
}
function fail() {
console.log('Build failed.');
process.exit(0);
}

View File

@ -1,108 +0,0 @@
/// # Google Closure Compiler Service #
/// https://github.com/weaver/scribbles/blob/master/node/google-closure/lib/closure.js
/// Compress javascript with Node.js using the Closure Compiler
/// Service.
var sys = require('sys');
exports.compile = compile;
// Use the Google Closure Compiler Service to compress Javascript
// code.
//
// + code - String of javascript to compress
// + next - Function callback that accepts.
//
// This method will POST the `code` to the compiler service. If an
// error occurs, `next()` will be called with an `Error` object as the
// first argument. Otherwise, the `next()` will be called with `null`
// as the first argument and a String of compressed javascript as the
// second argument.
//
// compile('... javascript ...', function(err, result) {
// if (err) throw err;
//
// ... do something with result ...
// });
//
// Returns nothing.
function compile(code, next) {
try {
var qs = require('querystring'),
http = require('http'),
host = 'closure-compiler.appspot.com',
body = qs.stringify({
js_code: code.toString('utf-8'),
compilation_level: 'SIMPLE_OPTIMIZATIONS',
output_format: 'json',
output_info: 'compiled_code'
}),
client = http.createClient(80, host).on('error', next),
req = client.request('POST', '/compile', {
'Host': host,
'Content-Length': body.length,
'Content-Type': 'application/x-www-form-urlencoded'
});
req.on('error', next).end(body);
req.on('response', function(res) {
if (res.statusCode != 200)
next(new Error('Unexpected HTTP response: ' + res.statusCode));
else
capture(res, 'utf-8', parseResponse);
});
function parseResponse(err, data) {
err ? next(err) : loadJSON(data, function(err, obj) {
var error;
if (err)
next(err);
else if ((error = obj.errors || obj.serverErrors || obj.warnings))
next(new Error('Failed to compile: ' + sys.inspect(error)));
else
next(null, obj.compiledCode);
});
}
} catch (err) {
next(err);
}
}
// Convert a Stream to a String.
//
// + input - Stream object
// + encoding - String input encoding
// + next - Function error/success callback
//
// Returns nothing.
function capture(input, encoding, next) {
var buffer = '';
input.on('data', function(chunk) {
buffer += chunk.toString(encoding);
});
input.on('end', function() {
next(null, buffer);
});
input.on('error', next);
}
// Convert JSON.load() to callback-style.
//
// + data - String value to load
// + next - Function error/success callback
//
// Returns nothing.
function loadJSON(data, next) {
var err, obj;
try {
obj = JSON.parse(data);
} catch (x) {
err = x;
}
next(err, obj);
}

View File

@ -1,12 +0,0 @@
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/