From b00f8f69f4c6acc5c48874d93ae39941909af5eb Mon Sep 17 00:00:00 2001 From: Tomas Korcak Date: Fri, 14 Aug 2015 15:24:30 +0200 Subject: [PATCH] Using common.js + webpack --- README.md | 38 +- build/dat.gui.js | 7407 +++++++++-------- build/dat.gui.min.js | 97 +- example.html | 2 +- index.js | 1 + package.json | 30 + src/dat/color/Color.js | 179 +- src/dat/color/interpret.js | 579 +- src/dat/color/math.js | 119 +- src/dat/color/toString.js | 30 +- src/dat/controllers/BooleanController.js | 78 +- src/dat/controllers/ColorController.js | 481 +- src/dat/controllers/Controller.js | 69 +- src/dat/controllers/FunctionController.js | 72 +- src/dat/controllers/NumberController.js | 118 +- src/dat/controllers/NumberControllerBox.js | 212 +- src/dat/controllers/NumberControllerSlider.js | 177 +- src/dat/controllers/OptionController.js | 93 +- src/dat/controllers/StringController.js | 106 +- src/dat/controllers/factory.js | 73 +- src/dat/dom/CenteredDiv.js | 79 +- src/dat/dom/dom.js | 360 +- src/dat/gui/GUI.js | 1436 ++-- src/dat/index.js | 27 + src/dat/utils/common.js | 215 +- src/dat/utils/css.js | 31 +- src/dat/utils/requestAnimationFrame.js | 29 +- tests/index.html | 3 +- utils/build.js | 19 - utils/build_color.js | 8 - utils/build_gui.js | 8 - utils/builder.js | 284 - utils/closure.js | 108 - utils/license.txt | 12 - webpack.config.js | 26 + webpack.config.min.js | 15 + 36 files changed, 6389 insertions(+), 6232 deletions(-) create mode 100644 index.js create mode 100644 package.json create mode 100644 src/dat/index.js delete mode 100644 utils/build.js delete mode 100644 utils/build_color.js delete mode 100644 utils/build_gui.js delete mode 100644 utils/builder.js delete mode 100644 utils/closure.js delete mode 100644 utils/license.txt create mode 100644 webpack.config.js create mode 100644 webpack.config.min.js diff --git a/README.md b/README.md index c384a56..125f3b5 100644 --- a/README.md +++ b/README.md @@ -10,32 +10,11 @@ The easiest way to use dat.GUI in your code is by using the built source at `bui In your `head` tag, include the following code: ``` - + ``` ---- -##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. - -In your `head` tag, include the following code: -``` - -``` - -Then, in `path/to/main.js`: -``` -require([ - 'path/to/gui/module/GUI' -], function(GUI) { - - // No namespace necessary - var gui = new GUI(); - -}); -``` - ----- ##Directory Contents * build: Concatenated source code. @@ -50,19 +29,20 @@ require([ In the terminal, enter the following: ``` -$ cd utils -$ node build_gui.js +$ npm run build ``` -This will create a namespaced, unminified build of dat.GUI at `build/dat.gui.js` - -_To export minified source using Closure Compiler, open `utils/build_gui.js` and set the `minify` parameter to `true`._ +This will create a namespaced, unminified build of dat.GUI at `build/dat.gui.main.js` ---- ##Change log -###0.5 +### 0.6.0 + * Using common.js + * Using webpack for build + +### 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). @@ -75,7 +55,7 @@ _To export minified source using Closure Compiler, open `utils/build_gui.js` and * Made Controller code completely agnostic of GUI. Controllers can easily be created independent of a GUI panel. -#0.4 +### 0.4 * Migrated from GitHub to Google Code. diff --git a/build/dat.gui.js b/build/dat.gui.js index b321b51..e9c986b 100644 --- a/build/dat.gui.js +++ b/build/dat.gui.js @@ -1,3673 +1,4394 @@ -/** - * 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 - */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define(factory); + else if(typeof exports === 'object') + exports["dat"] = factory(); + else + root["dat"] = factory(); +})(this, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = __webpack_require__(1); + + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + module.exports = { + color: { + Color: __webpack_require__(2), + math: __webpack_require__(6), + interpret: __webpack_require__(3) + }, + + controllers: { + Controller: __webpack_require__(7), + BooleanController: __webpack_require__(8), + OptionController: __webpack_require__(10), + StringController: __webpack_require__(11), + NumberController: __webpack_require__(12), + NumberControllerBox: __webpack_require__(13), + NumberControllerSlider: __webpack_require__(14), + FunctionController: __webpack_require__(20), + ColorController: __webpack_require__(21), + }, -/** @namespace */ -var dat = dat || {}; + dom: { + dom: __webpack_require__(9) + }, -/** @namespace */ -dat.gui = dat.gui || {}; + gui: { + GUI: __webpack_require__(22) + } + }; -/** @namespace */ -dat.utils = dat.utils || {}; +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { -/** @namespace */ -dat.controllers = dat.controllers || {}; + /** + * 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 + */ -/** @namespace */ -dat.dom = dat.dom || {}; + var interpret = __webpack_require__(3), + math = __webpack_require__(6), + toString = __webpack_require__(4), + common = __webpack_require__(5); -/** @namespace */ -dat.color = dat.color || {}; + var Color = function () { -dat.utils.css = (function () { - 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); - } - } -})(); + this.__state = interpret.apply(this, arguments); + if (this.__state === false) { + throw 'Failed to interpret color arguments'; + } -dat.utils.common = (function () { - - var ARR_EACH = Array.prototype.forEach; - var ARR_SLICE = Array.prototype.slice; + this.__state.a = this.__state.a || 1; + }; - /** - * 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/ - */ + Color.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a']; - return { - - BREAK: {}, - - extend: function(target) { - - this.each(ARR_SLICE.call(arguments, 1), function(obj) { - - for (var key in obj) - 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])) - 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) { + common.extend(Color.prototype, { - if (!obj) return; + toString: function () { + return toString(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 { + toOriginal: function () { + return this.__state.conversion.write(this); + } - 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); - }, + }); - 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]'; - } - - }; - -})(); + 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'); -dat.controllers.Controller = (function (common) { + Object.defineProperty(Color.prototype, 'a', { - /** - * @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) { + get: function () { + return this.__state.a; + }, - this.initialValue = object[property]; + set: function (v) { + this.__state.a = v; + } + }); - /** - * Those who extend this class will put their DOM elements in here. - * @type {DOMElement} - */ - this.domElement = document.createElement('div'); + Object.defineProperty(Color.prototype, 'hex', { - /** - * The object to manipulate - * @type {Object} - */ - this.object = object; + get: function () { - /** - * The name of the property to manipulate - * @type {String} - */ - this.property = property; + if (!this.__state.space !== 'HEX') { + this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b); + } - /** - * The function to be called on change. - * @type {Function} - * @ignore - */ - this.__onChange = undefined; + return this.__state.hex; - /** - * The function to be called on finishing change. - * @type {Function} - * @ignore - */ - this.__onFinishChange = undefined; + }, - }; + set: function (v) { - common.extend( + this.__state.space = 'HEX'; + this.__state.hex = v; - 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; - }, + function defineRGBComponent(target, component, componentHexIndex) { - /** - * 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; - }, + Object.defineProperty(target, component, { - /** - * 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; - }, + get: function () { - /** - * Gets the value of object[property] - * - * @returns {Object} The current value of object[property] - */ - getValue: function() { - return this.object[this.property]; - }, + if (this.__state.space === 'RGB') { + return this.__state[component]; + } - /** - * 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; - }, + recalculateRGB(this, component, componentHexIndex); - /** - * @returns {Boolean} true if the value has deviated from initialValue - */ - isModified: function() { - return this.initialValue !== this.getValue() - } + return this.__state[component]; - } + }, - ); + set: function (v) { - return Controller; + if (this.__state.space !== 'RGB') { + recalculateRGB(this, component, componentHexIndex); + this.__state.space = 'RGB'; + } + this.__state[component] = v; -})(dat.utils.common); + } + }); -dat.dom.dom = (function (common) { - - 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 ); - } - - }; - - 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(Math.abs(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; - } - } - - 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}"); + function defineHSVComponent(target, component) { + Object.defineProperty(target, component, { -dat.controllers.FunctionController = (function (Controller, dom, common) { + get: function () { - /** - * @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) { + if (this.__state.space === 'HSV') + return this.__state[component]; - FunctionController.superclass.call(this, object, property); + recalculateHSV(this); - var _this = this; + return this.__state[component]; - 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'); + set: function (v) { - this.domElement.appendChild(this.__button); + if (this.__state.space !== 'HSV') { + recalculateHSV(this); + this.__state.space = 'HSV'; + } + this.__state[component] = v; - }; + } - 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()); - } - } - } + function recalculateRGB(color, component, componentHexIndex) { - ); + if (color.__state.space === 'HEX') { - return FunctionController; + color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex); -})(dat.controllers.Controller, -dat.dom.dom, -dat.utils.common); + } else if (color.__state.space === 'HSV') { + common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v)); -dat.controllers.BooleanController = (function (Controller, dom, common) { + } else { - /** - * @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) { + throw 'Corrupted color state'; - BooleanController.superclass.call(this, object, property); + } - var _this = this; - this.__prev = this.getValue(); + } - this.__checkbox = document.createElement('input'); - this.__checkbox.setAttribute('type', 'checkbox'); + function recalculateHSV(color) { + var result = math.rgb_to_hsv(color.r, color.g, color.b); - dom.bind(this.__checkbox, 'change', onChange, false); + common.extend(color.__state, + { + s: result.s, + v: result.v + } + ); - this.domElement.appendChild(this.__checkbox); + if (!common.isNaN(result.h)) { + color.__state.h = result.h; + } else if (common.isUndefined(color.__state.h)) { + color.__state.h = 0; + } - // Match original value - this.updateDisplay(); + } - function onChange() { - _this.setValue(!_this.__prev); - } + module.exports = Color; - }; - BooleanController.superclass = Controller; +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { - common.extend( + /** + * 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 + */ - BooleanController.prototype, - Controller.prototype, + var toString = __webpack_require__(4), + common = __webpack_require__(5); - { + var result, toReturn; - 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; - }, + var interpret = function() { - updateDisplay: function() { - - if (this.getValue() === true) { - this.__checkbox.setAttribute('checked', 'checked'); - this.__checkbox.checked = true; - } else { - this.__checkbox.checked = false; - } + toReturn = false; - return BooleanController.superclass.prototype.updateDisplay.call(this); + var original = arguments.length > 1 ? 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); - return BooleanController; + if (toReturn === false && result !== false) { + toReturn = result; + result.conversionName = conversionName; + result.conversion = conversion; + return common.BREAK; -})(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) { - - var result, toReturn; - - var interpret = function() { - - toReturn = false; - - var original = arguments.length > 1 ? 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 = [ - - // Strings - { - - 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 - - } - - } - - }, - - // Numbers - { - - litmus: common.isNumber, - - conversions: { - - HEX: { - read: function(original) { - return { - space: 'HEX', - hex: original, - conversionName: 'HEX' - } - }, - - write: function(color) { - return color.hex; - } - } - - } - - }, - - // Arrays - { - - 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]; - } - - } - - } - - }, - - // Objects - { - - 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; - - -})(dat.color.toString, -dat.utils.common); - - -dat.GUI = dat.gui.GUI = (function (css, saveDialogueContents, styleSheet, controllerFactory, Controller, BooleanController, FunctionController, NumberControllerBox, NumberControllerSlider, OptionController, ColorController, requestAnimationFrame, CenteredDiv, dom, common) { - - css.inject(styleSheet); - - /** Outer-most className for GUI's */ - var CSS_NAMESPACE = 'dg'; - - var HIDE_KEY_CODE = 72; - - /** The only value shared between the JS and SCSS. Use caution. */ - 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; - - /** Have we yet to create an autoPlace GUI? */ - var auto_place_virgin = true; - - /** Fixed position div that auto place GUI's go inside */ - var auto_place_container; - - /** Are we hiding the GUI's ? */ - var hide = false; - - /** GUI's which should be hidden */ - var hideable_guis = []; - - /** - * A lightweight controller library for JavaScript. It allows you to easily - * manipulate variables and fire functions on the fly. - * @class - * - * @member dat.gui - * - * @param {Object} [params] - * @param {String} [params.name] The name of this GUI. - * @param {Object} [params.load] JSON object representing the saved state of - * this GUI. - * @param {Boolean} [params.auto=true] - * @param {dat.gui.GUI} [params.parent] The GUI I'm nested in. - * @param {Boolean} [params.closed] If true, starts closed - */ - var GUI = function(params) { - - var _this = this; - - /** - * Outermost DOM Element - * @type DOMElement - */ - this.domElement = document.createElement('div'); - this.__ul = document.createElement('ul'); - this.domElement.appendChild(this.__ul); - - dom.addClass(this.domElement, CSS_NAMESPACE); - - /** - * Nested GUI's by name - * @ignore - */ - this.__folders = {}; - - this.__controllers = []; - - /** - * List of objects I'm remembering for save, only used in top level GUI - * @ignore - */ - this.__rememberedObjects = []; - - /** - * Maps the index of remembered objects to a map of controllers, only used - * in top level GUI. - * - * @private - * @ignore - * - * @example - * [ - * { - * propertyName: Controller, - * anotherPropertyName: Controller - * }, - * { - * propertyName: Controller - * } - * ] - */ - this.__rememberedObjectIndecesToControllers = []; - - this.__listening = []; - - params = params || {}; - - // Default parameters - 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)) { - - // Explicit preset - if (params.preset) params.load.preset = params.preset; - - } else { - - params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME }; - - } - - if (common.isUndefined(params.parent) && params.hideable) { - hideable_guis.push(this); - } - - // Only root level GUI's are resizable. - params.resizable = common.isUndefined(params.parent) && params.resizable; - - - if (params.autoPlace && common.isUndefined(params.scrollable)) { - 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'; - - var saveToLocalStorage; - - Object.defineProperties(this, - - /** @lends dat.gui.GUI.prototype */ - { - - /** - * 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; - } - }, - - 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); - } - } - - } - - }); - - // Are we a root level GUI? - if (common.isUndefined(params.parent)) { - - params.closed = false; - - dom.addClass(this.domElement, GUI.CLASS_MAIN); - dom.makeSelectable(this.domElement, false); - - // Are we supposed to be loading locally? - 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; - - - }); - - - // Oh, you're a nested GUI! - } 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; - } - - // Put it in the dom for you. - auto_place_container.appendChild(this.domElement); - - // Apply the auto styles - dom.addClass(this.domElement, GUI.CLASS_AUTO_PLACE); - - } - - - // Make it not elastic. - 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())); - } - } - - // expose this method publicly - this.saveToLocalStorageIfPossible = saveToLocalStorage; - - var root = _this.getRoot(); - function resetWidth() { - var root = _this.getRoot(); - root.width += 1; - common.defer(function() { - root.width -= 1; }); + + return common.BREAK; + + } + + }); + + return toReturn; + + }; + + var INTERPRETATIONS = [ + + // Strings + { + + 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 + + } + + } + + }, + + // Numbers + { + + litmus: common.isNumber, + + conversions: { + + HEX: { + read: function(original) { + return { + space: 'HEX', + hex: original, + conversionName: 'HEX' + } + }, + + write: function(color) { + return color.hex; + } + } + + } + + }, + + // Arrays + { + + 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]; + } + + } + + } + + }, + + // Objects + { + + 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 + } + } + + } + + } + + } + + + ]; + + module.exports = interpret; + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(5); + + module.exports = 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 + ')'; + } + }; + +/***/ }, +/* 5 */ +/***/ function(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 ARR_EACH = Array.prototype.forEach; + var ARR_SLICE = Array.prototype.slice; + + /** + * 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 Common = { + + BREAK: {}, + + extend: function (target) { + + this.each(ARR_SLICE.call(arguments, 1), function (obj) { + + for (var key in obj) + 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])) + 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; + + } 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); + }, + + 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]'; + } + + }; + + module.exports = Common; + +/***/ }, +/* 6 */ +/***/ function(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 tmpComponent; + + var ColorMath = { + + 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)); + } + } + + module.exports = ColorMath; + + +/***/ }, +/* 7 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(5); + + /** + * @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) { + + 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() + } + } + ); + + module.exports = Controller; + +/***/ }, +/* 8 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(7), + dom = __webpack_require__(9), + common = __webpack_require__(5); + + /** + * @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); + + } + + + } + + ); + + module.exports = BooleanController; + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(5); + + 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; + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(7), + dom = __webpack_require__(9), + common = __webpack_require__(5); + + /** + * @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); + } + + } + + ); + + module.exports = OptionController; + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(7), + dom = __webpack_require__(9), + common = __webpack_require__(5); + + /** + * @class Provides a text input to alter the string property of an object. + * + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * + * @member dat.controllers + */ + var StringController = function(object, property) { + + StringController.superclass.call(this, object, property); + + 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); + } + + } + + ); + + module.exports = StringController; + + +/***/ }, +/* 12 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(7), + common = __webpack_require__(5); + + + /** + * @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(Math.abs(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; + } + } + + module.exports = NumberController; + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(7), + NumberController = __webpack_require__(12), + dom = __webpack_require__(9), + common = __webpack_require__(5); + + /** + * @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; + } + + module.exports = NumberControllerBox; + + + + +/***/ }, +/* 14 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * 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 = __webpack_require__(12), + dom = __webpack_require__(9), + css = __webpack_require__(15), + common = __webpack_require__(5), + styleSheet = __webpack_require__(16); + + /** + * @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)); + } + + module.exports = NumberControllerSlider; + +/***/ }, +/* 15 */ +/***/ function(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 = { + 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); + } + }; + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + // style-loader: Adds some css to the DOM by adding a