diff --git a/.gitignore b/.gitignore index b5d1df4..a72b52e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,15 @@ -.DS_Store -.sass-cache -.idea +lib-cov +*.seed +*.log +*.csv +*.dat +*.out +*.pid +*.gz + +pids +logs +results + +npm-debug.log +node_modules diff --git a/README.md b/README.md index c384a56..c629a26 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,65 @@ -#dat.GUI +# UI Controller (dat.gui ported to commonjs) + 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. ----- +## 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. In your `head` tag, include the following code: -``` + +``` html ``` ----- +## As commonjs module -##Using dat.GUI with require.js -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. +Install the module: -In your `head` tag, include the following code: ``` - +npm install dat.gui ``` -Then, in `path/to/main.js`: -``` -require([ - 'path/to/gui/module/GUI' -], function(GUI) { +Use it: - // No namespace necessary - var gui = new GUI(); +``` js +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. - * 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. + +## Directory Contents + + * build: Concatenated source code for browsers. + * src: source code in commonjs format. * 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: ``` -$ cd utils -$ node build_gui.js +npm start ``` -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. * 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). @@ -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: - * [require.js](http://requirejs.org/) + + * [browserify](http://browserify.org/) * [Sass](http://sass-lang.com/) * [node.js](http://nodejs.org/) - * [QUnit](https://github.com/jquery/qunit) / [jquery](http://jquery.com/) \ No newline at end of file + * [QUnit](https://github.com/jquery/qunit) / [jquery](http://jquery.com/) diff --git a/bower.json b/bower.json index 546d394..49bf1e4 100644 --- a/bower.json +++ b/bower.json @@ -1,9 +1,10 @@ { "name": "dat-gui", - "version": "0.5.0", + "version": "0.5.1", "homepage": "https://github.com/dataarts/dat.gui", "authors": [ - "Google Data Arts Team " + "Google Data Arts Team ", + "Andrei Kashcha " ], "description": "dat.gui is a lightweight controller library for JavaScript.", "main": "/build/dat.gui.js", diff --git a/build/dat.gui.js b/build/dat.gui.js index 78c5363..3ab136d 100644 --- a/build/dat.gui.js +++ b/build/dat.gui.js @@ -1,3 +1,4 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dat = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0; i--) { - args = [toCall[i].apply(this, args)]; - } - return args[0]; - } - }, - - each: function(obj, itr, scope) { + toString: function() { + return toString(this); + }, - if (!obj) return; + toOriginal: function() { + return this.__state.conversion.write(this); + } - if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) { - - obj.forEach(itr, scope); - - } else if (obj.length === obj.length + 0) { // Is number but not NaN - - for (var key = 0, l = obj.length; key < l; key++) - if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) - return; - - } else { +}); - for (var key in obj) - if (itr.call(scope, obj[key], key) === this.BREAK) - return; - - } - - }, - - defer: function(fnc) { - setTimeout(fnc, 0); - }, - - toArray: function(obj) { - if (obj.toArray) return obj.toArray(); - return ARR_SLICE.call(obj); - }, +defineRGBComponent(Color.prototype, 'r', 2); +defineRGBComponent(Color.prototype, 'g', 1); +defineRGBComponent(Color.prototype, 'b', 0); - isUndefined: function(obj) { - return obj === undefined; - }, - - isNull: function(obj) { - return obj === null; - }, - - isNaN: function(obj) { - return obj !== obj; - }, - - isArray: Array.isArray || function(obj) { - return obj.constructor === Array; - }, - - isObject: function(obj) { - return obj === Object(obj); - }, - - isNumber: function(obj) { - return obj === obj+0; - }, - - isString: function(obj) { - return obj === obj+''; - }, - - isBoolean: function(obj) { - return obj === false || obj === true; - }, - - isFunction: function(obj) { - return Object.prototype.toString.call(obj) === '[object Function]'; +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; -dat.controllers.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 - */ - var Controller = function(object, property) { + set: function(v) { - this.initialValue = object[property]; + this.__state.space = 'HEX'; + this.__state.hex = v; - /** - * Those who extend this class will put their DOM elements in here. - * @type {DOMElement} - */ - this.domElement = document.createElement('div'); + } - /** - * The object to manipulate - * @type {Object} - */ - this.object = object; +}); - /** - * The name of the property to manipulate - * @type {String} - */ - this.property = property; +function defineRGBComponent(target, component, componentHexIndex) { - /** - * The function to be called on change. - * @type {Function} - * @ignore - */ - this.__onChange = undefined; + Object.defineProperty(target, component, { - /** - * 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 object[property] - * - * @param {Object} newValue The new value of object[property] - */ - setValue: function(newValue) { - this.object[this.property] = newValue; - if (this.__onChange) { - this.__onChange.call(this, newValue); - } - this.updateDisplay(); - return this; - }, - - /** - * Gets the value of object[property] - * - * @returns {Object} The current value of object[property] - */ - 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() - } + get: function() { + if (this.__state.space === 'RGB') { + return this.__state[component]; } - ); + recalculateRGB(this, component, componentHexIndex); - return Controller; + return this.__state[component]; + }, -})(dat.utils.common); + set: function(v) { + if (this.__state.space !== 'RGB') { + recalculateRGB(this, component, componentHexIndex); + this.__state.space = 'RGB'; + } -dat.dom.dom = (function (common) { + this.__state[component] = v; - var EVENT_MAP = { - 'HTMLEvents': ['change'], - 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'], - 'KeyboardEvents': ['keydown'] - }; + } - var EVENT_MAP_INV = {}; - common.each(EVENT_MAP, function(v, k) { - common.each(v, function(e) { - EVENT_MAP_INV[e] = k; - }); }); - var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/; +} - function cssValueToPixels(val) { +function defineHSVComponent(target, component) { - if (val === '0' || common.isUndefined(val)) return 0; + Object.defineProperty(target, component, { - var match = val.match(CSS_VALUE_PIXELS); + 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; - if (!common.isNull(match)) { - return parseFloat(match[1]); } - // TODO ...ems? %? + }); - return 0; +} + +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'; } - /** - * @namespace - * @member dat.dom - */ - var dom = { +} - /** - * - * @param elem - * @param selectable - */ - makeSelectable: function(elem, selectable) { +function recalculateHSV(color) { - if (elem === undefined || elem.style === undefined) return; + var result = math.rgb_to_hsv(color.r, color.g, color.b); - elem.onselectstart = selectable ? function() { - return false; - } : function() { - }; + common.extend(color.__state, { + s: result.s, + v: result.v + }); - 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; - - elem.style.position = 'absolute'; - - if (horizontal) { - elem.style.left = 0; - elem.style.right = 0; - } - if (vertical) { - 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; - -})(dat.utils.common); - - -dat.controllers.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 - */ - var OptionController = function(object, property, options) { - - OptionController.superclass.call(this, object, property); - - var _this = this; - - /** - * The drop down menu - * @ignore - */ - this.__select = document.createElement('select'); - - if (common.isArray(options)) { - var map = {}; - common.each(options, function(element) { - map[element] = element; - }); - options = map; - } - - 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; - -})(dat.controllers.Controller, -dat.dom.dom, -dat.utils.common); - - -dat.controllers.NumberController = (function (Controller, common) { - - /** - * @class Represents a given property of an object that is a number. - * - * @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} [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 NumberController = function(object, property, params) { - - NumberController.superclass.call(this, object, property); - - params = params || {}; - - this.__min = params.min; - this.__max = params.max; - this.__step = params.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; - } - - } else { - - this.__impliedStep = this.__step; - - } - - 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 object[property]. - * - * @param {Number} minValue The minimum value for - * object[property] - * @returns {dat.controllers.NumberController} this - */ - min: function(v) { - this.__min = v; - return this; - }, - - /** - * Specify a maximum value for object[property]. - * - * @param {Number} maxValue The maximum value for - * object[property] - * @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; - } + if (!common.isNaN(result.h)) { + color.__state.h = result.h; + } else if (common.isUndefined(color.__state.h)) { + color.__state.h = 0; } - return NumberController; - -})(dat.controllers.Controller, -dat.utils.common); - - -dat.controllers.NumberControllerBox = (function (NumberController, dom, common) { - - /** - * @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 - */ - var NumberControllerBox = function(object, property, params) { - - this.__truncationSuspended = false; - - NumberControllerBox.superclass.call(this, object, property, params); - - var _this = this; - - /** - * {Number} Previous mouse y position - * @ignore - */ - var prev_y; - - 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) { - 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; - } - - return NumberControllerBox; - -})(dat.controllers.NumberController, -dat.dom.dom, -dat.utils.common); - - -dat.controllers.NumberControllerSlider = (function (NumberController, dom, css, common, styleSheet) { - - /** - * @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 - * manipulate it. It should be noted that the slider element is made up of - * <div> tags, not the html5 - * <slider> element. - * - * @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 {Number} minValue Minimum allowed value - * @param {Number} maxValue Maximum allowed value - * @param {Number} stepValue Increment by which to change value - * - * @member dat.controllers - */ - var NumberControllerSlider = function(object, property, min, max, step) { - - NumberControllerSlider.superclass.call(this, object, property, { min: min, max: max, step: step }); - - var _this = this; - - this.__background = document.createElement('div'); - this.__foreground = document.createElement('div'); - - - - dom.bind(this.__background, 'mousedown', onMouseDown); - - dom.addClass(this.__background, 'slider'); - dom.addClass(this.__foreground, 'slider-fg'); - - function onMouseDown(e) { - - dom.bind(window, 'mousemove', onMouseDrag); - dom.bind(window, 'mouseup', onMouseUp); - - 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 map(v, i1, i2, o1, o2) { - return o1 + (o2 - o1) * ((v - i1) / (i2 - i1)); - } - - return NumberControllerSlider; - -})(dat.controllers.NumberController, -dat.dom.dom, -dat.utils.css, -dat.utils.common, -"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); - - -dat.controllers.FunctionController = (function (Controller, dom, common) { - - /** - * @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); - - var _this = this; - - 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; - }); - - dom.addClass(this.__button, 'button'); - - this.domElement.appendChild(this.__button); - - - }; - - FunctionController.superclass = Controller; - - common.extend( - - FunctionController.prototype, - Controller.prototype, - { - - fire: function() { - if (this.__onChange) { - this.__onChange.call(this); - } - this.getValue().call(this.object); - if (this.__onFinishChange) { - this.__onFinishChange.call(this, this.getValue()); - } - } - } - - ); - - return FunctionController; - -})(dat.controllers.Controller, -dat.dom.dom, -dat.utils.common); - - -dat.controllers.BooleanController = (function (Controller, dom, common) { - - /** - * @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); - - var _this = this; - this.__prev = this.getValue(); - - this.__checkbox = document.createElement('input'); - this.__checkbox.setAttribute('type', 'checkbox'); - - - dom.bind(this.__checkbox, 'change', onChange, false); - - this.domElement.appendChild(this.__checkbox); - - // Match original value - this.updateDisplay(); - - function onChange() { - _this.setValue(!_this.__prev); - } - - }; - - BooleanController.superclass = Controller; - - common.extend( - - BooleanController.prototype, - Controller.prototype, - - { - - setValue: function(v) { - var toReturn = BooleanController.superclass.prototype.setValue.call(this, v); - if (this.__onFinishChange) { - this.__onFinishChange.call(this, this.getValue()); - } - this.__prev = this.getValue(); - 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); - - } - - - } - - ); - - return BooleanController; - -})(dat.controllers.Controller, -dat.dom.dom, -dat.utils.common); - - -dat.color.toString = (function (common) { - - return function(color) { - - if (color.a == 1 || common.isUndefined(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 + ')'; - - } - - } - -})(dat.utils.common); - - -dat.color.interpret = (function (toString, common) { +} + +},{"../utils/common.js":18,"./interpret.js":2,"./math.js":3,"./toString.js":4}],2:[function(require,module,exports){ +/** + * 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 + */ + +module.exports = createInterpert(); + +function createInterpert() { + var common = require('../utils/common.js'); + var toString = require('./toString.js'); var result, toReturn; @@ -1525,11 +522,1858 @@ dat.color.interpret = (function (toString, common) { return interpret; -})(dat.color.toString, -dat.utils.common); +} + +},{"../utils/common.js":18,"./toString.js":4}],3:[function(require,module,exports){ +/** + * 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 + */ + +module.exports = math(); + +function math() { + + var tmpComponent; + + return { + + hsv_to_rgb: function(h, s, v) { + + var hi = Math.floor(h / 60) % 6; + + var f = h / 60 - Math.floor(h / 60); + var p = v * (1.0 - s); + var q = v * (1.0 - (f * s)); + var t = v * (1.0 - ((1.0 - f) * s)); + var c = [ + [v, t, p], + [q, v, p], + [p, v, t], + [p, q, v], + [t, p, v], + [v, p, q] + ][hi]; + + return { + r: c[0] * 255, + g: c[1] * 255, + b: c[2] * 255 + }; + + }, + + rgb_to_hsv: function(r, g, b) { + + var min = Math.min(r, g, b), + max = Math.max(r, g, b), + delta = max - min, + h, s; + + if (max != 0) { + s = delta / max; + } else { + return { + h: NaN, + s: 0, + v: 0 + }; + } + + if (r == max) { + h = (g - b) / delta; + } else if (g == max) { + h = 2 + (b - r) / delta; + } else { + h = 4 + (r - g) / delta; + } + h /= 6; + if (h < 0) { + h += 1; + } + + return { + h: h * 360, + s: s, + v: max / 255 + }; + }, + + rgb_to_hex: function(r, g, b) { + var hex = this.hex_with_component(0, 2, r); + hex = this.hex_with_component(hex, 1, g); + hex = this.hex_with_component(hex, 0, b); + return hex; + }, + + component_from_hex: function(hex, componentIndex) { + return (hex >> (componentIndex * 8)) & 0xFF; + }, + + hex_with_component: function(hex, componentIndex, value) { + return value << (tmpComponent = componentIndex * 8) | (hex & ~(0xFF << tmpComponent)); + } + + }; +} + +},{}],4:[function(require,module,exports){ +/** + * 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 common = require('../utils/common.js'); + +module.exports = toString; + +function toString(color) { + + if (color.a == 1 || common.isUndefined(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 + ')'; + + } + +} + +},{"../utils/common.js":18}],5:[function(require,module,exports){ +/** + * 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 Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); + +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 + */ +function BooleanController(object, property) { + + BooleanController.superclass.call(this, object, property); + + var _this = this; + this.__prev = this.getValue(); + + this.__checkbox = document.createElement('input'); + this.__checkbox.setAttribute('type', 'checkbox'); -dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) { + dom.bind(this.__checkbox, 'change', onChange, false); + + this.domElement.appendChild(this.__checkbox); + + // Match original value + this.updateDisplay(); + + function onChange() { + _this.setValue(!_this.__prev); + } + +} + +BooleanController.superclass = Controller; + +common.extend( + + BooleanController.prototype, + Controller.prototype, + + { + + setValue: function(v) { + var toReturn = BooleanController.superclass.prototype.setValue.call(this, v); + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + this.__prev = this.getValue(); + 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); + + } + + + } + +); + +},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],6:[function(require,module,exports){ +/** + * 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 Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); +var Color = require('../color/Color.js'); +var interpret = require('../color/interpret.js'); + +module.exports = ColorController; + +function ColorController(object, property) { + + ColorController.superclass.call(this, object, property); + + this.__color = new Color(this.getValue()); + this.__temp = new Color(0); + + var _this = this; + + this.domElement = document.createElement('div'); + + dom.makeSelectable(this.domElement, false); + + this.__selector = document.createElement('div'); + this.__selector.className = 'selector'; + + this.__saturation_field = document.createElement('div'); + this.__saturation_field.className = 'saturation-field'; + + this.__field_knob = document.createElement('div'); + this.__field_knob.className = 'field-knob'; + this.__field_knob_border = '2px solid '; + + this.__hue_knob = document.createElement('div'); + this.__hue_knob.className = 'hue-knob'; + + this.__hue_field = document.createElement('div'); + this.__hue_field.className = 'hue-field'; + + this.__input = document.createElement('input'); + this.__input.type = 'text'; + this.__input_textShadow = '0 1px 1px '; + + dom.bind(this.__input, 'keydown', function(e) { + if (e.keyCode === 13) { // on enter + onBlur.call(this); + } + }); + + dom.bind(this.__input, 'blur', onBlur); + + dom.bind(this.__selector, 'mousedown', function(e) { + + 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()); + + 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.extend(this.__temp.__state, this.__color.__state); + + 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)' + }); + + } + + } + +); + +var vendors = ['-moz-', '-o-', '-webkit-', '-ms-', '']; + +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%);' +} + +},{"../color/Color.js":1,"../color/interpret.js":2,"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],7:[function(require,module,exports){ +/** + * 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 common = require('../utils/common.js'); +module.exports = Controller; + +/** + * @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]; + + /** + * Those who extend this class will put their DOM elements in here. + * @type {DOMElement} + */ + this.domElement = document.createElement('div'); + + /** + * 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 */ + { + + /** + * 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 object[property] + * + * @param {Object} newValue The new value of object[property] + */ + setValue: function(newValue) { + this.object[this.property] = newValue; + if (this.__onChange) { + this.__onChange.call(this, newValue); + } + this.updateDisplay(); + return this; + }, + + /** + * Gets the value of object[property] + * + * @returns {Object} The current value of object[property] + */ + 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(); + } + + } + +); + +},{"../utils/common.js":18}],8:[function(require,module,exports){ +/** + * 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 Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); + +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 + */ +function FunctionController(object, property, text) { + + FunctionController.superclass.call(this, object, property); + + var _this = this; + + 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; + }); + + dom.addClass(this.__button, 'button'); + + this.domElement.appendChild(this.__button); + +} + +FunctionController.superclass = Controller; + +common.extend( + + FunctionController.prototype, + Controller.prototype, { + + fire: function() { + if (this.__onChange) { + this.__onChange.call(this); + } + this.getValue().call(this.object); + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + } + } + +); + +},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],9:[function(require,module,exports){ +/** + * 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 Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +module.exports = NumberController; + +/** + * @class Represents a given property of an object that is a number. + * + * @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} [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 NumberController(object, property, params) { + + NumberController.superclass.call(this, object, property); + + params = params || {}; + + this.__min = params.min; + this.__max = params.max; + this.__step = params.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; + } + + } else { + + this.__impliedStep = this.__step; + + } + + 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 object[property]. + * + * @param {Number} minValue The minimum value for + * object[property] + * @returns {dat.controllers.NumberController} this + */ + min: function(v) { + this.__min = v; + return this; + }, + + /** + * Specify a maximum value for object[property]. + * + * @param {Number} maxValue The maximum value for + * object[property] + * @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; + } +} + +},{"../utils/common.js":18,"./Controller.js":7}],10:[function(require,module,exports){ +/** + * 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 NumberController = require('./NumberController.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); + +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; + + /** + * {Number} Previous mouse y position + * @ignore + */ + var prev_y; + + 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) { + 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; +} + +},{"../dom/dom.js":16,"../utils/common.js":18,"./NumberController.js":9}],11:[function(require,module,exports){ +/** + * 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 NumberController = require('./NumberController.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); +var css = require('../utils/css.js'); + +var styleSheet = "/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"; +module.exports = NumberControllerSlider; + +/** + * @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 + * manipulate it. It should be noted that the slider element is made up of + * <div> tags, not the html5 + * <slider> element. + * + * @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 {Number} minValue Minimum allowed value + * @param {Number} maxValue Maximum allowed value + * @param {Number} stepValue Increment by which to change value + * + * @member dat.controllers + */ +function NumberControllerSlider(object, property, min, max, step) { + + NumberControllerSlider.superclass.call(this, object, property, { + min: min, + max: max, + step: step + }); + + var _this = this; + + this.__background = document.createElement('div'); + this.__foreground = document.createElement('div'); + + + + dom.bind(this.__background, 'mousedown', onMouseDown); + + dom.addClass(this.__background, 'slider'); + dom.addClass(this.__foreground, 'slider-fg'); + + function onMouseDown(e) { + + dom.bind(window, 'mousemove', onMouseDrag); + dom.bind(window, 'mouseup', onMouseUp); + + 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 map(v, i1, i2, o1, o2) { + return o1 + (o2 - o1) * ((v - i1) / (i2 - i1)); +} + +},{"../dom/dom.js":16,"../utils/common.js":18,"../utils/css.js":19,"./NumberController.js":9}],12:[function(require,module,exports){ +/** + * 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 Controller = require('./Controller.js'); +var dom = require('../dom/dom.js'); +var common = require('../utils/common.js'); + +module.exports = OptionController; + +/** + * @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; + + /** + * The drop down menu + * @ignore + */ + this.__select = document.createElement('select'); + + if (common.isArray(options)) { + var map = {}; + common.each(options, function(element) { + map[element] = element; + }); + options = map; + } + + 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); + } + + } + +); + +},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],13:[function(require,module,exports){ +/** + * 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 Controller = require('./Controller.js'); +var dom = require('../dom/dom.js'); +var common = require('../utils/common.js'); + +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 + */ +function StringController(object, property) { + + StringController.superclass.call(this, object, property); + + var _this = this; + + this.__input = document.createElement('input'); + this.__input.setAttribute('type', 'text'); + + dom.bind(this.__input, 'keyup', onChange); + dom.bind(this.__input, 'change', onChange); + 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); + } + + } + +); + +},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],14:[function(require,module,exports){ +/** + * 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 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'); + +module.exports = factory; + +function factory(object, property) { + + var initialValue = object[property]; + + // Providing options? + if (common.isArray(arguments[2]) || common.isObject(arguments[2])) { + return new OptionController(object, property, arguments[2]); + } + + // Providing a map? + + if (common.isNumber(initialValue)) { + + if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) { + + // Has min and max. + return new NumberControllerSlider(object, property, arguments[2], arguments[3]); + + } else { + + return new NumberControllerBox(object, property, { + min: arguments[2], + max: arguments[3] + }); + + } + + } + + if (common.isString(initialValue)) { + return new StringController(object, property); + } + + if (common.isFunction(initialValue)) { + return new FunctionController(object, property, ''); + } + + if (common.isBoolean(initialValue)) { + return new BooleanController(object, property); + } + +} + +},{"../utils/common.js":18,"./BooleanController.js":5,"./FunctionController.js":8,"./NumberControllerBox.js":10,"./NumberControllerSlider.js":11,"./OptionController.js":12,"./StringController.js":13}],15:[function(require,module,exports){ +/** + * 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 common = require('../utils/common.js'); +var dom = require('./dom.js'); + +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' + }); + + + document.body.appendChild(this.backgroundElement); + document.body.appendChild(this.domElement); + + var _this = this; + dom.bind(this.backgroundElement, 'click', function() { + _this.hide(); + }); + + +}; + +CenteredDiv.prototype.show = function() { + + 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); + + }; + + 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); +} + +},{"../utils/common.js":18,"./dom.js":16}],16:[function(require,module,exports){ +/** + * 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 common = require('../utils/common.js'); + +var EVENT_MAP = { + 'HTMLEvents': ['change'], + 'MouseEvents': ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'], + 'KeyboardEvents': ['keydown'] +}; + +var EVENT_MAP_INV = {}; +common.each(EVENT_MAP, function(v, k) { + common.each(v, function(e) { + EVENT_MAP_INV[e] = k; + }); +}); + +var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/; + +function cssValueToPixels(val) { + + if (val === '0' || common.isUndefined(val)) return 0; + + var match = val.match(CSS_VALUE_PIXELS); + + if (!common.isNull(match)) { + return parseFloat(match[1]); + } + + // TODO ...ems? %? + + return 0; + +} + +/** + * @namespace + * @member dat.dom + */ +var dom = { + + /** + * + * @param elem + * @param selectable + */ + makeSelectable: function(elem, selectable) { + + if (elem === undefined || elem.style === undefined) return; + + elem.onselectstart = selectable ? function() { + return false; + } : function() {}; + + 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; + + elem.style.position = 'absolute'; + + if (horizontal) { + elem.style.left = 0; + elem.style.right = 0; + } + if (vertical) { + 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); + } + +}; + +module.exports = dom; + +},{"../utils/common.js":18}],17:[function(require,module,exports){ +/** + * 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 css = require('../utils/css.js'); + +var saveDialogueContents = "
\n\n Here's the new load parameter for your GUI's constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI's constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n
"; +var styleSheet = ".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n"; + +var controllerFactory = require('../controllers/factory.js'); +var Controller = require('../controllers/Controller.js'); +var BooleanController = require('../controllers/BooleanController.js'); +var FunctionController = require('../controllers/FunctionController.js'); +var NumberControllerBox = require('../controllers/NumberControllerBox.js'); +var NumberControllerSlider = require('../controllers/NumberControllerSlider.js'); +var ColorController = require('../controllers/ColorController.js'); + +var raf = require('../utils/requestAnimationFrame.js'); +var CenteredDiv = require('../dom/CenteredDiv.js'); +var dom = require('../dom/dom.js'); +var common = require('../utils/common.js'); + +module.exports = createGUI(); + +function createGUI() { css.inject(styleSheet); @@ -1651,7 +2495,9 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro } else { - params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME }; + params.load = { + preset: DEFAULT_DEFAULT_PRESET_NAME + }; } @@ -1666,166 +2512,166 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro if (params.autoPlace && common.isUndefined(params.scrollable)) { params.scrollable = true; } -// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true; + // params.scrollable = common.isUndefined(params.parent) && params.scrollable === true; // Not part of params because I don't want people passing this in via // constructor. Should be a 'remembered' value. var use_local_storage = - SUPPORTS_LOCAL_STORAGE && - localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true'; + SUPPORTS_LOCAL_STORAGE && + localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true'; var saveToLocalStorage; Object.defineProperties(this, - /** @lends dat.gui.GUI.prototype */ - { + /** @lends dat.gui.GUI.prototype */ + { - /** - * The parent GUI - * @type dat.gui.GUI - */ - parent: { - get: function() { - return params.parent; + /** + * The parent GUI + * @type dat.gui.GUI + */ + parent: { + get: function() { + return params.parent; + } + }, + + scrollable: { + get: function() { + return params.scrollable; + } + }, + + /** + * Handles GUI's element placement for you + * @type Boolean + */ + autoPlace: { + get: function() { + return params.autoPlace; + } + }, + + /** + * The identifier for a set of saved values + * @type String + */ + preset: { + + get: function() { + if (_this.parent) { + return _this.getRoot().preset; + } else { + return params.load.preset; } }, - scrollable: { - get: function() { - return params.scrollable; + set: function(v) { + if (_this.parent) { + _this.getRoot().preset = v; + } else { + params.load.preset = v; } - }, - - /** - * Handles GUI's element placement for you - * @type Boolean - */ - autoPlace: { - get: function() { - return params.autoPlace; - } - }, - - /** - * The identifier for a set of saved values - * @type String - */ - preset: { - - get: function() { - if (_this.parent) { - return _this.getRoot().preset; - } else { - return params.load.preset; - } - }, - - set: function(v) { - if (_this.parent) { - _this.getRoot().preset = v; - } else { - params.load.preset = v; - } - setPresetSelectIndex(this); - _this.revert(); - } - - }, - - /** - * The width of GUI element - * @type Number - */ - width: { - get: function() { - return params.width; - }, - set: function(v) { - params.width = v; - setWidth(_this, v); - } - }, - - /** - * The name of GUI. Used for folders. i.e - * a folder's name - * @type String - */ - name: { - get: function() { - return params.name; - }, - set: function(v) { - // TODO Check for collisions among sibling folders - params.name = v; - if (title_row_name) { - title_row_name.innerHTML = params.name; - } - } - }, - - /** - * Whether the GUI is collapsed or not - * @type Boolean - */ - closed: { - get: function() { - return params.closed; - }, - set: function(v) { - params.closed = v; - if (params.closed) { - dom.addClass(_this.__ul, GUI.CLASS_CLOSED); - } else { - dom.removeClass(_this.__ul, GUI.CLASS_CLOSED); - } - // For browsers that aren't going to respect the CSS transition, - // Lets just check our height against the window height right off - // the bat. - this.onResize(); - - if (_this.__closeButton) { - _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED; - } - } - }, - - /** - * Contains all presets - * @type Object - */ - load: { - get: function() { - return params.load; - } - }, - - /** - * Determines whether or not to use localStorage as the means for - * remembering - * @type Boolean - */ - useLocalStorage: { - - get: function() { - return use_local_storage; - }, - set: function(bool) { - if (SUPPORTS_LOCAL_STORAGE) { - use_local_storage = bool; - if (bool) { - dom.bind(window, 'unload', saveToLocalStorage); - } else { - dom.unbind(window, 'unload', saveToLocalStorage); - } - localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool); - } - } - + setPresetSelectIndex(this); + _this.revert(); } - }); + }, + + /** + * The width of GUI element + * @type Number + */ + width: { + get: function() { + return params.width; + }, + set: function(v) { + params.width = v; + setWidth(_this, v); + } + }, + + /** + * The name of GUI. Used for folders. i.e + * a folder's name + * @type String + */ + name: { + get: function() { + return params.name; + }, + set: function(v) { + // TODO Check for collisions among sibling folders + params.name = v; + if (title_row_name) { + title_row_name.innerHTML = params.name; + } + } + }, + + /** + * Whether the GUI is collapsed or not + * @type Boolean + */ + closed: { + get: function() { + return params.closed; + }, + set: function(v) { + params.closed = v; + if (params.closed) { + dom.addClass(_this.__ul, GUI.CLASS_CLOSED); + } else { + dom.removeClass(_this.__ul, GUI.CLASS_CLOSED); + } + // For browsers that aren't going to respect the CSS transition, + // Lets just check our height against the window height right off + // the bat. + this.onResize(); + + if (_this.__closeButton) { + _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED; + } + } + }, + + /** + * Contains all presets + * @type Object + */ + load: { + get: function() { + return params.load; + } + }, + + /** + * Determines whether or not to use localStorage as the means for + * remembering + * @type Boolean + */ + useLocalStorage: { + + get: function() { + return use_local_storage; + }, + set: function(bool) { + if (SUPPORTS_LOCAL_STORAGE) { + use_local_storage = bool; + if (bool) { + dom.bind(window, 'unload', saveToLocalStorage); + } else { + dom.unbind(window, 'unload', saveToLocalStorage); + } + localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool); + } + } + + } + + }); // Are we a root level GUI? if (common.isUndefined(params.parent)) { @@ -1920,10 +2766,18 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro } - dom.bind(window, 'resize', function() { _this.onResize() }); - dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); }); - dom.bind(this.__ul, 'transitionend', function() { _this.onResize() }); - dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() }); + dom.bind(window, 'resize', function() { + _this.onResize() + }); + dom.bind(this.__ul, 'webkitTransitionEnd', function() { + _this.onResize(); + }); + dom.bind(this.__ul, 'transitionend', function() { + _this.onResize() + }); + dom.bind(this.__ul, 'oTransitionEnd', function() { + _this.onResize() + }); this.onResize(); @@ -1931,7 +2785,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro addResizeHandle(this); } - saveToLocalStorage = function () { + saveToLocalStorage = function() { if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') { localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject())); } @@ -1941,17 +2795,18 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro this.saveToLocalStorageIfPossible = saveToLocalStorage; var root = _this.getRoot(); - function resetWidth() { - var root = _this.getRoot(); - root.width += 1; - common.defer(function() { - root.width -= 1; - }); - } - if (!params.parent) { - resetWidth(); - } + function resetWidth() { + var root = _this.getRoot(); + root.width += 1; + common.defer(function() { + root.width -= 1; + }); + } + + if (!params.parent) { + resetWidth(); + } }; @@ -1980,7 +2835,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro dom.bind(window, 'keydown', function(e) { if (document.activeElement.type !== 'text' && - (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) { + (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) { GUI.toggleHide(); } @@ -1988,307 +2843,308 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro common.extend( - GUI.prototype, + GUI.prototype, - /** @lends dat.gui.GUI */ - { + /** @lends dat.gui.GUI */ + { - /** - * @param object - * @param property - * @returns {dat.controllers.Controller} The new controller that was added. - * @instance - */ - add: function(object, property) { + /** + * @param object + * @param property + * @returns {dat.controllers.Controller} The new controller that was added. + * @instance + */ + add: function(object, property) { - return add( - this, - object, - property, - { - factoryArgs: Array.prototype.slice.call(arguments, 2) - } - ); - - }, - - /** - * @param object - * @param property - * @returns {dat.controllers.ColorController} The new controller that was added. - * @instance - */ - addColor: function(object, property) { - - return add( - this, - object, - property, - { - color: true - } - ); - - }, - - /** - * @param controller - * @instance - */ - remove: function(controller) { - - // TODO listening? - this.__ul.removeChild(controller.__li); - this.__controllers.splice(this.__controllers.indexOf(controller), 1); - var _this = this; - common.defer(function() { - _this.onResize(); - }); - - }, - - destroy: function() { - - if (this.autoPlace) { - auto_place_container.removeChild(this.domElement); + return add( + this, + object, + property, { + factoryArgs: Array.prototype.slice.call(arguments, 2) } + ); - }, + }, - /** - * @param name - * @returns {dat.gui.GUI} The new folder. - * @throws {Error} if this GUI already has a folder by the specified - * name - * @instance - */ - addFolder: function(name) { + /** + * @param object + * @param property + * @returns {dat.controllers.ColorController} The new controller that was added. + * @instance + */ + addColor: function(object, property) { - // We have to prevent collisions on names in order to have a key - // by which to remember saved values - if (this.__folders[name] !== undefined) { - throw new Error('You already have a folder in this GUI by the' + - ' name "' + name + '"'); + return add( + this, + object, + property, { + color: true } + ); - var new_gui_params = { name: name, parent: this }; + }, - // We need to pass down the autoPlace trait so that we can - // attach event listeners to open/close folder actions to - // ensure that a scrollbar appears if the window is too short. - new_gui_params.autoPlace = this.autoPlace; + /** + * @param controller + * @instance + */ + remove: function(controller) { - // Do we have saved appearance data for this folder? + // TODO listening? + this.__ul.removeChild(controller.__li); + this.__controllers.splice(this.__controllers.indexOf(controller), 1); + var _this = this; + common.defer(function() { + _this.onResize(); + }); - if (this.load && // Anything loaded? - this.load.folders && // Was my parent a dead-end? - this.load.folders[name]) { // Did daddy remember me? + }, - // Start me closed if I was closed - new_gui_params.closed = this.load.folders[name].closed; + destroy: function() { - // Pass down the loaded data - new_gui_params.load = this.load.folders[name]; + if (this.autoPlace) { + auto_place_container.removeChild(this.domElement); + } - } + }, - var gui = new GUI(new_gui_params); - this.__folders[name] = gui; + /** + * @param name + * @returns {dat.gui.GUI} The new folder. + * @throws {Error} if this GUI already has a folder by the specified + * name + * @instance + */ + addFolder: function(name) { - var li = addRow(this, gui.domElement); - dom.addClass(li, 'folder'); - return gui; + // We have to prevent collisions on names in order to have a key + // by which to remember saved values + if (this.__folders[name] !== undefined) { + throw new Error('You already have a folder in this GUI by the' + + ' name "' + name + '"'); + } - }, + var new_gui_params = { + name: name, + parent: this + }; - open: function() { - this.closed = false; - }, + // We need to pass down the autoPlace trait so that we can + // attach event listeners to open/close folder actions to + // ensure that a scrollbar appears if the window is too short. + new_gui_params.autoPlace = this.autoPlace; - close: function() { - this.closed = true; - }, + // Do we have saved appearance data for this folder? - onResize: function() { + if (this.load && // Anything loaded? + this.load.folders && // Was my parent a dead-end? + this.load.folders[name]) { // Did daddy remember me? - var root = this.getRoot(); + // Start me closed if I was closed + new_gui_params.closed = this.load.folders[name].closed; - if (root.scrollable) { - - var top = dom.getOffset(root.__ul).top; - var h = 0; - - common.each(root.__ul.childNodes, function(node) { - if (! (root.autoPlace && node === root.__save_row)) - h += dom.getHeight(node); - }); - - if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) { - dom.addClass(root.domElement, GUI.CLASS_TOO_TALL); - root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px'; - } else { - dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL); - root.__ul.style.height = 'auto'; - } - - } - - if (root.__resize_handle) { - common.defer(function() { - root.__resize_handle.style.height = root.__ul.offsetHeight + 'px'; - }); - } - - if (root.__closeButton) { - root.__closeButton.style.width = root.width + 'px'; - } - - }, - - /** - * Mark objects for saving. The order of these objects cannot change as - * the GUI grows. When remembering new objects, append them to the end - * of the list. - * - * @param {Object...} objects - * @throws {Error} if not called on a top level GUI. - * @instance - */ - remember: function() { - - if (common.isUndefined(SAVE_DIALOGUE)) { - SAVE_DIALOGUE = new CenteredDiv(); - SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents; - } - - if (this.parent) { - throw new Error("You can only call remember on a top level GUI."); - } - - var _this = this; - - common.each(Array.prototype.slice.call(arguments), function(object) { - if (_this.__rememberedObjects.length == 0) { - addSaveMenu(_this); - } - if (_this.__rememberedObjects.indexOf(object) == -1) { - _this.__rememberedObjects.push(object); - } - }); - - if (this.autoPlace) { - // Set save row width - setWidth(this, this.width); - } - - }, - - /** - * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI. - * @instance - */ - getRoot: function() { - var gui = this; - while (gui.parent) { - gui = gui.parent; - } - return gui; - }, - - /** - * @returns {Object} a JSON object representing the current state of - * this GUI as well as its remembered properties. - * @instance - */ - getSaveObject: function() { - - var toReturn = this.load; - - toReturn.closed = this.closed; - - // Am I remembering any values? - if (this.__rememberedObjects.length > 0) { - - toReturn.preset = this.preset; - - if (!toReturn.remembered) { - toReturn.remembered = {}; - } - - toReturn.remembered[this.preset] = getCurrentPreset(this); - - } - - toReturn.folders = {}; - common.each(this.__folders, function(element, key) { - toReturn.folders[key] = element.getSaveObject(); - }); - - return toReturn; - - }, - - save: function() { - - if (!this.load.remembered) { - this.load.remembered = {}; - } - - this.load.remembered[this.preset] = getCurrentPreset(this); - markPresetModified(this, false); - this.saveToLocalStorageIfPossible(); - - }, - - saveAs: function(presetName) { - - if (!this.load.remembered) { - - // Retain default values upon first save - this.load.remembered = {}; - this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true); - - } - - this.load.remembered[presetName] = getCurrentPreset(this); - this.preset = presetName; - addPresetOption(this, presetName, true); - this.saveToLocalStorageIfPossible(); - - }, - - revert: function(gui) { - - common.each(this.__controllers, function(controller) { - // Make revert work on Default. - if (!this.getRoot().load.remembered) { - controller.setValue(controller.initialValue); - } else { - recallSavedValue(gui || this.getRoot(), controller); - } - }, this); - - common.each(this.__folders, function(folder) { - folder.revert(folder); - }); - - if (!gui) { - markPresetModified(this.getRoot(), false); - } - - - }, - - listen: function(controller) { - - var init = this.__listening.length == 0; - this.__listening.push(controller); - if (init) updateDisplays(this.__listening); + // Pass down the loaded data + new_gui_params.load = this.load.folders[name]; } + var gui = new GUI(new_gui_params); + this.__folders[name] = gui; + + var li = addRow(this, gui.domElement); + dom.addClass(li, 'folder'); + return gui; + + }, + + open: function() { + this.closed = false; + }, + + close: function() { + this.closed = true; + }, + + onResize: function() { + + var root = this.getRoot(); + + if (root.scrollable) { + + var top = dom.getOffset(root.__ul).top; + var h = 0; + + common.each(root.__ul.childNodes, function(node) { + if (!(root.autoPlace && node === root.__save_row)) + h += dom.getHeight(node); + }); + + if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) { + dom.addClass(root.domElement, GUI.CLASS_TOO_TALL); + root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px'; + } else { + dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL); + root.__ul.style.height = 'auto'; + } + + } + + if (root.__resize_handle) { + common.defer(function() { + root.__resize_handle.style.height = root.__ul.offsetHeight + 'px'; + }); + } + + if (root.__closeButton) { + root.__closeButton.style.width = root.width + 'px'; + } + + }, + + /** + * Mark objects for saving. The order of these objects cannot change as + * the GUI grows. When remembering new objects, append them to the end + * of the list. + * + * @param {Object...} objects + * @throws {Error} if not called on a top level GUI. + * @instance + */ + remember: function() { + + if (common.isUndefined(SAVE_DIALOGUE)) { + SAVE_DIALOGUE = new CenteredDiv(); + SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents; + } + + if (this.parent) { + throw new Error("You can only call remember on a top level GUI."); + } + + var _this = this; + + common.each(Array.prototype.slice.call(arguments), function(object) { + if (_this.__rememberedObjects.length == 0) { + addSaveMenu(_this); + } + if (_this.__rememberedObjects.indexOf(object) == -1) { + _this.__rememberedObjects.push(object); + } + }); + + if (this.autoPlace) { + // Set save row width + setWidth(this, this.width); + } + + }, + + /** + * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI. + * @instance + */ + getRoot: function() { + var gui = this; + while (gui.parent) { + gui = gui.parent; + } + return gui; + }, + + /** + * @returns {Object} a JSON object representing the current state of + * this GUI as well as its remembered properties. + * @instance + */ + getSaveObject: function() { + + var toReturn = this.load; + + toReturn.closed = this.closed; + + // Am I remembering any values? + if (this.__rememberedObjects.length > 0) { + + toReturn.preset = this.preset; + + if (!toReturn.remembered) { + toReturn.remembered = {}; + } + + toReturn.remembered[this.preset] = getCurrentPreset(this); + + } + + toReturn.folders = {}; + common.each(this.__folders, function(element, key) { + toReturn.folders[key] = element.getSaveObject(); + }); + + return toReturn; + + }, + + save: function() { + + if (!this.load.remembered) { + this.load.remembered = {}; + } + + this.load.remembered[this.preset] = getCurrentPreset(this); + markPresetModified(this, false); + this.saveToLocalStorageIfPossible(); + + }, + + saveAs: function(presetName) { + + if (!this.load.remembered) { + + // Retain default values upon first save + this.load.remembered = {}; + this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true); + + } + + this.load.remembered[presetName] = getCurrentPreset(this); + this.preset = presetName; + addPresetOption(this, presetName, true); + this.saveToLocalStorageIfPossible(); + + }, + + revert: function(gui) { + + common.each(this.__controllers, function(controller) { + // Make revert work on Default. + if (!this.getRoot().load.remembered) { + controller.setValue(controller.initialValue); + } else { + recallSavedValue(gui || this.getRoot(), controller); + } + }, this); + + common.each(this.__folders, function(folder) { + folder.revert(folder); + }); + + if (!gui) { + markPresetModified(this.getRoot(), false); + } + + + }, + + listen: function(controller) { + + var init = this.__listening.length == 0; + this.__listening.push(controller); + if (init) updateDisplays(this.__listening); + } + } + ); function add(gui, object, property, params) { @@ -2305,7 +3161,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro } else { - var factoryArgs = [object,property].concat(params.factoryArgs); + var factoryArgs = [object, property].concat(params.factoryArgs); controller = controllerFactory.apply(gui, factoryArgs); } @@ -2371,13 +3227,12 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro controller.remove(); return add( - gui, - controller.object, - controller.property, - { - before: controller.__li.nextElementSibling, - factoryArgs: [common.toArray(arguments)] - } + gui, + controller.object, + controller.property, { + before: controller.__li.nextElementSibling, + factoryArgs: [common.toArray(arguments)] + } ); } @@ -2386,13 +3241,12 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro controller.remove(); return add( - gui, - controller.object, - controller.property, - { - before: controller.__li.nextElementSibling, - factoryArgs: [options] - } + gui, + controller.object, + controller.property, { + before: controller.__li.nextElementSibling, + factoryArgs: [options] + } ); } @@ -2419,8 +3273,11 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro // All sliders should be accompanied by a box. if (controller instanceof NumberControllerSlider) { - var box = new NumberControllerBox(controller.object, controller.property, - { min: controller.__min, max: controller.__max, step: controller.__step }); + var box = new NumberControllerBox(controller.object, controller.property, { + min: controller.__min, + max: controller.__max, + step: controller.__step + }); common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) { var pc = controller[method]; @@ -2435,8 +3292,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro dom.addClass(li, 'has-slider'); controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild); - } - else if (controller instanceof NumberControllerBox) { + } else if (controller instanceof NumberControllerBox) { var r = function(returned) { @@ -2446,13 +3302,12 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro // Well, then lets just replace this with a slider. controller.remove(); return add( - gui, - controller.object, - controller.property, - { - before: controller.__li.nextElementSibling, - factoryArgs: [controller.__min, controller.__max, controller.__step] - }); + gui, + controller.object, + controller.property, { + before: controller.__li.nextElementSibling, + factoryArgs: [controller.__min, controller.__max, controller.__step] + }); } @@ -2463,8 +3318,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro controller.min = common.compose(r, controller.min); controller.max = common.compose(r, controller.max); - } - else if (controller instanceof BooleanController) { + } else if (controller instanceof BooleanController) { dom.bind(li, 'click', function() { dom.fakeEvent(controller.__checkbox, 'click'); @@ -2474,8 +3328,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro e.stopPropagation(); // Prevents double-toggle }) - } - else if (controller instanceof FunctionController) { + } else if (controller instanceof FunctionController) { dom.bind(li, 'click', function() { dom.fakeEvent(controller.__button, 'click'); @@ -2489,8 +3342,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro dom.removeClass(controller.__button, 'hover'); }); - } - else if (controller instanceof ColorController) { + } else if (controller instanceof ColorController) { dom.addClass(li, 'color'); controller.updateDisplay = common.compose(function(r) { @@ -2525,14 +3377,14 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro // Let me fetch a map of controllers for thcommon.isObject. var controller_map = - root.__rememberedObjectIndecesToControllers[matched_index]; + root.__rememberedObjectIndecesToControllers[matched_index]; // Ohp, I believe this is the first controller we've created for this // object. Lets make the map fresh. if (controller_map === undefined) { controller_map = {}; root.__rememberedObjectIndecesToControllers[matched_index] = - controller_map; + controller_map; } // Keep track of this controller @@ -2568,7 +3420,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro if (preset[matched_index] && // Did we remember this particular property? - preset[matched_index][controller.property] !== undefined) { + preset[matched_index][controller.property] !== undefined) { // We did remember something for this guy ... var value = preset[matched_index][controller.property]; @@ -2705,7 +3557,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro gui.revert(); }); -// div.appendChild(button2); + // div.appendChild(button2); } @@ -2720,7 +3572,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro height: '200px', cursor: 'ew-resize', position: 'absolute' -// border: '1px solid blue' + // border: '1px solid blue' }); @@ -2773,7 +3625,8 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro // set the width manually if we want it to bleed to the edge if (gui.__save_row && gui.autoPlace) { gui.__save_row.style.width = w + 'px'; - }if (gui.__closeButton) { + } + if (gui.__closeButton) { gui.__closeButton.style.width = w + 'px'; } } @@ -2789,7 +3642,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro // The controllers I've made for thcommon.isObject by property var controller_map = - gui.__rememberedObjectIndecesToControllers[index]; + gui.__rememberedObjectIndecesToControllers[index]; // Remember each value for each property common.each(controller_map, function(controller, property) { @@ -2825,7 +3678,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro function markPresetModified(gui, modified) { var opt = gui.__preset_select[gui.__preset_select.selectedIndex]; -// console.log('mark', modified, opt); + // console.log('mark', modified, opt); if (modified) { opt.innerHTML = opt.value + "*"; } else { @@ -2838,7 +3691,7 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro if (controllerArray.length != 0) { - requestAnimationFrame(function() { + raf(function() { updateDisplays(controllerArray); }); @@ -2851,705 +3704,201 @@ dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, contro } return GUI; +} -})(dat.utils.css, -"
    \n\n Here's the new load parameter for your GUI's constructor:\n\n \n\n
    \n\n Automatically save\n values to localStorage on exit.\n\n
    The values saved to localStorage will\n override those passed to dat.GUI's constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
    \n \n
    \n\n
    ", -".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n", -dat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) { +},{"../controllers/BooleanController.js":5,"../controllers/ColorController.js":6,"../controllers/Controller.js":7,"../controllers/FunctionController.js":8,"../controllers/NumberControllerBox.js":10,"../controllers/NumberControllerSlider.js":11,"../controllers/factory.js":14,"../dom/CenteredDiv.js":15,"../dom/dom.js":16,"../utils/common.js":18,"../utils/css.js":19,"../utils/requestAnimationFrame.js":20}],18:[function(require,module,exports){ +/** + * 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 + */ - return function(object, property) { +module.exports = common(); - var initialValue = object[property]; +function common() { - // Providing options? - if (common.isArray(arguments[2]) || common.isObject(arguments[2])) { - return new OptionController(object, property, arguments[2]); - } - - // Providing a map? - - if (common.isNumber(initialValue)) { - - if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) { - - // Has min and max. - return new NumberControllerSlider(object, property, arguments[2], arguments[3]); - - } else { - - return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] }); - - } - - } - - if (common.isString(initialValue)) { - return new StringController(object, property); - } - - if (common.isFunction(initialValue)) { - return new FunctionController(object, property, ''); - } - - if (common.isBoolean(initialValue)) { - return new BooleanController(object, property); - } - - } - - })(dat.controllers.OptionController, -dat.controllers.NumberControllerBox, -dat.controllers.NumberControllerSlider, -dat.controllers.StringController = (function (Controller, dom, common) { + var ARR_EACH = Array.prototype.forEach; + var ARR_SLICE = Array.prototype.slice; /** - * @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 + * Band-aid methods for things that should be a lot easier in JavaScript. + * Implementation and structure inspired by underscore.js + * http://documentcloud.github.com/underscore/ */ - var StringController = function(object, property) { - - StringController.superclass.call(this, object, property); - - var _this = this; - - this.__input = document.createElement('input'); - this.__input.setAttribute('type', 'text'); - - dom.bind(this.__input, 'keyup', onChange); - dom.bind(this.__input, 'change', onChange); - 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); - } - - } - - ); - - return StringController; - -})(dat.controllers.Controller, -dat.dom.dom, -dat.utils.common), -dat.controllers.FunctionController, -dat.controllers.BooleanController, -dat.utils.common), -dat.controllers.Controller, -dat.controllers.BooleanController, -dat.controllers.FunctionController, -dat.controllers.NumberControllerBox, -dat.controllers.NumberControllerSlider, -dat.controllers.OptionController, -dat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) { - - var ColorController = function(object, property) { - - ColorController.superclass.call(this, object, property); - - this.__color = new Color(this.getValue()); - this.__temp = new Color(0); - - var _this = this; - - this.domElement = document.createElement('div'); - - dom.makeSelectable(this.domElement, false); - - this.__selector = document.createElement('div'); - this.__selector.className = 'selector'; - - this.__saturation_field = document.createElement('div'); - this.__saturation_field.className = 'saturation-field'; - - this.__field_knob = document.createElement('div'); - this.__field_knob.className = 'field-knob'; - this.__field_knob_border = '2px solid '; - - this.__hue_knob = document.createElement('div'); - this.__hue_knob.className = 'hue-knob'; - - this.__hue_field = document.createElement('div'); - this.__hue_field.className = 'hue-field'; - - this.__input = document.createElement('input'); - this.__input.type = 'text'; - this.__input_textShadow = '0 1px 1px '; - - dom.bind(this.__input, 'keydown', function(e) { - if (e.keyCode === 13) { // on enter - onBlur.call(this); - } - }); - - dom.bind(this.__input, 'blur', onBlur); - - dom.bind(this.__selector, 'mousedown', function(e) { - - 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()); - - 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.extend(this.__temp.__state, this.__color.__state); - - 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)' - }); - - } - - } - - ); - - var vendors = ['-moz-','-o-','-webkit-','-ms-','']; - - 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%);' - } - - - return ColorController; - -})(dat.controllers.Controller, -dat.dom.dom, -dat.color.Color = (function (interpret, math, toString, common) { - - var Color = function() { - - this.__state = interpret.apply(this, arguments); - - if (this.__state === false) { - 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; - - } - - }); - - } - - 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; - } - - } - - return Color; - -})(dat.color.interpret, -dat.color.math = (function () { - - var tmpComponent; return { - hsv_to_rgb: function(h, s, v) { + BREAK: {}, - var hi = Math.floor(h / 60) % 6; + extend: function(target) { - var f = h / 60 - Math.floor(h / 60); - var p = v * (1.0 - s); - var q = v * (1.0 - (f * s)); - var t = v * (1.0 - ((1.0 - f) * s)); - var c = [ - [v, t, p], - [q, v, p], - [p, v, t], - [p, q, v], - [t, p, v], - [v, p, q] - ][hi]; + this.each(ARR_SLICE.call(arguments, 1), function(obj) { - return { - r: c[0] * 255, - g: c[1] * 255, - b: c[2] * 255 - }; + for (var key in obj) + if (!this.isUndefined(obj[key])) + target[key] = obj[key]; + + }, this); + + return target; }, - rgb_to_hsv: function(r, g, b) { + defaults: function(target) { - var min = Math.min(r, g, b), - max = Math.max(r, g, b), - delta = max - min, - h, s; + this.each(ARR_SLICE.call(arguments, 1), function(obj) { + + for (var key in obj) + if (this.isUndefined(target[key])) + target[key] = obj[key]; + + }, this); + + return target; + + }, + + compose: function() { + var toCall = ARR_SLICE.call(arguments); + return function() { + var args = ARR_SLICE.call(arguments); + for (var i = toCall.length -1; i >= 0; i--) { + args = [toCall[i].apply(this, args)]; + } + return args[0]; + }; + }, + + each: function(obj, itr, scope) { + + if (!obj) return; + + if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) { + + obj.forEach(itr, scope); + + } else if (obj.length === obj.length + 0) { // Is number but not NaN + + for (var key = 0, l = obj.length; key < l; key++) + if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) + return; - if (max != 0) { - s = delta / max; } else { - return { - h: NaN, - s: 0, - v: 0 - }; + + for (var key in obj) + if (itr.call(scope, obj[key], key) === this.BREAK) + return; + } - if (r == max) { - h = (g - b) / delta; - } else if (g == max) { - h = 2 + (b - r) / delta; - } else { - h = 4 + (r - g) / delta; - } - h /= 6; - if (h < 0) { - h += 1; - } - - return { - h: h * 360, - s: s, - v: max / 255 - }; }, - rgb_to_hex: function(r, g, b) { - var hex = this.hex_with_component(0, 2, r); - hex = this.hex_with_component(hex, 1, g); - hex = this.hex_with_component(hex, 0, b); - return hex; + defer: function(fnc) { + setTimeout(fnc, 0); }, - component_from_hex: function(hex, componentIndex) { - return (hex >> (componentIndex * 8)) & 0xFF; + toArray: function(obj) { + if (obj.toArray) return obj.toArray(); + return ARR_SLICE.call(obj); }, - hex_with_component: function(hex, componentIndex, value) { - return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent)); + isUndefined: function(obj) { + return obj === undefined; + }, + + isNull: function(obj) { + return obj === null; + }, + + isNaN: function(obj) { + return obj !== obj; + }, + + isArray: Array.isArray || function(obj) { + return obj.constructor === Array; + }, + + isObject: function(obj) { + return obj === Object(obj); + }, + + isNumber: function(obj) { + return obj === obj+0; + }, + + isString: function(obj) { + return obj === obj+''; + }, + + isBoolean: function(obj) { + return obj === false || obj === true; + }, + + isFunction: function(obj) { + return Object.prototype.toString.call(obj) === '[object Function]'; } - } + }; +} -})(), -dat.color.toString, -dat.utils.common), -dat.color.interpret, -dat.utils.common), -dat.utils.requestAnimationFrame = (function () { +},{}],19:[function(require,module,exports){ +/** + * 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 + */ +module.exports = css(); + +function css() { + return { + load: function (url, doc) { + doc = doc || document; + var link = doc.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = url; + doc.getElementsByTagName('head')[0].appendChild(link); + }, + inject: function(css, doc) { + doc = doc || document; + var injected = document.createElement('style'); + injected.type = 'text/css'; + injected.innerHTML = css; + doc.getElementsByTagName('head')[0].appendChild(injected); + } + }; +} + +},{}],20:[function(require,module,exports){ +/** + * 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 + */ +module.exports = raf(); + +function raf() { /** * requirejs version of Paul Irish's RequestAnimationFrame @@ -3565,108 +3914,46 @@ dat.utils.requestAnimationFrame = (function () { window.setTimeout(callback, 1000 / 60); }; -})(), -dat.dom.CenteredDiv = (function (dom, common) { +} +},{}],21:[function(require,module,exports){ +/** @license + * 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 + */ +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') +}; - var CenteredDiv = function() { - - 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' - }); - - - document.body.appendChild(this.backgroundElement); - document.body.appendChild(this.domElement); - - var _this = this; - dom.bind(this.backgroundElement, 'click', function() { - _this.hide(); - }); - - - }; - - CenteredDiv.prototype.show = function() { - - 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); - - }; - - 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; - -})(dat.dom.dom, -dat.utils.common), -dat.dom.dom, -dat.utils.common); \ No newline at end of file +},{"./dat/color/Color.js":1,"./dat/color/interpret.js":2,"./dat/color/math.js":3,"./dat/controllers/BooleanController.js":5,"./dat/controllers/ColorController.js":6,"./dat/controllers/Controller.js":7,"./dat/controllers/FunctionController.js":8,"./dat/controllers/NumberController.js":9,"./dat/controllers/NumberControllerBox.js":10,"./dat/controllers/NumberControllerSlider.js":11,"./dat/controllers/OptionController.js":12,"./dat/controllers/StringController.js":13,"./dat/dom/dom.js":16,"./dat/gui/GUI.js":17}]},{},[21])(21) +}); \ No newline at end of file diff --git a/build/dat.gui.min.js b/build/dat.gui.min.js index 23fd518..a130e8c 100644 --- a/build/dat.gui.min.js +++ b/build/dat.gui.min.js @@ -1,4 +1,7 @@ -/** +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dat=f()}})(function(){var define,module,exports;return function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o1?common.toArray(arguments):arguments[0];common.each(INTERPRETATIONS,function(family){if(family.litmus(original)){common.each(family.conversions,function(conversion,conversionName){result=conversion.read(original);if(toReturn===false&&result!==false){toReturn=result;result.conversionName=conversionName;result.conversion=conversion;return common.BREAK}});return common.BREAK}});return toReturn};var INTERPRETATIONS=[{litmus:common.isString,conversions:{THREE_CHAR_HEX:{read:function(original){var test=original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);if(test===null)return false;return{space:"HEX",hex:parseInt("0x"+test[1].toString()+test[1].toString()+test[2].toString()+test[2].toString()+test[3].toString()+test[3].toString())}},write:toString},SIX_CHAR_HEX:{read:function(original){var test=original.match(/^#([A-F0-9]{6})$/i);if(test===null)return false;return{space:"HEX",hex:parseInt("0x"+test[1].toString())}},write:toString},CSS_RGB:{read:function(original){var test=original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);if(test===null)return false;return{space:"RGB",r:parseFloat(test[1]),g:parseFloat(test[2]),b:parseFloat(test[3])}},write:toString},CSS_RGBA:{read:function(original){var test=original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);if(test===null)return false;return{space:"RGB",r:parseFloat(test[1]),g:parseFloat(test[2]),b:parseFloat(test[3]),a:parseFloat(test[4])}},write:toString}}},{litmus:common.isNumber,conversions:{HEX:{read:function(original){return{space:"HEX",hex:original,conversionName:"HEX"}},write:function(color){return color.hex}}}},{litmus:common.isArray,conversions:{RGB_ARRAY:{read:function(original){if(original.length!=3)return false;return{space:"RGB",r:original[0],g:original[1],b:original[2]}},write:function(color){return[color.r,color.g,color.b]}},RGBA_ARRAY:{read:function(original){if(original.length!=4)return false;return{space:"RGB",r:original[0],g:original[1],b:original[2],a:original[3]}},write:function(color){return[color.r,color.g,color.b,color.a]}}}},{litmus:common.isObject,conversions:{RGBA_OBJ:{read:function(original){if(common.isNumber(original.r)&&common.isNumber(original.g)&&common.isNumber(original.b)&&common.isNumber(original.a)){return{space:"RGB",r:original.r,g:original.g,b:original.b,a:original.a}}return false},write:function(color){return{r:color.r,g:color.g,b:color.b,a:color.a}}},RGB_OBJ:{read:function(original){if(common.isNumber(original.r)&&common.isNumber(original.g)&&common.isNumber(original.b)){return{space:"RGB",r:original.r,g:original.g,b:original.b}}return false},write:function(color){return{r:color.r,g:color.g,b:color.b}}},HSVA_OBJ:{read:function(original){if(common.isNumber(original.h)&&common.isNumber(original.s)&&common.isNumber(original.v)&&common.isNumber(original.a)){return{space:"HSV",h:original.h,s:original.s,v:original.v,a:original.a}}return false},write:function(color){return{h:color.h,s:color.s,v:color.v,a:color.a}}},HSV_OBJ:{read:function(original){if(common.isNumber(original.h)&&common.isNumber(original.s)&&common.isNumber(original.v)){return{space:"HSV",h:original.h,s:original.s,v:original.v}}return false},write:function(color){return{h:color.h,s:color.s,v:color.v}}}}}];return interpret}},{"../utils/common.js":18,"./toString.js":4}],3:[function(require,module,exports){module.exports=math();function math(){var tmpComponent;return{hsv_to_rgb:function(h,s,v){var hi=Math.floor(h/60)%6;var f=h/60-Math.floor(h/60);var p=v*(1-s);var q=v*(1-f*s);var t=v*(1-(1-f)*s);var c=[[v,t,p],[q,v,p],[p,v,t],[p,q,v],[t,p,v],[v,p,q]][hi];return{r:c[0]*255,g:c[1]*255,b:c[2]*255}},rgb_to_hsv:function(r,g,b){var min=Math.min(r,g,b),max=Math.max(r,g,b),delta=max-min,h,s;if(max!=0){s=delta/max}else{return{h:NaN,s:0,v:0}}if(r==max){h=(g-b)/delta}else if(g==max){h=2+(b-r)/delta}else{h=4+(r-g)/delta}h/=6;if(h<0){h+=1}return{h:h*360,s:s,v:max/255}},rgb_to_hex:function(r,g,b){var hex=this.hex_with_component(0,2,r);hex=this.hex_with_component(hex,1,g);hex=this.hex_with_component(hex,0,b);return hex},component_from_hex:function(hex,componentIndex){return hex>>componentIndex*8&255},hex_with_component:function(hex,componentIndex,value){return value<<(tmpComponent=componentIndex*8)|hex&~(255<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;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{}}},this);if(mismatch){common.extend(this.__color.__state,i)}}common.extend(this.__temp.__state,this.__color.__state);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)"})}});var vendors=["-moz-","-o-","-webkit-","-ms-",""];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%);"}},{"../color/Color.js":1,"../color/interpret.js":2,"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],7:[function(require,module,exports){var common=require("../utils/common.js");module.exports=Controller;function Controller(object,property){this.initialValue=object[property];this.domElement=document.createElement("div");this.object=object;this.property=property;this.__onChange=undefined;this.__onFinishChange=undefined}common.extend(Controller.prototype,{onChange:function(fnc){this.__onChange=fnc;return this},onFinishChange:function(fnc){this.__onFinishChange=fnc;return this},setValue:function(newValue){this.object[this.property]=newValue;if(this.__onChange){this.__onChange.call(this,newValue)}this.updateDisplay();return this},getValue:function(){return this.object[this.property]},updateDisplay:function(){return this},isModified:function(){return this.initialValue!==this.getValue()}})},{"../utils/common.js":18}],8:[function(require,module,exports){var Controller=require("./Controller.js");var common=require("../utils/common.js");var dom=require("../dom/dom.js");module.exports=FunctionController;function FunctionController(object,property,text){FunctionController.superclass.call(this,object,property);var _this=this;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});dom.addClass(this.__button,"button");this.domElement.appendChild(this.__button)}FunctionController.superclass=Controller;common.extend(FunctionController.prototype,Controller.prototype,{fire:function(){if(this.__onChange){this.__onChange.call(this)}this.getValue().call(this.object);if(this.__onFinishChange){this.__onFinishChange.call(this,this.getValue())}}})},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],9:[function(require,module,exports){var Controller=require("./Controller.js");var common=require("../utils/common.js");module.exports=NumberController;function NumberController(object,property,params){NumberController.superclass.call(this,object,property);params=params||{};this.__min=params.min;this.__max=params.max;this.__step=params.step;if(common.isUndefined(this.__step)){if(this.initialValue==0){this.__impliedStep=1}else{this.__impliedStep=Math.pow(10,Math.floor(Math.log(this.initialValue)/Math.LN10))/10}}else{this.__impliedStep=this.__step}this.__precision=numDecimals(this.__impliedStep)}NumberController.superclass=Controller;common.extend(NumberController.prototype,Controller.prototype,{setValue:function(v){if(this.__min!==undefined&&vthis.__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)},min:function(v){this.__min=v;return this},max:function(v){this.__max=v;return 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}}},{"../utils/common.js":18,"./Controller.js":7}],10:[function(require,module,exports){var NumberController=require("./NumberController.js");var common=require("../utils/common.js");var dom=require("../dom/dom.js");module.exports=NumberControllerBox;function NumberControllerBox(object,property,params){this.__truncationSuspended=false;NumberControllerBox.superclass.call(this,object,property,params);var _this=this;var prev_y;this.__input=document.createElement("input");this.__input.setAttribute("type","text");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){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){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}},{"../dom/dom.js":16,"../utils/common.js":18,"./NumberController.js":9}],11:[function(require,module,exports){var NumberController=require("./NumberController.js");var common=require("../utils/common.js");var dom=require("../dom/dom.js");var css=require("../utils/css.js");var styleSheet="/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}";module.exports=NumberControllerSlider;function NumberControllerSlider(object,property,min,max,step){NumberControllerSlider.superclass.call(this,object,property,{min:min,max:max,step:step});var _this=this;this.__background=document.createElement("div");this.__foreground=document.createElement("div");dom.bind(this.__background,"mousedown",onMouseDown);dom.addClass(this.__background,"slider");dom.addClass(this.__foreground,"slider-fg");function onMouseDown(e){dom.bind(window,"mousemove",onMouseDrag);dom.bind(window,"mouseup",onMouseUp);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;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){return o1+(o2-o1)*((v-i1)/(i2-i1))}},{"../dom/dom.js":16,"../utils/common.js":18,"../utils/css.js":19,"./NumberController.js":9}],12:[function(require,module,exports){var Controller=require("./Controller.js");var dom=require("../dom/dom.js");var common=require("../utils/common.js");module.exports=OptionController;function OptionController(object,property,options){OptionController.superclass.call(this,object,property);var _this=this;this.__select=document.createElement("select");if(common.isArray(options)){var map={};common.each(options,function(element){map[element]=element});options=map}common.each(options,function(value,key){var opt=document.createElement("option");opt.innerHTML=key;opt.setAttribute("value",value);_this.__select.appendChild(opt)});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)}})},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],13:[function(require,module,exports){var Controller=require("./Controller.js");var dom=require("../dom/dom.js");var common=require("../utils/common.js");module.exports=StringController;function StringController(object,property){StringController.superclass.call(this,object,property);var _this=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");dom.bind(this.__input,"keyup",onChange);dom.bind(this.__input,"change",onChange);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(){if(!dom.isActive(this.__input)){this.__input.value=this.getValue()}return StringController.superclass.prototype.updateDisplay.call(this)}})},{"../dom/dom.js":16,"../utils/common.js":18,"./Controller.js":7}],14:[function(require,module,exports){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");module.exports=factory;function factory(object,property){var initialValue=object[property];if(common.isArray(arguments[2])||common.isObject(arguments[2])){return new OptionController(object,property,arguments[2])}if(common.isNumber(initialValue)){if(common.isNumber(arguments[2])&&common.isNumber(arguments[3])){return new NumberControllerSlider(object,property,arguments[2],arguments[3])}else{return new NumberControllerBox(object,property,{min:arguments[2],max:arguments[3]})}}if(common.isString(initialValue)){return new StringController(object,property)}if(common.isFunction(initialValue)){return new FunctionController(object,property,"")}if(common.isBoolean(initialValue)){return new BooleanController(object,property)}}},{"../utils/common.js":18,"./BooleanController.js":5,"./FunctionController.js":8,"./NumberControllerBox.js":10,"./NumberControllerSlider.js":11,"./OptionController.js":12,"./StringController.js":13}],15:[function(require,module,exports){var common=require("../utils/common.js");var dom=require("./dom.js");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"});document.body.appendChild(this.backgroundElement);document.body.appendChild(this.domElement);var _this=this;dom.bind(this.backgroundElement,"click",function(){_this.hide()})}CenteredDiv.prototype.show=function(){var _this=this;this.backgroundElement.style.display="block";this.domElement.style.display="block";this.domElement.style.opacity=0;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)};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.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)}},{"../utils/common.js":18,"./dom.js":16}],16:[function(require,module,exports){var common=require("../utils/common.js");var EVENT_MAP={HTMLEvents:["change"],MouseEvents:["click","mousemove","mousedown","mouseup","mouseover"],KeyboardEvents:["keydown"]};var EVENT_MAP_INV={};common.each(EVENT_MAP,function(v,k){common.each(v,function(e){EVENT_MAP_INV[e]=k})});var CSS_VALUE_PIXELS=/(\d+(\.\d+)?)px/;function cssValueToPixels(val){if(val==="0"||common.isUndefined(val))return 0;var match=val.match(CSS_VALUE_PIXELS);if(!common.isNull(match)){return parseFloat(match[1])}return 0}var dom={makeSelectable:function(elem,selectable){if(elem===undefined||elem.style===undefined)return;elem.onselectstart=selectable?function(){return false}:function(){};elem.style.MozUserSelect=selectable?"auto":"none";elem.style.KhtmlUserSelect=selectable?"auto":"none";elem.unselectable=selectable?"on":"off"},makeFullscreen:function(elem,horizontal,vertical){if(common.isUndefined(horizontal))horizontal=true;if(common.isUndefined(vertical))vertical=true;elem.style.position="absolute";if(horizontal){elem.style.left=0;elem.style.right=0}if(vertical){elem.style.top=0;elem.style.bottom=0}},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,0,clientX,clientY,false,false,false,false,0,null);break;case"KeyboardEvents":var init=evt.initKeyboardEvent||evt.initKeyEvent;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)},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},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},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},removeClass:function(elem,className){if(className){if(elem.className===undefined){}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},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"])},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"])},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},isActive:function(elem){return elem===document.activeElement&&(elem.type||elem.href)}};module.exports=dom},{"../utils/common.js":18}],17:[function(require,module,exports){var css=require("../utils/css.js");var saveDialogueContents='
    \n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
    \n\n Automatically save\n values to localStorage on exit.\n\n
    The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
    \n \n
    \n\n
    ';var styleSheet=".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n";var controllerFactory=require("../controllers/factory.js");var Controller=require("../controllers/Controller.js");var BooleanController=require("../controllers/BooleanController.js");var FunctionController=require("../controllers/FunctionController.js");var NumberControllerBox=require("../controllers/NumberControllerBox.js");var NumberControllerSlider=require("../controllers/NumberControllerSlider.js");var ColorController=require("../controllers/ColorController.js");var raf=require("../utils/requestAnimationFrame.js");var CenteredDiv=require("../dom/CenteredDiv.js");var dom=require("../dom/dom.js");var common=require("../utils/common.js");module.exports=createGUI();function createGUI(){css.inject(styleSheet);var CSS_NAMESPACE="dg";var HIDE_KEY_CODE=72;var CLOSE_BUTTON_HEIGHT=20;var DEFAULT_DEFAULT_PRESET_NAME="Default";var SUPPORTS_LOCAL_STORAGE=function(){try{return"localStorage"in window&&window["localStorage"]!==null}catch(e){return false}}();var SAVE_DIALOGUE;var auto_place_virgin=true;var auto_place_container;var hide=false;var hideable_guis=[];var GUI=function(params){var _this=this;this.domElement=document.createElement("div");this.__ul=document.createElement("ul");this.domElement.appendChild(this.__ul);dom.addClass(this.domElement,CSS_NAMESPACE);this.__folders={};this.__controllers=[];this.__rememberedObjects=[];this.__rememberedObjectIndecesToControllers=[];this.__listening=[];params=params||{};params=common.defaults(params,{autoPlace:true,width:GUI.DEFAULT_WIDTH});params=common.defaults(params,{resizable:params.autoPlace,hideable:params.autoPlace});if(!common.isUndefined(params.load)){if(params.preset)params.load.preset=params.preset}else{params.load={preset:DEFAULT_DEFAULT_PRESET_NAME}}if(common.isUndefined(params.parent)&¶ms.hideable){hideable_guis.push(this)}params.resizable=common.isUndefined(params.parent)&¶ms.resizable;if(params.autoPlace&&common.isUndefined(params.scrollable)){params.scrollable=true}var use_local_storage=SUPPORTS_LOCAL_STORAGE&&localStorage.getItem(getLocalStorageHash(this,"isLocal"))==="true";var saveToLocalStorage;Object.defineProperties(this,{parent:{get:function(){return params.parent}},scrollable:{get:function(){return params.scrollable}},autoPlace:{get:function(){return params.autoPlace}},preset:{get:function(){if(_this.parent){return _this.getRoot().preset}else{return params.load.preset}},set:function(v){if(_this.parent){_this.getRoot().preset=v}else{params.load.preset=v}setPresetSelectIndex(this);_this.revert()}},width:{get:function(){return params.width},set:function(v){params.width=v;setWidth(_this,v)}},name:{get:function(){return params.name},set:function(v){params.name=v;if(title_row_name){title_row_name.innerHTML=params.name}}},closed:{get:function(){return params.closed},set:function(v){params.closed=v;if(params.closed){dom.addClass(_this.__ul,GUI.CLASS_CLOSED)}else{dom.removeClass(_this.__ul,GUI.CLASS_CLOSED)}this.onResize();if(_this.__closeButton){_this.__closeButton.innerHTML=v?GUI.TEXT_OPEN:GUI.TEXT_CLOSED}}},load:{get:function(){return params.load}},useLocalStorage:{get:function(){return use_local_storage},set:function(bool){if(SUPPORTS_LOCAL_STORAGE){use_local_storage=bool;if(bool){dom.bind(window,"unload",saveToLocalStorage)}else{dom.unbind(window,"unload",saveToLocalStorage)}localStorage.setItem(getLocalStorageHash(_this,"isLocal"),bool)}}}});if(common.isUndefined(params.parent)){params.closed=false;dom.addClass(this.domElement,GUI.CLASS_MAIN);dom.makeSelectable(this.domElement,false);if(SUPPORTS_LOCAL_STORAGE){if(use_local_storage){_this.useLocalStorage=true;var saved_gui=localStorage.getItem(getLocalStorageHash(this,"gui"));if(saved_gui){params.load=JSON.parse(saved_gui)}}}this.__closeButton=document.createElement("div");this.__closeButton.innerHTML=GUI.TEXT_CLOSED;dom.addClass(this.__closeButton,GUI.CLASS_CLOSE_BUTTON);this.domElement.appendChild(this.__closeButton);dom.bind(this.__closeButton,"click",function(){_this.closed=!_this.closed})}else{if(params.closed===undefined){params.closed=true}var title_row_name=document.createTextNode(params.name);dom.addClass(title_row_name,"controller-name");var title_row=addRow(_this,title_row_name);var on_click_title=function(e){e.preventDefault();_this.closed=!_this.closed;return false};dom.addClass(this.__ul,GUI.CLASS_CLOSED);dom.addClass(title_row,"title");dom.bind(title_row,"click",on_click_title);if(!params.closed){this.closed=false}}if(params.autoPlace){if(common.isUndefined(params.parent)){if(auto_place_virgin){auto_place_container=document.createElement("div");dom.addClass(auto_place_container,CSS_NAMESPACE);dom.addClass(auto_place_container,GUI.CLASS_AUTO_PLACE_CONTAINER);document.body.appendChild(auto_place_container);auto_place_virgin=false}auto_place_container.appendChild(this.domElement);dom.addClass(this.domElement,GUI.CLASS_AUTO_PLACE)}if(!this.parent)setWidth(_this,params.width)}dom.bind(window,"resize",function(){_this.onResize()});dom.bind(this.__ul,"webkitTransitionEnd",function(){_this.onResize()});dom.bind(this.__ul,"transitionend",function(){_this.onResize()});dom.bind(this.__ul,"oTransitionEnd",function(){_this.onResize()});this.onResize();if(params.resizable){addResizeHandle(this)}saveToLocalStorage=function(){if(SUPPORTS_LOCAL_STORAGE&&localStorage.getItem(getLocalStorageHash(_this,"isLocal"))==="true"){localStorage.setItem(getLocalStorageHash(_this,"gui"),JSON.stringify(_this.getSaveObject()))}};this.saveToLocalStorageIfPossible=saveToLocalStorage;var root=_this.getRoot();function resetWidth(){var root=_this.getRoot();root.width+=1;common.defer(function(){root.width-=1})}if(!params.parent){resetWidth()}};GUI.toggleHide=function(){hide=!hide;common.each(hideable_guis,function(gui){gui.domElement.style.zIndex=hide?-999:999;gui.domElement.style.opacity=hide?0:1})};GUI.CLASS_AUTO_PLACE="a";GUI.CLASS_AUTO_PLACE_CONTAINER="ac";GUI.CLASS_MAIN="main";GUI.CLASS_CONTROLLER_ROW="cr";GUI.CLASS_TOO_TALL="taller-than-window";GUI.CLASS_CLOSED="closed";GUI.CLASS_CLOSE_BUTTON="close-button";GUI.CLASS_DRAG="drag";GUI.DEFAULT_WIDTH=245;GUI.TEXT_CLOSED="Close Controls";GUI.TEXT_OPEN="Open Controls";dom.bind(window,"keydown",function(e){if(document.activeElement.type!=="text"&&(e.which===HIDE_KEY_CODE||e.keyCode==HIDE_KEY_CODE)){GUI.toggleHide()}},false);common.extend(GUI.prototype,{add:function(object,property){return add(this,object,property,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(object,property){return add(this,object,property,{color:true})},remove:function(controller){this.__ul.removeChild(controller.__li);this.__controllers.splice(this.__controllers.indexOf(controller),1);var _this=this;common.defer(function(){_this.onResize()})},destroy:function(){if(this.autoPlace){auto_place_container.removeChild(this.domElement)}},addFolder:function(name){if(this.__folders[name]!==undefined){throw new Error("You already have a folder in this GUI by the"+' name "'+name+'"')}var new_gui_params={name:name,parent:this};new_gui_params.autoPlace=this.autoPlace;if(this.load&&this.load.folders&&this.load.folders[name]){new_gui_params.closed=this.load.folders[name].closed;new_gui_params.load=this.load.folders[name]}var gui=new GUI(new_gui_params);this.__folders[name]=gui;var li=addRow(this,gui.domElement);dom.addClass(li,"folder");return gui},open:function(){this.closed=false},close:function(){this.closed=true},onResize:function(){var root=this.getRoot();if(root.scrollable){var top=dom.getOffset(root.__ul).top;var h=0;common.each(root.__ul.childNodes,function(node){if(!(root.autoPlace&&node===root.__save_row))h+=dom.getHeight(node)});if(window.innerHeight-top-CLOSE_BUTTON_HEIGHT0){toReturn.preset=this.preset;if(!toReturn.remembered){toReturn.remembered={}}toReturn.remembered[this.preset]=getCurrentPreset(this)}toReturn.folders={};common.each(this.__folders,function(element,key){toReturn.folders[key]=element.getSaveObject()});return toReturn},save:function(){if(!this.load.remembered){this.load.remembered={}}this.load.remembered[this.preset]=getCurrentPreset(this);markPresetModified(this,false);this.saveToLocalStorageIfPossible()},saveAs:function(presetName){if(!this.load.remembered){this.load.remembered={};this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME]=getCurrentPreset(this,true)}this.load.remembered[presetName]=getCurrentPreset(this);this.preset=presetName;addPresetOption(this,presetName,true);this.saveToLocalStorageIfPossible()},revert:function(gui){common.each(this.__controllers,function(controller){if(!this.getRoot().load.remembered){controller.setValue(controller.initialValue)}else{recallSavedValue(gui||this.getRoot(),controller)}},this);common.each(this.__folders,function(folder){folder.revert(folder)});if(!gui){markPresetModified(this.getRoot(),false)}},listen:function(controller){var init=this.__listening.length==0;this.__listening.push(controller);if(init)updateDisplays(this.__listening)}});function add(gui,object,property,params){if(object[property]===undefined){throw new Error("Object "+object+' has no property "'+property+'"')}var controller;if(params.color){controller=new ColorController(object,property)}else{var factoryArgs=[object,property].concat(params.factoryArgs);controller=controllerFactory.apply(gui,factoryArgs)}if(params.before instanceof Controller){params.before=params.before.__li}recallSavedValue(gui,controller);dom.addClass(controller.domElement,"c");var name=document.createElement("span");dom.addClass(name,"property-name");name.innerHTML=controller.property;var container=document.createElement("div");container.appendChild(name);container.appendChild(controller.domElement);var li=addRow(gui,container,params.before);dom.addClass(li,GUI.CLASS_CONTROLLER_ROW);dom.addClass(li,typeof controller.getValue());augmentController(gui,li,controller);gui.__controllers.push(controller);return controller}function addRow(gui,dom,liBefore){var li=document.createElement("li");if(dom)li.appendChild(dom);if(liBefore){gui.__ul.insertBefore(li,params.before)}else{gui.__ul.appendChild(li)}gui.onResize();return li}function augmentController(gui,li,controller){controller.__li=li;controller.__gui=gui;common.extend(controller,{options:function(options){if(arguments.length>1){controller.remove();return add(gui,controller.object,controller.property,{before:controller.__li.nextElementSibling,factoryArgs:[common.toArray(arguments)]})}if(common.isArray(options)||common.isObject(options)){controller.remove();return add(gui,controller.object,controller.property,{before:controller.__li.nextElementSibling,factoryArgs:[options]})}},name:function(v){controller.__li.firstElementChild.firstElementChild.innerHTML=v;return controller},listen:function(){controller.__gui.listen(controller);return controller},remove:function(){controller.__gui.remove(controller);return controller}});if(controller instanceof NumberControllerSlider){var box=new NumberControllerBox(controller.object,controller.property,{min:controller.__min,max:controller.__max,step:controller.__step});common.each(["updateDisplay","onChange","onFinishChange"],function(method){var pc=controller[method];var pb=box[method];controller[method]=box[method]=function(){var args=Array.prototype.slice.call(arguments);pc.apply(controller,args);return pb.apply(box,args)}});dom.addClass(li,"has-slider");controller.domElement.insertBefore(box.domElement,controller.domElement.firstElementChild)}else if(controller instanceof NumberControllerBox){var r=function(returned){if(common.isNumber(controller.__min)&&common.isNumber(controller.__max)){controller.remove();return add(gui,controller.object,controller.property,{before:controller.__li.nextElementSibling,factoryArgs:[controller.__min,controller.__max,controller.__step]})}return returned};controller.min=common.compose(r,controller.min);controller.max=common.compose(r,controller.max)}else if(controller instanceof BooleanController){dom.bind(li,"click",function(){dom.fakeEvent(controller.__checkbox,"click")});dom.bind(controller.__checkbox,"click",function(e){e.stopPropagation()})}else if(controller instanceof FunctionController){dom.bind(li,"click",function(){dom.fakeEvent(controller.__button,"click")});dom.bind(li,"mouseover",function(){dom.addClass(controller.__button,"hover")});dom.bind(li,"mouseout",function(){dom.removeClass(controller.__button,"hover")})}else if(controller instanceof ColorController){dom.addClass(li,"color");controller.updateDisplay=common.compose(function(r){li.style.borderLeftColor=controller.__color.toString();return r},controller.updateDisplay);controller.updateDisplay()}controller.setValue=common.compose(function(r){if(gui.getRoot().__preset_select&&controller.isModified()){markPresetModified(gui.getRoot(),true)}return r},controller.setValue)}function recallSavedValue(gui,controller){var root=gui.getRoot();var matched_index=root.__rememberedObjects.indexOf(controller.object);if(matched_index!=-1){var controller_map=root.__rememberedObjectIndecesToControllers[matched_index];if(controller_map===undefined){controller_map={};root.__rememberedObjectIndecesToControllers[matched_index]=controller_map}controller_map[controller.property]=controller;if(root.load&&root.load.remembered){var preset_map=root.load.remembered;var preset;if(preset_map[gui.preset]){preset=preset_map[gui.preset]}else if(preset_map[DEFAULT_DEFAULT_PRESET_NAME]){preset=preset_map[DEFAULT_DEFAULT_PRESET_NAME]}else{return}if(preset[matched_index]&&preset[matched_index][controller.property]!==undefined){var value=preset[matched_index][controller.property];controller.initialValue=value;controller.setValue(value)}}}}function getLocalStorageHash(gui,key){return document.location.href+"."+key}function addSaveMenu(gui){var div=gui.__save_row=document.createElement("li");dom.addClass(gui.domElement,"has-save");gui.__ul.insertBefore(div,gui.__ul.firstChild);dom.addClass(div,"save-row");var gears=document.createElement("span");gears.innerHTML=" ";dom.addClass(gears,"button gears");var button=document.createElement("span");button.innerHTML="Save";dom.addClass(button,"button");dom.addClass(button,"save");var button2=document.createElement("span");button2.innerHTML="New";dom.addClass(button2,"button");dom.addClass(button2,"save-as");var button3=document.createElement("span");button3.innerHTML="Revert";dom.addClass(button3,"button");dom.addClass(button3,"revert");var select=gui.__preset_select=document.createElement("select");if(gui.load&&gui.load.remembered){common.each(gui.load.remembered,function(value,key){addPresetOption(gui,key,key==gui.preset)})}else{addPresetOption(gui,DEFAULT_DEFAULT_PRESET_NAME,false)}dom.bind(select,"change",function(){for(var index=0;index=0;i--){args=[toCall[i].apply(this,args)]}return args[0]}},each:function(obj,itr,scope){if(!obj)return;if(ARR_EACH&&obj.forEach&&obj.forEach===ARR_EACH){obj.forEach(itr,scope)}else if(obj.length===obj.length+0){for(var key=0,l=obj.length;keythis.__max&&(a=this.__max);void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step);return e.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__impliedStep=this.__step=a;this.__precision=d(a);return this}});return e}(dat.controllers.Controller,dat.utils.common); -dat.controllers.NumberControllerBox=function(f,a,d){var e=function(c,b,f){function q(){var a=parseFloat(n.__input.value);d.isNaN(a)||n.setValue(a)}function l(a){var b=u-a.clientY;n.setValue(n.getValue()+b*n.__impliedStep);u=a.clientY}function r(){a.unbind(window,"mousemove",l);a.unbind(window,"mouseup",r)}this.__truncationSuspended=!1;e.superclass.call(this,c,b,f);var n=this,u;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",q);a.bind(this.__input, -"blur",function(){q();n.__onFinishChange&&n.__onFinishChange.call(n,n.getValue())});a.bind(this.__input,"mousedown",function(b){a.bind(window,"mousemove",l);a.bind(window,"mouseup",r);u=b.clientY});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&(n.__truncationSuspended=!0,this.blur(),n.__truncationSuspended=!1)});this.updateDisplay();this.domElement.appendChild(this.__input)};e.superclass=f;d.extend(e.prototype,f.prototype,{updateDisplay:function(){var a=this.__input,b;if(this.__truncationSuspended)b= -this.getValue();else{b=this.getValue();var d=Math.pow(10,this.__precision);b=Math.round(b*d)/d}a.value=b;return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common); -dat.controllers.NumberControllerSlider=function(f,a,d,e,c){function b(a,b,c,e,d){return e+(a-b)/(c-b)*(d-e)}var p=function(c,e,d,f,u){function A(c){c.preventDefault();var e=a.getOffset(k.__background),d=a.getWidth(k.__background);k.setValue(b(c.clientX,e.left,e.left+d,k.__min,k.__max));return!1}function g(){a.unbind(window,"mousemove",A);a.unbind(window,"mouseup",g);k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())}p.superclass.call(this,c,e,{min:d,max:f,step:u});var k=this;this.__background= -document.createElement("div");this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(b){a.bind(window,"mousemove",A);a.bind(window,"mouseup",g);A(b)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};p.superclass=f;p.useDefaultStyles=function(){d.inject(c)};e.extend(p.prototype,f.prototype,{updateDisplay:function(){var a= -(this.getValue()-this.__min)/(this.__max-this.__min);this.__foreground.style.width=100*a+"%";return p.superclass.prototype.updateDisplay.call(this)}});return p}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); -dat.controllers.FunctionController=function(f,a,d){var e=function(c,b,d){e.superclass.call(this,c,b);var f=this;this.__button=document.createElement("div");this.__button.innerHTML=void 0===d?"Fire":d;a.bind(this.__button,"click",function(a){a.preventDefault();f.fire();return!1});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};e.superclass=f;d.extend(e.prototype,f.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.getValue().call(this.object); -this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); -dat.controllers.BooleanController=function(f,a,d){var e=function(c,b){e.superclass.call(this,c,b);var d=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){d.setValue(!d.__prev)},!1);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};e.superclass=f;d.extend(e.prototype,f.prototype,{setValue:function(a){a=e.superclass.prototype.setValue.call(this,a);this.__onFinishChange&& -this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0):this.__checkbox.checked=!1;return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); -dat.color.toString=function(f){return function(a){if(1==a.a||f.isUndefined(a.a)){for(a=a.hex.toString(16);6>a.length;)a="0"+a;return"#"+a}return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common); -dat.color.interpret=function(f,a){var d,e,c=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:f},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:f},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); -return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:f},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:f}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return 3!= -a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return 4!=a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(b){return a.isNumber(b.r)&&a.isNumber(b.g)&&a.isNumber(b.b)&&a.isNumber(b.a)?{space:"RGB",r:b.r,g:b.g,b:b.b,a:b.a}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(b){return a.isNumber(b.r)&& -a.isNumber(b.g)&&a.isNumber(b.b)?{space:"RGB",r:b.r,g:b.g,b:b.b}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)&&a.isNumber(b.a)?{space:"HSV",h:b.h,s:b.s,v:b.v,a:b.a}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)?{space:"HSV",h:b.h,s:b.s,v:b.v}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){e=!1; -var b=1\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
    \n\n Automatically save\n values to localStorage on exit.\n\n
    The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
    \n \n
    \n\n', -".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n", -dat.controllers.factory=function(f,a,d,e,c,b,p){return function(q,l,r,n){var u=q[l];if(p.isArray(r)||p.isObject(r))return new f(q,l,r);if(p.isNumber(u))return p.isNumber(r)&&p.isNumber(n)?new d(q,l,r,n):new a(q,l,{min:r,max:n});if(p.isString(u))return new e(q,l);if(p.isFunction(u))return new c(q,l,"");if(p.isBoolean(u))return new b(q,l)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(f,a,d){var e= -function(c,b){function d(){f.setValue(f.__input.value)}e.superclass.call(this,c,b);var f=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",d);a.bind(this.__input,"change",d);a.bind(this.__input,"blur",function(){f.__onFinishChange&&f.__onFinishChange.call(f,f.getValue())});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};e.superclass=f;d.extend(e.prototype, -f.prototype,{updateDisplay:function(){a.isActive(this.__input)||(this.__input.value=this.getValue());return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController, -dat.controllers.ColorController=function(f,a,d,e,c){function b(a,b,d,e){a.style.background="";c.each(l,function(c){a.style.cssText+="background: "+c+"linear-gradient("+b+", "+d+" 0%, "+e+" 100%); "})}function p(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; -a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var q=function(f,n){function u(b){v(b);a.bind(window,"mousemove",v);a.bind(window, -"mouseup",l)}function l(){a.unbind(window,"mousemove",v);a.unbind(window,"mouseup",l)}function g(){var a=e(this.value);!1!==a?(t.__color.__state=a,t.setValue(t.__color.toOriginal())):this.value=t.__color.toString()}function k(){a.unbind(window,"mousemove",w);a.unbind(window,"mouseup",k)}function v(b){b.preventDefault();var c=a.getWidth(t.__saturation_field),d=a.getOffset(t.__saturation_field),e=(b.clientX-d.left+document.body.scrollLeft)/c;b=1-(b.clientY-d.top+document.body.scrollTop)/c;1 -b&&(b=0);1e&&(e=0);t.__color.v=b;t.__color.s=e;t.setValue(t.__color.toOriginal());return!1}function w(b){b.preventDefault();var c=a.getHeight(t.__hue_field),d=a.getOffset(t.__hue_field);b=1-(b.clientY-d.top+document.body.scrollTop)/c;1b&&(b=0);t.__color.h=360*b;t.setValue(t.__color.toOriginal());return!1}q.superclass.call(this,f,n);this.__color=new d(this.getValue());this.__temp=new d(0);var t=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement,!1); -this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=document.createElement("input"); -this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){13===a.keyCode&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(b){a.addClass(this,"drag").bind(window,"mouseup",function(b){a.removeClass(t.__selector,"drag")})});var y=document.createElement("div");c.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});c.extend(this.__field_knob.style, -{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});c.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});c.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});c.extend(y.style,{width:"100%",height:"100%", -background:"none"});b(y,"top","rgba(0,0,0,0)","#000");c.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});p(this.__hue_field);c.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",u);a.bind(this.__field_knob,"mousedown",u);a.bind(this.__hue_field,"mousedown",function(b){w(b);a.bind(window, -"mousemove",w);a.bind(window,"mouseup",k)});this.__saturation_field.appendChild(y);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()};q.superclass=f;c.extend(q.prototype,f.prototype,{updateDisplay:function(){var a=e(this.getValue());if(!1!==a){var f=!1; -c.each(d.COMPONENTS,function(b){if(!c.isUndefined(a[b])&&!c.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return f=!0,{}},this);f&&c.extend(this.__color.__state,a)}c.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var l=.5>this.__color.v||.5a&&(a+=1);return{h:360*a,s:c/b,v:b/255}},rgb_to_hex:function(a,d,e){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,d);return a=this.hex_with_component(a,0,e)},component_from_hex:function(a,d){return a>>8*d&255},hex_with_component:function(a,d,e){return e<<(f=8*d)|a&~(255< var obj = { x: 5 }; var gui = new dat.GUI(); - gui.add(obj, 'x'); + gui.add(obj, 'x'); - \ No newline at end of file + diff --git a/package.json b/package.json new file mode 100644 index 0000000..d2691c2 --- /dev/null +++ b/package.json @@ -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" + } +} diff --git a/src/dat/color/Color.js b/src/dat/color/Color.js index 429d314..53b88b7 100644 --- a/src/dat/color/Color.js +++ b/src/dat/color/Color.js @@ -11,179 +11,171 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/color/interpret', - 'dat/color/math', - 'dat/color/toString', - 'dat/utils/common' -], function(interpret, math, toString, common) { +var common = require('../utils/common.js'); +var toString = require('./toString.js'); +var math = require('./math.js'); +var interpret = require('./interpret.js'); - var Color = function() { +module.exports = Color; - this.__state = interpret.apply(this, arguments); +function Color() { - if (this.__state === false) { - 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; - - } - - }); + this.__state = interpret.apply(this, arguments); + 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') - 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; - - } - - }); + toString: function() { + return toString(this); + }, + 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; + } + +} diff --git a/src/dat/color/interpret.js b/src/dat/color/interpret.js index 8e64d03..3fa5366 100644 --- a/src/dat/color/interpret.js +++ b/src/dat/color/interpret.js @@ -11,10 +11,11 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/color/toString', - 'dat/utils/common' -], function(toString, common) { +module.exports = createInterpert(); + +function createInterpert() { + var common = require('../utils/common.js'); + var toString = require('./toString.js'); var result, toReturn; @@ -337,4 +338,4 @@ define([ return interpret; -}); \ No newline at end of file +} diff --git a/src/dat/color/math.js b/src/dat/color/math.js index 6be2613..72696da 100644 --- a/src/dat/color/math.js +++ b/src/dat/color/math.js @@ -11,9 +11,9 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ +module.exports = math(); -], function() { +function math() { var tmpComponent; @@ -47,9 +47,9 @@ define([ rgb_to_hsv: function(r, g, b) { var min = Math.min(r, g, b), - max = Math.max(r, g, b), - delta = max - min, - h, s; + max = Math.max(r, g, b), + delta = max - min, + h, s; if (max != 0) { s = delta / max; @@ -92,9 +92,8 @@ define([ }, hex_with_component: function(hex, componentIndex, value) { - return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent)); + return value << (tmpComponent = componentIndex * 8) | (hex & ~(0xFF << tmpComponent)); } - } - -}); \ No newline at end of file + }; +} diff --git a/src/dat/color/toString.js b/src/dat/color/toString.js index c052a79..5476e36 100644 --- a/src/dat/color/toString.js +++ b/src/dat/color/toString.js @@ -11,27 +11,25 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/utils/common' -], function(common) { +var common = require('../utils/common.js'); - return function(color) { +module.exports = toString; - if (color.a == 1 || common.isUndefined(color.a)) { +function toString(color) { - 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 + ')'; + if (color.a == 1 || common.isUndefined(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 + ')'; + } -}); \ No newline at end of file +} diff --git a/src/dat/controllers/BooleanController.js b/src/dat/controllers/BooleanController.js index 49ddf57..0625d11 100644 --- a/src/dat/controllers/BooleanController.js +++ b/src/dat/controllers/BooleanController.js @@ -11,81 +11,77 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/Controller', - 'dat/dom/dom', - 'dat/utils/common' -], function(Controller, dom, common) { +var Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); - /** - * @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) { +module.exports = BooleanController; - 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; - this.__prev = this.getValue(); + BooleanController.superclass.call(this, object, property); - this.__checkbox = document.createElement('input'); - this.__checkbox.setAttribute('type', 'checkbox'); + var _this = this; + 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 - this.updateDisplay(); + // Match original value + this.updateDisplay(); - function onChange() { - _this.setValue(!_this.__prev); - } + function onChange() { + _this.setValue(!_this.__prev); + } - }; +} - BooleanController.superclass = Controller; +BooleanController.superclass = Controller; - common.extend( +common.extend( - BooleanController.prototype, - Controller.prototype, + BooleanController.prototype, + Controller.prototype, - { + { - setValue: function(v) { - var toReturn = BooleanController.superclass.prototype.setValue.call(this, v); - if (this.__onFinishChange) { - this.__onFinishChange.call(this, this.getValue()); - } - this.__prev = this.getValue(); - 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); - - } + setValue: function(v) { + var toReturn = BooleanController.superclass.prototype.setValue.call(this, v); + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + this.__prev = this.getValue(); + 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); - return BooleanController; + } -}); \ No newline at end of file + + } + +); diff --git a/src/dat/controllers/ColorController.js b/src/dat/controllers/ColorController.js index eef8978..cf16440 100644 --- a/src/dat/controllers/ColorController.js +++ b/src/dat/controllers/ColorController.js @@ -11,314 +11,309 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/Controller', - 'dat/dom/dom', - 'dat/color/Color', - 'dat/color/interpret', - 'dat/utils/common' -], function(Controller, dom, Color, interpret, common) { +var Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); +var Color = require('../color/Color.js'); +var interpret = require('../color/interpret.js'); - var ColorController = function(object, property) { +module.exports = ColorController; - ColorController.superclass.call(this, object, property); +function ColorController(object, property) { - this.__color = new Color(this.getValue()); - this.__temp = new Color(0); + ColorController.superclass.call(this, object, property); - 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'); - this.__selector.className = 'selector'; + dom.makeSelectable(this.domElement, false); - this.__saturation_field = document.createElement('div'); - this.__saturation_field.className = 'saturation-field'; + this.__selector = document.createElement('div'); + this.__selector.className = 'selector'; - this.__field_knob = document.createElement('div'); - this.__field_knob.className = 'field-knob'; - this.__field_knob_border = '2px solid '; + this.__saturation_field = document.createElement('div'); + this.__saturation_field.className = 'saturation-field'; - this.__hue_knob = document.createElement('div'); - this.__hue_knob.className = 'hue-knob'; + this.__field_knob = document.createElement('div'); + this.__field_knob.className = 'field-knob'; + this.__field_knob_border = '2px solid '; - this.__hue_field = document.createElement('div'); - this.__hue_field.className = 'hue-field'; + this.__hue_knob = document.createElement('div'); + this.__hue_knob.className = 'hue-knob'; - this.__input = document.createElement('input'); - this.__input.type = 'text'; - this.__input_textShadow = '0 1px 1px '; + this.__hue_field = document.createElement('div'); + this.__hue_field.className = 'hue-field'; - dom.bind(this.__input, 'keydown', function(e) { - if (e.keyCode === 13) { // on enter - onBlur.call(this); - } - }); + this.__input = document.createElement('input'); + this.__input.type = 'text'; + this.__input_textShadow = '0 1px 1px '; - dom.bind(this.__input, 'blur', onBlur); - - dom.bind(this.__selector, 'mousedown', function(e) { - - 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); + dom.bind(this.__input, 'keydown', function(e) { + if (e.keyCode === 13) { // on enter + onBlur.call(this); } + }); - function unbindSV() { - dom.unbind(window, 'mousemove', setSV); - dom.unbind(window, 'mouseup', unbindSV); - // document.body.style.cursor = 'default'; + dom.bind(this.__input, 'blur', onBlur); + + dom.bind(this.__selector, 'mousedown', function(e) { + + 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) { - _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); - } + var mismatch = false; - 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()); - - 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); - } + // 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); - common.extend(this.__temp.__state, this.__color.__state); - - 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)' - }); - + // If nothing diverges, we keep our previous values + // for statefulness, otherwise we recalculate fresh + if (mismatch) { + common.extend(this.__color.__state, i); } } - ); - - var vendors = ['-moz-','-o-','-webkit-','-ms-','']; - - 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%);' + common.extend(this.__temp.__state, this.__color.__state); + + 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)' + }); + + } + } +); - return ColorController; +var vendors = ['-moz-', '-o-', '-webkit-', '-ms-', '']; -}); \ No newline at end of file +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%);' +} diff --git a/src/dat/controllers/Controller.js b/src/dat/controllers/Controller.js index 3a44df3..648dcbc 100644 --- a/src/dat/controllers/Controller.js +++ b/src/dat/controllers/Controller.js @@ -11,134 +11,128 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/utils/common' -], function(common) { +var common = require('../utils/common.js'); +module.exports = Controller; + +/** + * @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. - * - * @param {Object} object The object to be manipulated - * @param {string} property The name of the property to be manipulated - * - * @member dat.controllers + * Those who extend this class will put their DOM elements in here. + * @type {DOMElement} */ - 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. - * @type {DOMElement} + * 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 */ - this.domElement = document.createElement('div'); + onChange: function(fnc) { + this.__onChange = fnc; + return this; + }, /** - * The object to manipulate - * @type {Object} + * 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 */ - this.object = object; + onFinishChange: function(fnc) { + this.__onFinishChange = fnc; + return this; + }, /** - * The name of the property to manipulate - * @type {String} + * Change the value of object[property] + * + * @param {Object} newValue The new value of object[property] */ - 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 */ - { - - /** - * 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 object[property] - * - * @param {Object} newValue The new value of object[property] - */ - setValue: function(newValue) { - this.object[this.property] = newValue; - if (this.__onChange) { - this.__onChange.call(this, newValue); - } - this.updateDisplay(); - return this; - }, - - /** - * Gets the value of object[property] - * - * @returns {Object} The current value of object[property] - */ - 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() - } - + setValue: function(newValue) { + this.object[this.property] = newValue; + if (this.__onChange) { + this.__onChange.call(this, newValue); } + this.updateDisplay(); + return this; + }, - ); + /** + * Gets the value of object[property] + * + * @returns {Object} The current value of object[property] + */ + 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(); + } -}); \ No newline at end of file + } + +); diff --git a/src/dat/controllers/FunctionController.js b/src/dat/controllers/FunctionController.js index e7748cc..7c28f23 100644 --- a/src/dat/controllers/FunctionController.js +++ b/src/dat/controllers/FunctionController.js @@ -11,64 +11,58 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/Controller', - 'dat/dom/dom', - 'dat/utils/common' -], function(Controller, dom, common) { +var Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); - /** - * @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) { +module.exports = FunctionController; - 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'); - this.__button.innerHTML = text === undefined ? 'Fire' : text; - dom.bind(this.__button, 'click', function(e) { - e.preventDefault(); - _this.fire(); - return false; - }); + var _this = this; - 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, - Controller.prototype, - { - - fire: function() { - if (this.__onChange) { - this.__onChange.call(this); - } - this.getValue().call(this.object); - if (this.__onFinishChange) { - this.__onFinishChange.call(this, this.getValue()); - } - } + FunctionController.prototype, + Controller.prototype, { + + fire: function() { + if (this.__onChange) { + this.__onChange.call(this); } + this.getValue().call(this.object); + if (this.__onFinishChange) { + this.__onFinishChange.call(this, this.getValue()); + } + } + } - ); - - return FunctionController; - -}); +); diff --git a/src/dat/controllers/NumberController.js b/src/dat/controllers/NumberController.js index 294e36c..b16ad8c 100644 --- a/src/dat/controllers/NumberController.js +++ b/src/dat/controllers/NumberController.js @@ -11,135 +11,130 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/Controller', - 'dat/utils/common' -], function(Controller, common) { +var Controller = require('./Controller.js'); +var common = require('../utils/common.js'); +module.exports = NumberController; - /** - * @class Represents a given property of an object that is a number. - * - * @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} [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 NumberController = function(object, property, params) { +/** + * @class Represents a given property of an object that is a number. + * + * @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} [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 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.__max = params.max; - this.__step = params.step; + this.__min = params.min; + this.__max = params.max; + this.__step = params.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 (common.isUndefined(this.__step)) { + if (this.initialValue == 0) { + this.__impliedStep = 1; // What are we, psychics? } else { - - this.__impliedStep = this.__step; - + // Hey Doug, check this out. + 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 object[property]. - * - * @param {Number} minValue The minimum value for - * object[property] - * @returns {dat.controllers.NumberController} this - */ - min: function(v) { - this.__min = v; - return this; - }, - - /** - * Specify a maximum value for object[property]. - * - * @param {Number} maxValue The maximum value for - * object[property] - * @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); -}); \ No newline at end of file + +} + +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 object[property]. + * + * @param {Number} minValue The minimum value for + * object[property] + * @returns {dat.controllers.NumberController} this + */ + min: function(v) { + this.__min = v; + return this; + }, + + /** + * Specify a maximum value for object[property]. + * + * @param {Number} maxValue The maximum value for + * object[property] + * @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; + } +} diff --git a/src/dat/controllers/NumberControllerBox.js b/src/dat/controllers/NumberControllerBox.js index 6ae574d..019399a 100644 --- a/src/dat/controllers/NumberControllerBox.js +++ b/src/dat/controllers/NumberControllerBox.js @@ -11,124 +11,119 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/NumberController', - 'dat/dom/dom', - 'dat/utils/common' -], function(NumberController, dom, common) { +var NumberController = require('./NumberController.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); + +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 - * 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 + * {Number} Previous mouse y position + * @ignore */ - 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) { - /** - * {Number} Previous mouse y position - * @ignore - */ - var prev_y; - - 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); + // When pressing entire, you can be as precise as you want. + if (e.keyCode === 13) { + _this.__truncationSuspended = true; + this.blur(); + _this.__truncationSuspended = false; } - 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; + function onChange() { + var attempted = parseFloat(_this.__input.value); + if (!common.isNaN(attempted)) _this.setValue(attempted); } - 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; +} diff --git a/src/dat/controllers/NumberControllerSlider.js b/src/dat/controllers/NumberControllerSlider.js index 6794008..396740c 100644 --- a/src/dat/controllers/NumberControllerSlider.js +++ b/src/dat/controllers/NumberControllerSlider.js @@ -11,119 +11,118 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/NumberController', - 'dat/dom/dom', - 'dat/utils/css', - 'dat/utils/common', - 'text!dat/controllers/NumberControllerSlider.css' -], -function(NumberController, dom, css, common, styleSheet) { +var NumberController = require('./NumberController.js'); +var common = require('../utils/common.js'); +var dom = require('../dom/dom.js'); +var css = require('../utils/css.js'); +var fs = require('fs'); +var styleSheet = fs.readFileSync(__dirname + '/NumberControllerSlider.css', 'utf8'); +module.exports = NumberControllerSlider; - /** - * @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 - * manipulate it. It should be noted that the slider element is made up of - * <div> tags, not the html5 - * <slider> element. - * - * @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 {Number} minValue Minimum allowed value - * @param {Number} maxValue Maximum allowed value - * @param {Number} stepValue Increment by which to change value - * - * @member dat.controllers - */ - var NumberControllerSlider = function(object, property, min, max, step) { +/** + * @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 + * manipulate it. It should be noted that the slider element is made up of + * <div> tags, not the html5 + * <slider> element. + * + * @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 {Number} minValue Minimum allowed value + * @param {Number} maxValue Maximum allowed value + * @param {Number} stepValue Increment by which to change value + * + * @member dat.controllers + */ +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.__foreground = document.createElement('div'); - + this.__background = document.createElement('div'); + this.__foreground = document.createElement('div'); - dom.bind(this.__background, 'mousedown', onMouseDown); - - dom.addClass(this.__background, 'slider'); - dom.addClass(this.__foreground, 'slider-fg'); - function onMouseDown(e) { + dom.bind(this.__background, 'mousedown', onMouseDown); - dom.bind(window, 'mousemove', onMouseDrag); - dom.bind(window, 'mouseup', onMouseUp); + dom.addClass(this.__background, 'slider'); + dom.addClass(this.__foreground, 'slider-fg'); - onMouseDrag(e); + function onMouseDown(e) { + + dom.bind(window, 'mousemove', onMouseDrag); + dom.bind(window, 'mouseup', onMouseUp); + + 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) { - return o1 + (o2 - o1) * ((v - i1) / (i2 - i1)); - } - - return NumberControllerSlider; - -}); \ No newline at end of file +function map(v, i1, i2, o1, o2) { + return o1 + (o2 - o1) * ((v - i1) / (i2 - i1)); +} diff --git a/src/dat/controllers/OptionController.js b/src/dat/controllers/OptionController.js index 1e9c53e..ad2ab69 100644 --- a/src/dat/controllers/OptionController.js +++ b/src/dat/controllers/OptionController.js @@ -11,93 +11,88 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/Controller', - 'dat/dom/dom', - 'dat/utils/common' -], -function(Controller, dom, common) { +var Controller = require('./Controller.js'); +var dom = require('../dom/dom.js'); +var common = require('../utils/common.js'); + +module.exports = OptionController; + +/** + * @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 - * 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 + * The drop down menu + * @ignore */ - 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) { - /** - * The drop down menu - * @ignore - */ - this.__select = document.createElement('select'); + var opt = document.createElement('option'); + opt.innerHTML = key; + opt.setAttribute('value', value); + _this.__select.appendChild(opt); - if (common.isArray(options)) { - var map = {}; - common.each(options, function(element) { - map[element] = element; - }); - options = map; + }); + + // 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); } - 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; - -}); \ No newline at end of file +); diff --git a/src/dat/controllers/StringController.js b/src/dat/controllers/StringController.js index 75a5fd2..433cf7d 100644 --- a/src/dat/controllers/StringController.js +++ b/src/dat/controllers/StringController.js @@ -11,79 +11,75 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/controllers/Controller', - 'dat/dom/dom', - 'dat/utils/common' -], function(Controller, dom, common) { +var Controller = require('./Controller.js'); +var dom = require('../dom/dom.js'); +var common = require('../utils/common.js'); - /** - * @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) { +module.exports = StringController; - 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'); - this.__input.setAttribute('type', 'text'); + var _this = this; - dom.bind(this.__input, 'keyup', onChange); - dom.bind(this.__input, 'change', onChange); - dom.bind(this.__input, 'blur', onBlur); - dom.bind(this.__input, 'keydown', function(e) { - if (e.keyCode === 13) { - this.blur(); + this.__input = document.createElement('input'); + this.__input.setAttribute('type', 'text'); + + dom.bind(this.__input, 'keyup', onChange); + dom.bind(this.__input, 'change', onChange); + 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(); } - }); - - - function onChange() { - _this.setValue(_this.__input.value); + return StringController.superclass.prototype.updateDisplay.call(this); } - 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; - -}); \ No newline at end of file +); diff --git a/src/dat/controllers/factory.js b/src/dat/controllers/factory.js index 897b267..605efda 100644 --- a/src/dat/controllers/factory.js +++ b/src/dat/controllers/factory.js @@ -10,56 +10,55 @@ * * 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([ - '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) { +module.exports = factory; - return function(object, property) { +function factory(object, property) { - var initialValue = object[property]; + var initialValue = object[property]; - // Providing options? - if (common.isArray(arguments[2]) || common.isObject(arguments[2])) { - return new OptionController(object, property, arguments[2]); - } + // Providing options? + if (common.isArray(arguments[2]) || common.isObject(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. - return new NumberControllerSlider(object, property, arguments[2], arguments[3]); + // Has min and max. + 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)) { - return new StringController(object, property); - } + if (common.isString(initialValue)) { + return new StringController(object, property); + } - if (common.isFunction(initialValue)) { - return new FunctionController(object, property, ''); - } + if (common.isFunction(initialValue)) { + return new FunctionController(object, property, ''); + } - if (common.isBoolean(initialValue)) { - return new BooleanController(object, property); - } + if (common.isBoolean(initialValue)) { + return new BooleanController(object, property); + } - } - - }); \ No newline at end of file +} diff --git a/src/dat/dom/CenteredDiv.js b/src/dat/dom/CenteredDiv.js index 98f0602..0b91cc0 100644 --- a/src/dat/dom/CenteredDiv.js +++ b/src/dat/dom/CenteredDiv.js @@ -11,107 +11,102 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/dom/dom', - 'dat/utils/common' -], function(dom, common) { +var common = require('../utils/common.js'); +var dom = require('./dom.js'); + +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'); - 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 _this = this; + dom.bind(this.backgroundElement, 'click', function() { + _this.hide(); + }); - document.body.appendChild(this.backgroundElement); - document.body.appendChild(this.domElement); +}; - var _this = this; - dom.bind(this.backgroundElement, 'click', function() { - _this.hide(); - }); +CenteredDiv.prototype.show = function() { + 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'; - this.domElement.style.opacity = 0; -// this.domElement.style.top = '52%'; - 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'; +}; - 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); - - }; - - 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; - -}); \ No newline at end of file +function lockScroll(e) { + console.log(e); +} diff --git a/src/dat/dom/dom.js b/src/dat/dom/dom.js index 734bc3e..466f154 100644 --- a/src/dat/dom/dom.js +++ b/src/dat/dom/dom.js @@ -11,277 +11,275 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ - 'dat/utils/common' -], function(common) { +var common = require('../utils/common.js'); - var EVENT_MAP = { - 'HTMLEvents': ['change'], - 'MouseEvents': ['click','mousemove','mousedown','mouseup', 'mouseover'], - 'KeyboardEvents': ['keydown'] - }; +var EVENT_MAP = { + 'HTMLEvents': ['change'], + 'MouseEvents': ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'], + 'KeyboardEvents': ['keydown'] +}; - var EVENT_MAP_INV = {}; - common.each(EVENT_MAP, function(v, k) { - common.each(v, function(e) { - EVENT_MAP_INV[e] = k; - }); +var EVENT_MAP_INV = {}; +common.each(EVENT_MAP, function(v, k) { + common.each(v, function(e) { + 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); - - if (!common.isNull(match)) { - return parseFloat(match[1]); - } - - // TODO ...ems? %? - - return 0; + var match = val.match(CSS_VALUE_PIXELS); + 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) { - /** - * - * @param elem - * @param selectable - */ - makeSelectable: function(elem, selectable) { + if (elem === undefined || elem.style === undefined) return; - if (elem === undefined || elem.style === undefined) return; + elem.onselectstart = selectable ? function() { + return false; + } : function() {}; - elem.onselectstart = selectable ? function() { - return false; - } : function() { - }; + elem.style.MozUserSelect = selectable ? 'auto' : 'none'; + elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none'; + 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) { - /** - * - * @param elem - * @param horizontal - * @param vertical - */ - makeFullscreen: function(elem, horizontal, vertical) { + if (common.isUndefined(horizontal)) horizontal = true; + if (common.isUndefined(vertical)) vertical = true; - if (common.isUndefined(horizontal)) horizontal = true; - if (common.isUndefined(vertical)) vertical = true; + elem.style.position = 'absolute'; - elem.style.position = 'absolute'; - - if (horizontal) { - elem.style.left = 0; - elem.style.right = 0; - } - if (vertical) { - 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 ); + if (horizontal) { + elem.style.left = 0; + elem.style.right = 0; + } + if (vertical) { + elem.style.top = 0; + elem.style.bottom = 0; } - }; + }, - 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); + }, -}); \ No newline at end of file + /** + * + * @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; diff --git a/src/dat/gui/GUI.js b/src/dat/gui/GUI.js index b0f61d3..2fa9e51 100644 --- a/src/dat/gui/GUI.js +++ b/src/dat/gui/GUI.js @@ -10,31 +10,28 @@ * * http://www.apache.org/licenses/LICENSE-2.0 */ +var fs = require('fs'); +var css = require('../utils/css.js'); -define([ +var saveDialogueContents = fs.readFileSync(__dirname + '/saveDialogue.html', 'utf8'); +var styleSheet = fs.readFileSync(__dirname + '/style.css', 'utf8'); - 'dat/utils/css', +var controllerFactory = require('../controllers/factory.js'); +var Controller = require('../controllers/Controller.js'); +var BooleanController = require('../controllers/BooleanController.js'); +var FunctionController = require('../controllers/FunctionController.js'); +var NumberControllerBox = require('../controllers/NumberControllerBox.js'); +var NumberControllerSlider = require('../controllers/NumberControllerSlider.js'); +var ColorController = require('../controllers/ColorController.js'); - 'text!dat/gui/saveDialogue.html', - 'text!dat/gui/style.css', +var raf = require('../utils/requestAnimationFrame.js'); +var CenteredDiv = require('../dom/CenteredDiv.js'); +var dom = require('../dom/dom.js'); +var common = require('../utils/common.js'); - 'dat/controllers/factory', - 'dat/controllers/Controller', - 'dat/controllers/BooleanController', - 'dat/controllers/FunctionController', - 'dat/controllers/NumberControllerBox', - 'dat/controllers/NumberControllerSlider', - 'dat/controllers/OptionController', - 'dat/controllers/ColorController', +module.exports = createGUI(); - 'dat/utils/requestAnimationFrame', - - 'dat/dom/CenteredDiv', - 'dat/dom/dom', - - 'dat/utils/common' - -], function(css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) { +function createGUI() { css.inject(styleSheet); @@ -156,7 +153,9 @@ define([ } else { - params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME }; + params.load = { + preset: DEFAULT_DEFAULT_PRESET_NAME + }; } @@ -171,166 +170,166 @@ define([ if (params.autoPlace && common.isUndefined(params.scrollable)) { params.scrollable = true; } -// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true; + // params.scrollable = common.isUndefined(params.parent) && params.scrollable === true; // Not part of params because I don't want people passing this in via // constructor. Should be a 'remembered' value. var use_local_storage = - SUPPORTS_LOCAL_STORAGE && - localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true'; + SUPPORTS_LOCAL_STORAGE && + localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true'; var saveToLocalStorage; Object.defineProperties(this, - /** @lends dat.gui.GUI.prototype */ - { + /** @lends dat.gui.GUI.prototype */ + { - /** - * The parent GUI - * @type dat.gui.GUI - */ - parent: { - get: function() { - return params.parent; + /** + * The parent GUI + * @type dat.gui.GUI + */ + parent: { + get: function() { + return params.parent; + } + }, + + scrollable: { + get: function() { + return params.scrollable; + } + }, + + /** + * Handles GUI's element placement for you + * @type Boolean + */ + autoPlace: { + get: function() { + return params.autoPlace; + } + }, + + /** + * The identifier for a set of saved values + * @type String + */ + preset: { + + get: function() { + if (_this.parent) { + return _this.getRoot().preset; + } else { + return params.load.preset; } }, - scrollable: { - get: function() { - return params.scrollable; + set: function(v) { + if (_this.parent) { + _this.getRoot().preset = v; + } else { + params.load.preset = v; } - }, - - /** - * Handles GUI's element placement for you - * @type Boolean - */ - autoPlace: { - get: function() { - return params.autoPlace; - } - }, - - /** - * The identifier for a set of saved values - * @type String - */ - preset: { - - get: function() { - if (_this.parent) { - return _this.getRoot().preset; - } else { - return params.load.preset; - } - }, - - set: function(v) { - if (_this.parent) { - _this.getRoot().preset = v; - } else { - params.load.preset = v; - } - setPresetSelectIndex(this); - _this.revert(); - } - - }, - - /** - * The width of GUI element - * @type Number - */ - width: { - get: function() { - return params.width; - }, - set: function(v) { - params.width = v; - setWidth(_this, v); - } - }, - - /** - * The name of GUI. Used for folders. i.e - * a folder's name - * @type String - */ - name: { - get: function() { - return params.name; - }, - set: function(v) { - // TODO Check for collisions among sibling folders - params.name = v; - if (title_row_name) { - title_row_name.innerHTML = params.name; - } - } - }, - - /** - * Whether the GUI is collapsed or not - * @type Boolean - */ - closed: { - get: function() { - return params.closed; - }, - set: function(v) { - params.closed = v; - if (params.closed) { - dom.addClass(_this.__ul, GUI.CLASS_CLOSED); - } else { - dom.removeClass(_this.__ul, GUI.CLASS_CLOSED); - } - // For browsers that aren't going to respect the CSS transition, - // Lets just check our height against the window height right off - // the bat. - this.onResize(); - - if (_this.__closeButton) { - _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED; - } - } - }, - - /** - * Contains all presets - * @type Object - */ - load: { - get: function() { - return params.load; - } - }, - - /** - * Determines whether or not to use localStorage as the means for - * remembering - * @type Boolean - */ - useLocalStorage: { - - get: function() { - return use_local_storage; - }, - set: function(bool) { - if (SUPPORTS_LOCAL_STORAGE) { - use_local_storage = bool; - if (bool) { - dom.bind(window, 'unload', saveToLocalStorage); - } else { - dom.unbind(window, 'unload', saveToLocalStorage); - } - localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool); - } - } - + setPresetSelectIndex(this); + _this.revert(); } - }); + }, + + /** + * The width of GUI element + * @type Number + */ + width: { + get: function() { + return params.width; + }, + set: function(v) { + params.width = v; + setWidth(_this, v); + } + }, + + /** + * The name of GUI. Used for folders. i.e + * a folder's name + * @type String + */ + name: { + get: function() { + return params.name; + }, + set: function(v) { + // TODO Check for collisions among sibling folders + params.name = v; + if (title_row_name) { + title_row_name.innerHTML = params.name; + } + } + }, + + /** + * Whether the GUI is collapsed or not + * @type Boolean + */ + closed: { + get: function() { + return params.closed; + }, + set: function(v) { + params.closed = v; + if (params.closed) { + dom.addClass(_this.__ul, GUI.CLASS_CLOSED); + } else { + dom.removeClass(_this.__ul, GUI.CLASS_CLOSED); + } + // For browsers that aren't going to respect the CSS transition, + // Lets just check our height against the window height right off + // the bat. + this.onResize(); + + if (_this.__closeButton) { + _this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED; + } + } + }, + + /** + * Contains all presets + * @type Object + */ + load: { + get: function() { + return params.load; + } + }, + + /** + * Determines whether or not to use localStorage as the means for + * remembering + * @type Boolean + */ + useLocalStorage: { + + get: function() { + return use_local_storage; + }, + set: function(bool) { + if (SUPPORTS_LOCAL_STORAGE) { + use_local_storage = bool; + if (bool) { + dom.bind(window, 'unload', saveToLocalStorage); + } else { + dom.unbind(window, 'unload', saveToLocalStorage); + } + localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool); + } + } + + } + + }); // Are we a root level GUI? if (common.isUndefined(params.parent)) { @@ -425,10 +424,18 @@ define([ } - dom.bind(window, 'resize', function() { _this.onResize() }); - dom.bind(this.__ul, 'webkitTransitionEnd', function() { _this.onResize(); }); - dom.bind(this.__ul, 'transitionend', function() { _this.onResize() }); - dom.bind(this.__ul, 'oTransitionEnd', function() { _this.onResize() }); + dom.bind(window, 'resize', function() { + _this.onResize() + }); + dom.bind(this.__ul, 'webkitTransitionEnd', function() { + _this.onResize(); + }); + dom.bind(this.__ul, 'transitionend', function() { + _this.onResize() + }); + dom.bind(this.__ul, 'oTransitionEnd', function() { + _this.onResize() + }); this.onResize(); @@ -436,7 +443,7 @@ define([ addResizeHandle(this); } - saveToLocalStorage = function () { + saveToLocalStorage = function() { if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') { localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject())); } @@ -446,17 +453,18 @@ define([ this.saveToLocalStorageIfPossible = saveToLocalStorage; var root = _this.getRoot(); - function resetWidth() { - var root = _this.getRoot(); - root.width += 1; - common.defer(function() { - root.width -= 1; - }); - } - if (!params.parent) { - resetWidth(); - } + function resetWidth() { + var root = _this.getRoot(); + root.width += 1; + common.defer(function() { + root.width -= 1; + }); + } + + if (!params.parent) { + resetWidth(); + } }; @@ -485,7 +493,7 @@ define([ dom.bind(window, 'keydown', function(e) { if (document.activeElement.type !== 'text' && - (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) { + (e.which === HIDE_KEY_CODE || e.keyCode == HIDE_KEY_CODE)) { GUI.toggleHide(); } @@ -493,307 +501,308 @@ define([ common.extend( - GUI.prototype, + GUI.prototype, - /** @lends dat.gui.GUI */ - { + /** @lends dat.gui.GUI */ + { - /** - * @param object - * @param property - * @returns {dat.controllers.Controller} The new controller that was added. - * @instance - */ - add: function(object, property) { + /** + * @param object + * @param property + * @returns {dat.controllers.Controller} The new controller that was added. + * @instance + */ + add: function(object, property) { - return add( - this, - object, - property, - { - factoryArgs: Array.prototype.slice.call(arguments, 2) - } - ); - - }, - - /** - * @param object - * @param property - * @returns {dat.controllers.ColorController} The new controller that was added. - * @instance - */ - addColor: function(object, property) { - - return add( - this, - object, - property, - { - color: true - } - ); - - }, - - /** - * @param controller - * @instance - */ - remove: function(controller) { - - // TODO listening? - this.__ul.removeChild(controller.__li); - this.__controllers.splice(this.__controllers.indexOf(controller), 1); - var _this = this; - common.defer(function() { - _this.onResize(); - }); - - }, - - destroy: function() { - - if (this.autoPlace) { - auto_place_container.removeChild(this.domElement); + return add( + this, + object, + property, { + factoryArgs: Array.prototype.slice.call(arguments, 2) } + ); - }, + }, - /** - * @param name - * @returns {dat.gui.GUI} The new folder. - * @throws {Error} if this GUI already has a folder by the specified - * name - * @instance - */ - addFolder: function(name) { + /** + * @param object + * @param property + * @returns {dat.controllers.ColorController} The new controller that was added. + * @instance + */ + addColor: function(object, property) { - // We have to prevent collisions on names in order to have a key - // by which to remember saved values - if (this.__folders[name] !== undefined) { - throw new Error('You already have a folder in this GUI by the' + - ' name "' + name + '"'); + return add( + this, + object, + property, { + color: true } + ); - var new_gui_params = { name: name, parent: this }; + }, - // We need to pass down the autoPlace trait so that we can - // attach event listeners to open/close folder actions to - // ensure that a scrollbar appears if the window is too short. - new_gui_params.autoPlace = this.autoPlace; + /** + * @param controller + * @instance + */ + remove: function(controller) { - // Do we have saved appearance data for this folder? + // TODO listening? + this.__ul.removeChild(controller.__li); + this.__controllers.splice(this.__controllers.indexOf(controller), 1); + var _this = this; + common.defer(function() { + _this.onResize(); + }); - if (this.load && // Anything loaded? - this.load.folders && // Was my parent a dead-end? - this.load.folders[name]) { // Did daddy remember me? + }, - // Start me closed if I was closed - new_gui_params.closed = this.load.folders[name].closed; + destroy: function() { - // Pass down the loaded data - new_gui_params.load = this.load.folders[name]; + if (this.autoPlace) { + auto_place_container.removeChild(this.domElement); + } - } + }, - var gui = new GUI(new_gui_params); - this.__folders[name] = gui; + /** + * @param name + * @returns {dat.gui.GUI} The new folder. + * @throws {Error} if this GUI already has a folder by the specified + * name + * @instance + */ + addFolder: function(name) { - var li = addRow(this, gui.domElement); - dom.addClass(li, 'folder'); - return gui; + // We have to prevent collisions on names in order to have a key + // by which to remember saved values + if (this.__folders[name] !== undefined) { + throw new Error('You already have a folder in this GUI by the' + + ' name "' + name + '"'); + } - }, + var new_gui_params = { + name: name, + parent: this + }; - open: function() { - this.closed = false; - }, + // We need to pass down the autoPlace trait so that we can + // attach event listeners to open/close folder actions to + // ensure that a scrollbar appears if the window is too short. + new_gui_params.autoPlace = this.autoPlace; - close: function() { - this.closed = true; - }, + // Do we have saved appearance data for this folder? - onResize: function() { + if (this.load && // Anything loaded? + this.load.folders && // Was my parent a dead-end? + this.load.folders[name]) { // Did daddy remember me? - var root = this.getRoot(); + // Start me closed if I was closed + new_gui_params.closed = this.load.folders[name].closed; - if (root.scrollable) { - - var top = dom.getOffset(root.__ul).top; - var h = 0; - - common.each(root.__ul.childNodes, function(node) { - if (! (root.autoPlace && node === root.__save_row)) - h += dom.getHeight(node); - }); - - if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) { - dom.addClass(root.domElement, GUI.CLASS_TOO_TALL); - root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px'; - } else { - dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL); - root.__ul.style.height = 'auto'; - } - - } - - if (root.__resize_handle) { - common.defer(function() { - root.__resize_handle.style.height = root.__ul.offsetHeight + 'px'; - }); - } - - if (root.__closeButton) { - root.__closeButton.style.width = root.width + 'px'; - } - - }, - - /** - * Mark objects for saving. The order of these objects cannot change as - * the GUI grows. When remembering new objects, append them to the end - * of the list. - * - * @param {Object...} objects - * @throws {Error} if not called on a top level GUI. - * @instance - */ - remember: function() { - - if (common.isUndefined(SAVE_DIALOGUE)) { - SAVE_DIALOGUE = new CenteredDiv(); - SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents; - } - - if (this.parent) { - throw new Error("You can only call remember on a top level GUI."); - } - - var _this = this; - - common.each(Array.prototype.slice.call(arguments), function(object) { - if (_this.__rememberedObjects.length == 0) { - addSaveMenu(_this); - } - if (_this.__rememberedObjects.indexOf(object) == -1) { - _this.__rememberedObjects.push(object); - } - }); - - if (this.autoPlace) { - // Set save row width - setWidth(this, this.width); - } - - }, - - /** - * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI. - * @instance - */ - getRoot: function() { - var gui = this; - while (gui.parent) { - gui = gui.parent; - } - return gui; - }, - - /** - * @returns {Object} a JSON object representing the current state of - * this GUI as well as its remembered properties. - * @instance - */ - getSaveObject: function() { - - var toReturn = this.load; - - toReturn.closed = this.closed; - - // Am I remembering any values? - if (this.__rememberedObjects.length > 0) { - - toReturn.preset = this.preset; - - if (!toReturn.remembered) { - toReturn.remembered = {}; - } - - toReturn.remembered[this.preset] = getCurrentPreset(this); - - } - - toReturn.folders = {}; - common.each(this.__folders, function(element, key) { - toReturn.folders[key] = element.getSaveObject(); - }); - - return toReturn; - - }, - - save: function() { - - if (!this.load.remembered) { - this.load.remembered = {}; - } - - this.load.remembered[this.preset] = getCurrentPreset(this); - markPresetModified(this, false); - this.saveToLocalStorageIfPossible(); - - }, - - saveAs: function(presetName) { - - if (!this.load.remembered) { - - // Retain default values upon first save - this.load.remembered = {}; - this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true); - - } - - this.load.remembered[presetName] = getCurrentPreset(this); - this.preset = presetName; - addPresetOption(this, presetName, true); - this.saveToLocalStorageIfPossible(); - - }, - - revert: function(gui) { - - common.each(this.__controllers, function(controller) { - // Make revert work on Default. - if (!this.getRoot().load.remembered) { - controller.setValue(controller.initialValue); - } else { - recallSavedValue(gui || this.getRoot(), controller); - } - }, this); - - common.each(this.__folders, function(folder) { - folder.revert(folder); - }); - - if (!gui) { - markPresetModified(this.getRoot(), false); - } - - - }, - - listen: function(controller) { - - var init = this.__listening.length == 0; - this.__listening.push(controller); - if (init) updateDisplays(this.__listening); + // Pass down the loaded data + new_gui_params.load = this.load.folders[name]; } + var gui = new GUI(new_gui_params); + this.__folders[name] = gui; + + var li = addRow(this, gui.domElement); + dom.addClass(li, 'folder'); + return gui; + + }, + + open: function() { + this.closed = false; + }, + + close: function() { + this.closed = true; + }, + + onResize: function() { + + var root = this.getRoot(); + + if (root.scrollable) { + + var top = dom.getOffset(root.__ul).top; + var h = 0; + + common.each(root.__ul.childNodes, function(node) { + if (!(root.autoPlace && node === root.__save_row)) + h += dom.getHeight(node); + }); + + if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) { + dom.addClass(root.domElement, GUI.CLASS_TOO_TALL); + root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px'; + } else { + dom.removeClass(root.domElement, GUI.CLASS_TOO_TALL); + root.__ul.style.height = 'auto'; + } + + } + + if (root.__resize_handle) { + common.defer(function() { + root.__resize_handle.style.height = root.__ul.offsetHeight + 'px'; + }); + } + + if (root.__closeButton) { + root.__closeButton.style.width = root.width + 'px'; + } + + }, + + /** + * Mark objects for saving. The order of these objects cannot change as + * the GUI grows. When remembering new objects, append them to the end + * of the list. + * + * @param {Object...} objects + * @throws {Error} if not called on a top level GUI. + * @instance + */ + remember: function() { + + if (common.isUndefined(SAVE_DIALOGUE)) { + SAVE_DIALOGUE = new CenteredDiv(); + SAVE_DIALOGUE.domElement.innerHTML = saveDialogueContents; + } + + if (this.parent) { + throw new Error("You can only call remember on a top level GUI."); + } + + var _this = this; + + common.each(Array.prototype.slice.call(arguments), function(object) { + if (_this.__rememberedObjects.length == 0) { + addSaveMenu(_this); + } + if (_this.__rememberedObjects.indexOf(object) == -1) { + _this.__rememberedObjects.push(object); + } + }); + + if (this.autoPlace) { + // Set save row width + setWidth(this, this.width); + } + + }, + + /** + * @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI. + * @instance + */ + getRoot: function() { + var gui = this; + while (gui.parent) { + gui = gui.parent; + } + return gui; + }, + + /** + * @returns {Object} a JSON object representing the current state of + * this GUI as well as its remembered properties. + * @instance + */ + getSaveObject: function() { + + var toReturn = this.load; + + toReturn.closed = this.closed; + + // Am I remembering any values? + if (this.__rememberedObjects.length > 0) { + + toReturn.preset = this.preset; + + if (!toReturn.remembered) { + toReturn.remembered = {}; + } + + toReturn.remembered[this.preset] = getCurrentPreset(this); + + } + + toReturn.folders = {}; + common.each(this.__folders, function(element, key) { + toReturn.folders[key] = element.getSaveObject(); + }); + + return toReturn; + + }, + + save: function() { + + if (!this.load.remembered) { + this.load.remembered = {}; + } + + this.load.remembered[this.preset] = getCurrentPreset(this); + markPresetModified(this, false); + this.saveToLocalStorageIfPossible(); + + }, + + saveAs: function(presetName) { + + if (!this.load.remembered) { + + // Retain default values upon first save + this.load.remembered = {}; + this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true); + + } + + this.load.remembered[presetName] = getCurrentPreset(this); + this.preset = presetName; + addPresetOption(this, presetName, true); + this.saveToLocalStorageIfPossible(); + + }, + + revert: function(gui) { + + common.each(this.__controllers, function(controller) { + // Make revert work on Default. + if (!this.getRoot().load.remembered) { + controller.setValue(controller.initialValue); + } else { + recallSavedValue(gui || this.getRoot(), controller); + } + }, this); + + common.each(this.__folders, function(folder) { + folder.revert(folder); + }); + + if (!gui) { + markPresetModified(this.getRoot(), false); + } + + + }, + + listen: function(controller) { + + var init = this.__listening.length == 0; + this.__listening.push(controller); + if (init) updateDisplays(this.__listening); + } + } + ); function add(gui, object, property, params) { @@ -810,7 +819,7 @@ define([ } else { - var factoryArgs = [object,property].concat(params.factoryArgs); + var factoryArgs = [object, property].concat(params.factoryArgs); controller = controllerFactory.apply(gui, factoryArgs); } @@ -876,13 +885,12 @@ define([ controller.remove(); return add( - gui, - controller.object, - controller.property, - { - before: controller.__li.nextElementSibling, - factoryArgs: [common.toArray(arguments)] - } + gui, + controller.object, + controller.property, { + before: controller.__li.nextElementSibling, + factoryArgs: [common.toArray(arguments)] + } ); } @@ -891,13 +899,12 @@ define([ controller.remove(); return add( - gui, - controller.object, - controller.property, - { - before: controller.__li.nextElementSibling, - factoryArgs: [options] - } + gui, + controller.object, + controller.property, { + before: controller.__li.nextElementSibling, + factoryArgs: [options] + } ); } @@ -924,8 +931,11 @@ define([ // All sliders should be accompanied by a box. if (controller instanceof NumberControllerSlider) { - var box = new NumberControllerBox(controller.object, controller.property, - { min: controller.__min, max: controller.__max, step: controller.__step }); + var box = new NumberControllerBox(controller.object, controller.property, { + min: controller.__min, + max: controller.__max, + step: controller.__step + }); common.each(['updateDisplay', 'onChange', 'onFinishChange'], function(method) { var pc = controller[method]; @@ -940,8 +950,7 @@ define([ dom.addClass(li, 'has-slider'); controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild); - } - else if (controller instanceof NumberControllerBox) { + } else if (controller instanceof NumberControllerBox) { var r = function(returned) { @@ -951,13 +960,12 @@ define([ // Well, then lets just replace this with a slider. controller.remove(); return add( - gui, - controller.object, - controller.property, - { - before: controller.__li.nextElementSibling, - factoryArgs: [controller.__min, controller.__max, controller.__step] - }); + gui, + controller.object, + controller.property, { + before: controller.__li.nextElementSibling, + factoryArgs: [controller.__min, controller.__max, controller.__step] + }); } @@ -968,8 +976,7 @@ define([ controller.min = common.compose(r, controller.min); controller.max = common.compose(r, controller.max); - } - else if (controller instanceof BooleanController) { + } else if (controller instanceof BooleanController) { dom.bind(li, 'click', function() { dom.fakeEvent(controller.__checkbox, 'click'); @@ -979,8 +986,7 @@ define([ e.stopPropagation(); // Prevents double-toggle }) - } - else if (controller instanceof FunctionController) { + } else if (controller instanceof FunctionController) { dom.bind(li, 'click', function() { dom.fakeEvent(controller.__button, 'click'); @@ -994,8 +1000,7 @@ define([ dom.removeClass(controller.__button, 'hover'); }); - } - else if (controller instanceof ColorController) { + } else if (controller instanceof ColorController) { dom.addClass(li, 'color'); controller.updateDisplay = common.compose(function(r) { @@ -1030,14 +1035,14 @@ define([ // Let me fetch a map of controllers for thcommon.isObject. var controller_map = - root.__rememberedObjectIndecesToControllers[matched_index]; + root.__rememberedObjectIndecesToControllers[matched_index]; // Ohp, I believe this is the first controller we've created for this // object. Lets make the map fresh. if (controller_map === undefined) { controller_map = {}; root.__rememberedObjectIndecesToControllers[matched_index] = - controller_map; + controller_map; } // Keep track of this controller @@ -1073,7 +1078,7 @@ define([ if (preset[matched_index] && // Did we remember this particular property? - preset[matched_index][controller.property] !== undefined) { + preset[matched_index][controller.property] !== undefined) { // We did remember something for this guy ... var value = preset[matched_index][controller.property]; @@ -1210,7 +1215,7 @@ define([ gui.revert(); }); -// div.appendChild(button2); + // div.appendChild(button2); } @@ -1225,7 +1230,7 @@ define([ height: '200px', cursor: 'ew-resize', position: 'absolute' -// border: '1px solid blue' + // border: '1px solid blue' }); @@ -1278,7 +1283,8 @@ define([ // set the width manually if we want it to bleed to the edge if (gui.__save_row && gui.autoPlace) { gui.__save_row.style.width = w + 'px'; - }if (gui.__closeButton) { + } + if (gui.__closeButton) { gui.__closeButton.style.width = w + 'px'; } } @@ -1294,7 +1300,7 @@ define([ // The controllers I've made for thcommon.isObject by property var controller_map = - gui.__rememberedObjectIndecesToControllers[index]; + gui.__rememberedObjectIndecesToControllers[index]; // Remember each value for each property common.each(controller_map, function(controller, property) { @@ -1330,7 +1336,7 @@ define([ function markPresetModified(gui, modified) { var opt = gui.__preset_select[gui.__preset_select.selectedIndex]; -// console.log('mark', modified, opt); + // console.log('mark', modified, opt); if (modified) { opt.innerHTML = opt.value + "*"; } else { @@ -1343,7 +1349,7 @@ define([ if (controllerArray.length != 0) { - requestAnimationFrame(function() { + raf(function() { updateDisplays(controllerArray); }); @@ -1356,5 +1362,4 @@ define([ } return GUI; - -}); +} diff --git a/src/dat/utils/common.js b/src/dat/utils/common.js index b5bcc34..86631d5 100644 --- a/src/dat/utils/common.js +++ b/src/dat/utils/common.js @@ -11,9 +11,10 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -define([ -], function() { - +module.exports = common(); + +function common() { + var ARR_EACH = Array.prototype.forEach; var ARR_SLICE = Array.prototype.slice; @@ -23,38 +24,38 @@ define([ * http://documentcloud.github.com/underscore/ */ - return { - + return { + BREAK: {}, - + extend: function(target) { - + this.each(ARR_SLICE.call(arguments, 1), function(obj) { - + for (var key in obj) - if (!this.isUndefined(obj[key])) + if (!this.isUndefined(obj[key])) target[key] = obj[key]; - + }, this); - + return target; - + }, - + defaults: function(target) { - + this.each(ARR_SLICE.call(arguments, 1), function(obj) { - + for (var key in obj) - if (this.isUndefined(target[key])) + if (this.isUndefined(target[key])) target[key] = obj[key]; - + }, this); - + return target; - + }, - + compose: function() { var toCall = ARR_SLICE.call(arguments); return function() { @@ -63,37 +64,37 @@ define([ args = [toCall[i].apply(this, args)]; } return args[0]; - } + }; }, - + each: function(obj, itr, scope) { if (!obj) return; - if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) { - + if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) { + obj.forEach(itr, scope); - + } else if (obj.length === obj.length + 0) { // Is number but not NaN - + for (var key = 0, l = obj.length; key < l; key++) - if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) + if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) return; - + } else { - for (var key in obj) + for (var key in obj) if (itr.call(scope, obj[key], key) === this.BREAK) return; - + } - + }, - + defer: function(fnc) { setTimeout(fnc, 0); }, - + toArray: function(obj) { if (obj.toArray) return obj.toArray(); return ARR_SLICE.call(obj); @@ -102,39 +103,38 @@ define([ isUndefined: function(obj) { return obj === undefined; }, - + isNull: function(obj) { return obj === null; }, - + isNaN: function(obj) { return obj !== obj; }, - + isArray: Array.isArray || function(obj) { return obj.constructor === Array; }, - + isObject: function(obj) { return obj === Object(obj); }, - + isNumber: function(obj) { return obj === obj+0; }, - + isString: function(obj) { return obj === obj+''; }, - + isBoolean: function(obj) { return obj === false || obj === true; }, - + isFunction: function(obj) { return Object.prototype.toString.call(obj) === '[object Function]'; } - + }; - -}); \ No newline at end of file +} diff --git a/src/dat/utils/css.js b/src/dat/utils/css.js index 4b8a926..3a4889a 100644 --- a/src/dat/utils/css.js +++ b/src/dat/utils/css.js @@ -10,9 +10,9 @@ * * http://www.apache.org/licenses/LICENSE-2.0 */ +module.exports = css(); -define([], -function() { +function css() { return { load: function (url, doc) { doc = doc || document; @@ -29,5 +29,5 @@ function() { injected.innerHTML = css; doc.getElementsByTagName('head')[0].appendChild(injected); } - } -}); + }; +} diff --git a/src/dat/utils/requestAnimationFrame.js b/src/dat/utils/requestAnimationFrame.js index 2954316..d11a77e 100644 --- a/src/dat/utils/requestAnimationFrame.js +++ b/src/dat/utils/requestAnimationFrame.js @@ -10,9 +10,9 @@ * * http://www.apache.org/licenses/LICENSE-2.0 */ +module.exports = raf(); -define([ -], function() { +function raf() { /** * requirejs version of Paul Irish's RequestAnimationFrame @@ -28,4 +28,4 @@ define([ window.setTimeout(callback, 1000 / 60); }; -}); \ No newline at end of file +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..66f3647 --- /dev/null +++ b/src/index.js @@ -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') +}; diff --git a/tests/index.html b/tests/index.html index 2246526..6fc8e30 100644 --- a/tests/index.html +++ b/tests/index.html @@ -1417,4 +1417,4 @@ console.log(c2.__checkbox.getAttribute('checked'));
      test markup, will be hidden
      - \ No newline at end of file + diff --git a/utils/build.js b/utils/build.js deleted file mode 100644 index 307e319..0000000 --- a/utils/build.js +++ /dev/null @@ -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": {} -}); diff --git a/utils/build_color.js b/utils/build_color.js deleted file mode 100644 index 7f035a7..0000000 --- a/utils/build_color.js +++ /dev/null @@ -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": {} -}); \ No newline at end of file diff --git a/utils/build_gui.js b/utils/build_gui.js deleted file mode 100644 index acca53e..0000000 --- a/utils/build_gui.js +++ /dev/null @@ -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": {} -}); \ No newline at end of file diff --git a/utils/builder.js b/utils/builder.js deleted file mode 100644 index 42adbe2..0000000 --- a/utils/builder.js +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/utils/closure.js b/utils/closure.js deleted file mode 100644 index 3287fb0..0000000 --- a/utils/closure.js +++ /dev/null @@ -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); -} \ No newline at end of file diff --git a/utils/license.txt b/utils/license.txt deleted file mode 100644 index dd7aa97..0000000 --- a/utils/license.txt +++ /dev/null @@ -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 - */