From 3d57fba4ae63fe996a3d10bf5e3e32c516933526 Mon Sep 17 00:00:00 2001 From: Jules Date: Sat, 23 May 2015 13:31:55 -0400 Subject: displacement proj --- .gitignore | 3 + cam.html | 207 ++++++++ canvasquery.js | 1599 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dat.gui.min.js | 82 +++ index.html | 197 +++++++ 5 files changed, 2088 insertions(+) create mode 100644 .gitignore create mode 100644 cam.html create mode 100644 canvasquery.js create mode 100644 dat.gui.min.js create mode 100644 index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91269fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.webm +*.png +*.jpg diff --git a/cam.html b/cam.html new file mode 100644 index 0000000..614cd51 --- /dev/null +++ b/cam.html @@ -0,0 +1,207 @@ + + + + + + +

+ +
+
+ + + + + + + + + + diff --git a/canvasquery.js b/canvasquery.js new file mode 100644 index 0000000..70257ea --- /dev/null +++ b/canvasquery.js @@ -0,0 +1,1599 @@ +/* + Canvas Query 0.8.1 + http://canvasquery.org + (c) 2012-2013 http://rezoner.net + Canvas Query may be freely distributed under the MIT license. +*/ + +(function(window, undefined) { + + var MOBILE = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); + + + window.requestAnimationFrame = (function() { + return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || + function(callback) { + window.setTimeout(callback, 1000 / 60); + }; + })(); + + + var $ = function(selector) { + if(arguments.length === 0) { + var canvas = $.createCanvas(window.innerWidth, window.innerHeight); + window.addEventListener("resize", function() { + // canvas.width = window.innerWidth; + // canvas.height = window.innerHeight; + }); + } else if(typeof selector === "string") { + var canvas = document.querySelector(selector); + } else if(typeof selector === "number") { + var canvas = $.createCanvas(arguments[0], arguments[1]); + } else if(selector instanceof Image || selector instanceof HTMLImageElement) { + var canvas = $.createCanvas(selector); + } else if(selector instanceof $.Wrapper) { + return selector; + } else { + var canvas = selector; + } + + return new $.Wrapper(canvas); + } + + $.extend = function() { + for(var i = 1; i < arguments.length; i++) { + for(var j in arguments[i]) { + arguments[0][j] = arguments[i][j]; + } + } + + return arguments[0]; + } + + $.augment = function() { + for(var i = 1; i < arguments.length; i++) { + _.extend(arguments[0], arguments[i]); + arguments[i](arguments[0]); + } + } + + $.extend($, { + + keycodes: { + 37: "left", + 38: "up", + 39: "right", + 40: "down", + 45: "insert", + 46: "delete", + 8: "backspace", + 9: "tab", + 13: "enter", + 16: "shift", + 17: "ctrl", + 18: "alt", + 19: "pause", + 20: "capslock", + 27: "escape", + 32: "space", + 33: "pageup", + 34: "pagedown", + 35: "end", + 112: "f1", + 113: "f2", + 114: "f3", + 115: "f4", + 116: "f5", + 117: "f6", + 118: "f7", + 119: "f8", + 120: "f9", + 121: "f10", + 122: "f11", + 123: "f12", + 144: "numlock", + 145: "scrolllock", + 186: "semicolon", + 187: "equal", + 188: "comma", + 189: "dash", + 190: "period", + 191: "slash", + 192: "graveaccent", + 219: "openbracket", + 220: "backslash", + 221: "closebraket", + 222: "singlequote" + }, + + cleanArray: function(array, property) { + + var lastArgument = arguments[arguments.length - 1]; + var isLastArgumentFunction = typeof lastArgument === "function"; + + for(var i = 0, len = array.length; i < len; i++) { + if(array[i] === null || (property && array[i][property])) { + if(isLastArgumentFunction) { + lastArgument(array[i]); + } + array.splice(i--, 1); + len--; + } + } + }, + + specialBlendFunctions: ["color", "value", "hue", "saturation"], + + blendFunctions: { + normal: function(a, b) { + return b; + }, + + overlay: function(a, b) { + a /= 255; + b /= 255; + var result = 0; + + if(a < 0.5) result = 2 * a * b; + else result = 1 - 2 * (1 - a) * (1 - b); + + return Math.min(255, Math.max(0, result * 255 | 0)); + }, + + hardLight: function(a, b) { + return $.blendFunctions.overlay(b, a); + }, + + softLight: function(a, b) { + a /= 255; + b /= 255; + + var v = (1 - 2 * b) * (a * a) + 2 * b * a; + return $.limitValue(v * 255, 0, 255); + }, + + dodge: function(a, b) { + return Math.min(256 * a / (255 - b + 1), 255); + }, + + burn: function(a, b) { + return 255 - Math.min(256 * (255 - a) / (b + 1), 255); + }, + + multiply: function(a, b) { + return b * a / 255; + }, + + divide: function(a, b) { + return Math.min(256 * a / (b + 1), 255); + }, + + screen: function(a, b) { + return 255 - (255 - b) * (255 - a) / 255; + }, + + grainExtract: function(a, b) { + return $.limitValue(a - b + 128, 0, 255); + }, + + grainMerge: function(a, b) { + return $.limitValue(a + b - 128, 0, 255); + }, + + difference: function(a, b) { + return Math.abs(a - b); + }, + + addition: function(a, b) { + return Math.min(a + b, 255); + }, + + substract: function(a, b) { + return Math.max(a - b, 0); + }, + + darkenOnly: function(a, b) { + return Math.min(a, b); + }, + + lightenOnly: function(a, b) { + return Math.max(a, b); + }, + + color: function(a, b) { + var aHSL = $.rgbToHsl(a); + var bHSL = $.rgbToHsl(b); + + return $.hslToRgb(bHSL[0], bHSL[1], aHSL[2]); + }, + + hue: function(a, b) { + var aHSV = $.rgbToHsv(a); + var bHSV = $.rgbToHsv(b); + + if(!bHSV[1]) return $.hsvToRgb(aHSV[0], aHSV[1], aHSV[2]); + else return $.hsvToRgb(bHSV[0], aHSV[1], aHSV[2]); + }, + + value: function(a, b) { + var aHSV = $.rgbToHsv(a); + var bHSV = $.rgbToHsv(b); + + return $.hsvToRgb(aHSV[0], aHSV[1], bHSV[2]); + }, + + saturation: function(a, b) { + var aHSV = $.rgbToHsv(a); + var bHSV = $.rgbToHsv(b); + + return $.hsvToRgb(aHSV[0], bHSV[1], aHSV[2]); + } + }, + + blend: function(below, above, mode, mix) { + if(typeof mix === "undefined") mix = 1; + + var below = $(below); + var above = $(above); + + var belowCtx = below.context; + var aboveCtx = above.context; + + var belowData = belowCtx.getImageData(0, 0, below.canvas.width, below.canvas.height); + var aboveData = aboveCtx.getImageData(0, 0, above.canvas.width, above.canvas.height); + + var belowPixels = belowData.data; + var abovePixels = aboveData.data; + + var imageData = this.createImageData(below.canvas.width, below.canvas.height); + var pixels = imageData.data; + + var blendingFunction = $.blendFunctions[mode]; + + if($.specialBlendFunctions.indexOf(mode) !== -1) { + for(var i = 0, len = belowPixels.length; i < len; i += 4) { + var rgb = blendingFunction([belowPixels[i + 0], belowPixels[i + 1], belowPixels[i + 2]], [abovePixels[i + 0], abovePixels[i + 1], abovePixels[i + 2]]); + + pixels[i + 0] = belowPixels[i + 0] + (rgb[0] - belowPixels[i + 0]) * mix; + pixels[i + 1] = belowPixels[i + 1] + (rgb[1] - belowPixels[i + 1]) * mix; + pixels[i + 2] = belowPixels[i + 2] + (rgb[2] - belowPixels[i + 2]) * mix; + + pixels[i + 3] = belowPixels[i + 3]; + } + } else { + + for(var i = 0, len = belowPixels.length; i < len; i += 4) { + var r = blendingFunction(belowPixels[i + 0], abovePixels[i + 0]); + var g = blendingFunction(belowPixels[i + 1], abovePixels[i + 1]); + var b = blendingFunction(belowPixels[i + 2], abovePixels[i + 2]); + + pixels[i + 0] = belowPixels[i + 0] + (r - belowPixels[i + 0]) * mix; + pixels[i + 1] = belowPixels[i + 1] + (g - belowPixels[i + 1]) * mix; + pixels[i + 2] = belowPixels[i + 2] + (b - belowPixels[i + 2]) * mix; + + pixels[i + 3] = belowPixels[i + 3]; + } + } + + below.context.putImageData(imageData, 0, 0); + + return below; + }, + + wrapValue: function(value, min, max) { + var d = Math.abs(max - min); + return min + (value - min) % d; + }, + + limitValue: function(value, min, max) { + return value < min ? min : value > max ? max : value; + }, + + mix: function(a, b, ammount) { + return a + (b - a) * ammount; + }, + + hexToRgb: function(hex) { + return ['0x' + hex[1] + hex[2] | 0, '0x' + hex[3] + hex[4] | 0, '0x' + hex[5] + hex[6] | 0]; + }, + + rgbToHex: function(r, g, b) { + return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1, 7); + }, + + /* author: http://mjijackson.com/ */ + + rgbToHsl: function(r, g, b) { + + if(r instanceof Array) { + b = r[2]; + g = r[1]; + r = r[0]; + } + + r /= 255, g /= 255, b /= 255; + var max = Math.max(r, g, b), + min = Math.min(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min) { + h = s = 0; // achromatic + } else { + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch(max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return [h, s, l]; + }, + + /* author: http://mjijackson.com/ */ + + hslToRgb: function(h, s, l) { + var r, g, b; + + if(s == 0) { + r = g = b = l; // achromatic + } else { + function hue2rgb(p, q, t) { + if(t < 0) t += 1; + if(t > 1) t -= 1; + if(t < 1 / 6) return p + (q - p) * 6 * t; + if(t < 1 / 2) return q; + if(t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hue2rgb(p, q, h + 1 / 3); + g = hue2rgb(p, q, h); + b = hue2rgb(p, q, h - 1 / 3); + } + + return [r * 255 | 0, g * 255 | 0, b * 255 | 0]; + }, + + rgbToHsv: function(r, g, b) { + if(r instanceof Array) { + b = r[2]; + g = r[1]; + r = r[0]; + } + + r = r / 255, g = g / 255, b = b / 255; + var max = Math.max(r, g, b), + min = Math.min(r, g, b); + var h, s, v = max; + + var d = max - min; + s = max == 0 ? 0 : d / max; + + if(max == min) { + h = 0; // achromatic + } else { + switch(max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + return [h, s, v]; + }, + + hsvToRgb: function(h, s, v) { + var r, g, b; + + var i = Math.floor(h * 6); + var f = h * 6 - i; + var p = v * (1 - s); + var q = v * (1 - f * s); + var t = v * (1 - (1 - f) * s); + + switch(i % 6) { + case 0: + r = v, g = t, b = p; + break; + case 1: + r = q, g = v, b = p; + break; + case 2: + r = p, g = v, b = t; + break; + case 3: + r = p, g = q, b = v; + break; + case 4: + r = t, g = p, b = v; + break; + case 5: + r = v, g = p, b = q; + break; + } + + return [r * 255, g * 255, b * 255]; + }, + + color: function() { + var result = new $.Color(); + result.parse(arguments); + return result; + }, + + createCanvas: function(width, height) { + var result = document.createElement("canvas"); + + if(arguments[0] instanceof Image || arguments[0] instanceof HTMLImageElement) { + var image = arguments[0]; + result.width = image.width; + result.height = image.height; + result.getContext("2d").drawImage(image, 0, 0); + } else { + result.width = width; + result.height = height; + } + + return result; + }, + + createImageData: function(width, height) { + return document.createElement("Canvas").getContext("2d").createImageData(width, height); + }, + + + /* https://gist.github.com/3781251 */ + + mousePosition: function(event) { + var totalOffsetX = 0, + totalOffsetY = 0, + coordX = 0, + coordY = 0, + currentElement = event.target || event.srcElement, + mouseX = 0, + mouseY = 0; + + // Traversing the parents to get the total offset + do { + totalOffsetX += currentElement.offsetLeft; + totalOffsetY += currentElement.offsetTop; + } + while ((currentElement = currentElement.offsetParent)); + // Set the event to first touch if using touch-input + if(event.changedTouches && event.changedTouches[0] !== undefined) { + event = event.changedTouches[0]; + } + // Use pageX to get the mouse coordinates + if(event.pageX || event.pageY) { + mouseX = event.pageX; + mouseY = event.pageY; + } + // IE8 and below doesn't support event.pageX + else if(event.clientX || event.clientY) { + mouseX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + mouseY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + // Subtract the offset from the mouse coordinates + coordX = mouseX - totalOffsetX; + coordY = mouseY - totalOffsetY; + + return { + x: coordX, + y: coordY + }; + } + }); + + $.Wrapper = function(canvas) { + this.context = canvas.getContext("2d"); + this.canvas = canvas; + } + + $.Wrapper.prototype = { + appendTo: function(selector) { + if(typeof selector === "object") { + var element = selector; + } else { + var element = document.querySelector(selector); + } + + element.appendChild(this.canvas); + + return this; + }, + + blendOn: function(what, mode, mix) { + $.blend(what, this, mode, mix); + + return this; + }, + + blend: function(what, mode, mix) { + if(typeof what === "string") { + var color = what; + what = $($.createCanvas(this.canvas.width, this.canvas.height)); + what.fillStyle(color).fillRect(0, 0, this.canvas.width, this.canvas.height); + } + + $.blend(this, what, mode, mix); + + return this; + }, + + circle: function(x, y, r) { + this.context.arc(x, y, r, 0, Math.PI * 2); + return this; + }, + + crop: function(x, y, w, h) { + + var canvas = $.createCanvas(w, h); + var context = canvas.getContext("2d"); + + context.drawImage(this.canvas, x, y, w, h, 0, 0, w, h); + this.canvas.width = w; + this.canvas.height = h; + this.clear(); + this.context.drawImage(canvas, 0, 0); + + return this; + }, + + set: function(properties) { + $.extend(this.context, properties); + }, + + resize: function(width, height) { + var w = width, + h = height; + if(height === null) { + if(this.canvas.width > width) { + h = this.canvas.height * (width / this.canvas.width) | 0; + w = width; + } else { + w = this.canvas.width; + h = this.canvas.height; + } + } else if(width === null) { + if(this.canvas.width > width) { + w = this.canvas.width * (height / this.canvas.height) | 0; + h = height; + } else { + w = this.canvas.width; + h = this.canvas.height; + } + } + + var $resized = $(w, h).drawImage(this.canvas, 0, 0, this.canvas.width, this.canvas.height, 0, 0, w, h); + this.canvas = $resized.canvas; + this.context = $resized.context; + + return this; + }, + + trim: function(color) { + var transparent; + + if(color) { + color = $.color(color).toArray(); + transparent = !color[3]; + } else transparent = true; + + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + var bound = [this.canvas.width, this.canvas.height, 0, 0]; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + if(transparent) { + if(!sourcePixels[i + 3]) continue; + } else if(sourcePixels[i + 0] === color[0] && sourcePixels[i + 1] === color[1] && sourcePixels[i + 2] === color[2]) continue; + var x = (i / 4 | 0) % this.canvas.width | 0; + var y = (i / 4 | 0) / this.canvas.width | 0; + + if(x < bound[0]) bound[0] = x; + if(x > bound[2]) bound[2] = x; + + if(y < bound[1]) bound[1] = y; + if(y > bound[3]) bound[3] = y; + } + + if(bound[2] === 0 || bound[3] === 0) { + + } else this.crop(bound[0], bound[1], bound[2] - bound[0] + 1, bound[3] - bound[1] + 1); + + return this; + }, + + resizePixel: function(pixelSize) { + + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + var canvas = document.createElement("canvas"); + var context = canvas.context = canvas.getContext("2d"); + + canvas.width = this.canvas.width * pixelSize | 0; + canvas.height = this.canvas.height * pixelSize | 0; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + if(!sourcePixels[i + 3]) continue; + context.fillStyle = $.rgbToHex(sourcePixels[i + 0], sourcePixels[i + 1], sourcePixels[i + 2]); + + var x = (i / 4) % this.canvas.width; + var y = (i / 4) / this.canvas.width | 0; + + context.fillRect(x * pixelSize, y * pixelSize, pixelSize, pixelSize); + } + + this.canvas.width = canvas.width; + this.canvas.height = canvas.height; + this.clear().drawImage(canvas, 0, 0); + + return this; + + /* this very clever method is working only under Chrome */ + + var x = 0, + y = 0; + + var canvas = document.createElement("canvas"); + var context = canvas.context = canvas.getContext("2d"); + + canvas.width = this.canvas.width * pixelSize | 0; + canvas.height = this.canvas.height * pixelSize | 0; + + while(x < this.canvas.width) { + y = 0; + while(y < this.canvas.height) { + context.drawImage(this.canvas, x, y, 1, 1, x * pixelSize, y * pixelSize, pixelSize, pixelSize); + y++; + } + x++; + } + + this.canvas = canvas; + this.context = context; + + return this; + }, + + + matchPalette: function(palette) { + var imgData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + + var rgbPalette = []; + for(var i = 0; i < palette.length; i++) { + rgbPalette.push($.color(palette[i])); + } + + + for(var i = 0; i < imgData.data.length; i += 4) { + var difList = []; + for(var j = 0; j < rgbPalette.length; j++) { + var rgbVal = rgbPalette[j]; + var rDif = Math.abs(imgData.data[i] - rgbVal[0]), + gDif = Math.abs(imgData.data[i + 1] - rgbVal[1]), + bDif = Math.abs(imgData.data[i + 2] - rgbVal[2]); + difList.push(rDif + gDif + bDif); + } + + var closestMatch = 0; + for(var j = 0; j < palette.length; j++) { + if(difList[j] < difList[closestMatch]) { + closestMatch = j; + } + } + + var paletteRgb = cq.hexToRgb(palette[closestMatch]); + imgData.data[i] = paletteRgb[0]; + imgData.data[i + 1] = paletteRgb[1]; + imgData.data[i + 2] = paletteRgb[2]; + } + + this.context.putImageData(imgData, 0, 0); + + return this; + }, + + getPalette: function() { + var palette = []; + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + if(sourcePixels[i + 3]) { + var hex = $.rgbToHex(sourcePixels[i + 0], sourcePixels[i + 1], sourcePixels[i + 2]); + if(palette.indexOf(hex) === -1) palette.push(hex); + } + } + + return palette; + }, + + pixelize: function(size) { + if(!size) return this; + size = size || 4; + + var mozImageSmoothingEnabled = this.context.mozImageSmoothingEnabled; + var webkitImageSmoothingEnabled = this.context.webkitImageSmoothingEnabled; + + this.context.mozImageSmoothingEnabled = false; + this.context.webkitImageSmoothingEnabled = false; + + var scale = (this.canvas.width / size) / this.canvas.width; + + var temp = cq(this.canvas.width, this.canvas.height); + + temp.drawImage(this.canvas, 0, 0, this.canvas.width, this.canvas.height, 0, 0, this.canvas.width * scale | 0, this.canvas.height * scale | 0); + this.clear().drawImage(temp.canvas, 0, 0, this.canvas.width * scale | 0, this.canvas.height * scale | 0, 0, 0, this.canvas.width, this.canvas.height); + + this.context.mozImageSmoothingEnabled = mozImageSmoothingEnabled; + this.context.webkitImageSmoothingEnabled = webkitImageSmoothingEnabled; + + return this; + }, + + colorToMask: function(color, inverted) { + color = $.color(color).toArray(); + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + var mask = []; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + if(sourcePixels[i + 0] == color[0] && sourcePixels[i + 1] == color[1] && sourcePixels[i + 2] == color[2]) mask.push(inverted || false); + else mask.push(!inverted); + } + + return mask; + }, + + grayscaleToMask: function(color) { + color = $.color(color).toArray(); + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + var mask = []; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + mask.push((sourcePixels[i + 0] + sourcePixels[i + 1] + sourcePixels[i + 2]) / 3 | 0); + } + + return mask; + }, + + grayscaleToAlpha: function() { + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + var mask = []; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + sourcePixels[i + 3] = (sourcePixels[i + 0] + sourcePixels[i + 1] + sourcePixels[i + 2]) / 3 | 0; + + sourcePixels[i + 0] = sourcePixels[i + 1] = sourcePixels[i + 2] = 255; + } + + this.context.putImageData(sourceData, 0, 0); + + return this; + }, + + applyMask: function(mask) { + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + var mode = typeof mask[0] === "boolean" ? "bool" : "byte"; + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + var value = mask[i / 4]; + + if(mode === "bool") sourcePixels[i + 3] = 255 * value | 0; + else { + sourcePixels[i + 3] = value | 0; + } + } + + + this.context.putImageData(sourceData, 0, 0); + return this; + }, + + fillMask: function(mask) { + + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var sourcePixels = sourceData.data; + + var maskType = typeof mask[0] === "boolean" ? "bool" : "byte"; + var colorMode = arguments.length === 2 ? "normal" : "gradient"; + + var color = $.color(arguments[1]); + if(colorMode === "gradient") colorB = $.color(arguments[2]); + + for(var i = 0, len = sourcePixels.length; i < len; i += 4) { + var value = mask[i / 4]; + + if(maskType === "byte") value /= 255; + + if(colorMode === "normal") { + if(value) { + sourcePixels[i + 0] = color[0] | 0; + sourcePixels[i + 1] = color[1] | 0; + sourcePixels[i + 2] = color[2] | 0; + sourcePixels[i + 3] = value * 255 | 0; + } + } else { + sourcePixels[i + 0] = color[0] + (colorB[0] - color[0]) * value | 0; + sourcePixels[i + 1] = color[1] + (colorB[1] - color[1]) * value | 0; + sourcePixels[i + 2] = color[2] + (colorB[2] - color[2]) * value | 0; + sourcePixels[i + 3] = 255; + } + } + + this.context.putImageData(sourceData, 0, 0); + return this; + }, + + clear: function(color) { + if(color) { + this.context.fillStyle = color; + this.context.fillRect(0, 0, this.canvas.width, this.canvas.height); + } else { + this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); + } + + return this; + }, + + clone: function() { + var result = $.createCanvas(this.canvas.width, this.canvas.height); + result.getContext("2d").drawImage(this.canvas, 0, 0); + return $(result); + }, + + fillStyle: function(fillStyle) { + this.context.fillStyle = fillStyle; + return this; + }, + + strokeStyle: function(strokeStyle) { + this.context.strokeStyle = strokeStyle; + return this; + }, + + gradientText: function(text, x, y, maxWidth, gradient) { + + var words = text.split(" "); + + var h = this.font().match(/\d+/g)[0] * 2; + + var ox = 0; + var oy = 0; + + if(maxWidth) { + var line = 0; + var lines = [""]; + + for(var i = 0; i < words.length; i++) { + var word = words[i] + " "; + var wordWidth = this.context.measureText(word).width; + + if(ox + wordWidth > maxWidth) { + lines[++line] = ""; + ox = 0; + } + + lines[line] += word; + + ox += wordWidth; + } + } else var lines = [text]; + + for(var i = 0; i < lines.length; i++) { + var oy = y + i * h * 0.6 | 0; + var lingrad = this.context.createLinearGradient(0, oy, 0, oy + h * 0.6 | 0); + + for(var j = 0; j < gradient.length; j += 2) { + lingrad.addColorStop(gradient[j], gradient[j + 1]); + } + + var text = lines[i]; + + this.fillStyle(lingrad).fillText(text, x, oy); + } + + return this; + }, + + setHsl: function() { + + if(arguments.length === 1) { + var args = arguments[0]; + } else { + var args = arguments; + } + + var data = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var pixels = data.data; + var r, g, b, a, h, s, l, hsl = [], + newPixel = []; + + for(var i = 0, len = pixels.length; i < len; i += 4) { + hsl = $.rgbToHsl(pixels[i + 0], pixels[i + 1], pixels[i + 2]); + + h = args[0] === null ? hsl[0] : $.limitValue(args[0], 0, 1); + s = args[1] === null ? hsl[1] : $.limitValue(args[1], 0, 1); + l = args[2] === null ? hsl[2] : $.limitValue(args[2], 0, 1); + + newPixel = $.hslToRgb(h, s, l); + + pixels[i + 0] = newPixel[0]; + pixels[i + 1] = newPixel[1]; + pixels[i + 2] = newPixel[2]; + } + + this.context.putImageData(data, 0, 0); + + return this; + }, + + shiftHsl: function() { + + if(arguments.length === 1) { + var args = arguments[0]; + } else { + var args = arguments; + } + + var data = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var pixels = data.data; + var r, g, b, a, h, s, l, hsl = [], + newPixel = []; + + for(var i = 0, len = pixels.length; i < len; i += 4) { + hsl = $.rgbToHsl(pixels[i + 0], pixels[i + 1], pixels[i + 2]); + + h = args[0] === null ? hsl[0] : $.wrapValue(hsl[0] + args[0], 0, 1); + s = args[1] === null ? hsl[1] : $.limitValue(hsl[1] + args[1], 0, 1); + l = args[2] === null ? hsl[2] : $.limitValue(hsl[2] + args[2], 0, 1); + + newPixel = $.hslToRgb(h, s, l); + + pixels[i + 0] = newPixel[0]; + pixels[i + 1] = newPixel[1]; + pixels[i + 2] = newPixel[2]; + } + + + this.context.putImageData(data, 0, 0); + + return this; + }, + + replaceHue: function(src, dst) { + + var data = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var pixels = data.data; + var r, g, b, a, h, s, l, hsl = [], + newPixel = []; + + for(var i = 0, len = pixels.length; i < len; i += 4) { + hsl = $.rgbToHsl(pixels[i + 0], pixels[i + 1], pixels[i + 2]); + + if(Math.abs(hsl[0] - src) < 0.05) h = $.wrapValue(dst, 0, 1); + else h = hsl[0]; + + newPixel = $.hslToRgb(h, hsl[1], hsl[2]); + + pixels[i + 0] = newPixel[0]; + pixels[i + 1] = newPixel[1]; + pixels[i + 2] = newPixel[2]; + } + + this.context.putImageData(data, 0, 0); + + return this; + }, + + invert: function(src, dst) { + + var data = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var pixels = data.data; + var r, g, b, a, h, s, l, hsl = [], + newPixel = []; + + for(var i = 0, len = pixels.length; i < len; i += 4) { + pixels[i + 0] = 255 - pixels[i + 0]; + pixels[i + 1] = 255 - pixels[i + 1]; + pixels[i + 2] = 255 - pixels[i + 2]; + } + + this.context.putImageData(data, 0, 0); + + return this; + }, + + roundRect: function(x, y, width, height, radius) { + + this.beginPath(); + this.moveTo(x + radius, y); + this.lineTo(x + width - radius, y); + this.quadraticCurveTo(x + width, y, x + width, y + radius); + this.lineTo(x + width, y + height - radius); + this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); + this.lineTo(x + radius, y + height); + this.quadraticCurveTo(x, y + height, x, y + height - radius); + this.lineTo(x, y + radius); + this.quadraticCurveTo(x, y, x + radius, y); + this.closePath(); + + return this; + }, + + wrappedText: function(text, x, y, maxWidth, newlineCallback) { + + var words = text.split(" "); + + var h = this.font().match(/\d+/g)[0] * 2; + + var ox = 0; + var oy = 0; + + if(maxWidth) { + var line = 0; + var lines = [""]; + + for(var i = 0; i < words.length; i++) { + var word = words[i] + " "; + var wordWidth = this.context.measureText(word).width; + + if(ox + wordWidth > maxWidth) { + lines[++line] = ""; + ox = 0; + } + + lines[line] += word; + + ox += wordWidth; + } + } else { + var lines = [text]; + } + + for(var i = 0; i < lines.length; i++) { + var oy = y + i * h * 0.6 | 0; + + var text = lines[i]; + + if(newlineCallback) newlineCallback.call(this, x, y + oy); + + this.fillText(text, x, oy); + } + + return this; + }, + + textBoundaries: function(text, maxWidth) { + var words = text.split(" "); + + var h = this.font().match(/\d+/g)[0] * 2; + + var ox = 0; + var oy = 0; + + if(maxWidth) { + var line = 0; + var lines = [""]; + + for(var i = 0; i < words.length; i++) { + var word = words[i] + " "; + var wordWidth = this.context.measureText(word).width; + + if(ox + wordWidth > maxWidth) { + lines[++line] = ""; + ox = 0; + } + + lines[line] += word; + + ox += wordWidth; + } + } else { + var lines = [text]; + maxWidth = this.measureText(text).width; + } + + return { + height: lines.length * h * 0.6 | 0, + width: maxWidth + } + }, + + paperBag: function(x, y, width, height, blowX, blowY) { + var lx, ly; + this.beginPath(); + this.moveTo(x, y); + this.quadraticCurveTo(x + width / 2 | 0, y + height * blowY | 0, x + width, y); + this.quadraticCurveTo(x + width - width * blowX | 0, y + height / 2 | 0, x + width, y + height); + this.quadraticCurveTo(x + width / 2 | 0, y + height - height * blowY | 0, x, y + height); + this.quadraticCurveTo(x + width * blowX | 0, y + height / 2 | 0, x, y); + }, + + borderImage: function(image, x, y, w, h, t, r, b, l, fill) { + + /* top */ + this.drawImage(image, l, 0, image.width - l - r, t, x + l, y, w - l - r, t); + + /* bottom */ + this.drawImage(image, l, image.height - b, image.width - l - r, b, x + l, y + h - b, w - l - r, b); + + /* left */ + this.drawImage(image, 0, t, l, image.height - b - t, x, y + t, l, h - b - t); + + /* right */ + this.drawImage(image, image.width - r, t, r, image.height - b - t, x + w - r, y + t, r, h - b - t); + + /* top-left */ + this.drawImage(image, 0, 0, l, t, x, y, l, t); + + /* top-right */ + this.drawImage(image, image.width - r, 0, r, t, x + w - r, y, r, t); + + /* bottom-right */ + this.drawImage(image, image.width - r, image.height - b, r, b, x + w - r, y + h - b, r, b); + + /* bottom-left */ + this.drawImage(image, 0, image.height - b, l, b, x, y + h - b, l, b); + + if(fill) { + if(typeof fill === "string") { + this.fillStyle(fill).fillRect(x + l, y + t, w - l - r, h - t - b); + } else { + this.drawImage(image, l, t, image.width - r - l, image.height - b - t, x + l, y + t, w - l - r, h - t - b); + } + } + }, + + /* www.html5rocks.com/en/tutorials/canvas/imagefilters/ */ + + convolve: function(matrix, mix, divide) { + + if(typeof divide === "undefined") divide = 1; + if(typeof mix === "undefined") mix = 1; + + var sourceData = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var matrixSize = Math.sqrt(matrix.length) + 0.5 | 0; + var halfMatrixSize = matrixSize / 2 | 0; + var src = sourceData.data; + var sw = sourceData.width; + var sh = sourceData.height; + var w = sw; + var h = sh; + var output = $.createImageData(this.canvas.width, this.canvas.height); + var dst = output.data; + + for(var y = 1; y < h - 1; y++) { + for(var x = 1; x < w - 1; x++) { + + var dstOff = (y * w + x) * 4; + var r = 0, + g = 0, + b = 0, + a = 0; + for(var cy = 0; cy < matrixSize; cy++) { + for(var cx = 0; cx < matrixSize; cx++) { + var scy = y + cy - halfMatrixSize; + var scx = x + cx - halfMatrixSize; + if(scy >= 0 && scy < sh && scx >= 0 && scx < sw) { + var srcOff = (scy * sw + scx) * 4; + var wt = matrix[cy * matrixSize + cx] / divide; + r += src[srcOff + 0] * wt; + g += src[srcOff + 1] * wt; + b += src[srcOff + 2] * wt; + a += src[srcOff + 3] * wt; + } + } + } + dst[dstOff + 0] = $.mix(src[dstOff + 0], r, mix); + dst[dstOff + 1] = $.mix(src[dstOff + 1], g, mix); + dst[dstOff + 2] = $.mix(src[dstOff + 2], b, mix); + dst[dstOff + 3] = src[dstOff + 3]; + } + } + + this.context.putImageData(output, 0, 0); + + return this; + }, + + blur: function(mix) { + return this.convolve([1, 1, 1, 1, 1, 1, 1, 1, 1], mix, 9); + }, + + gaussianBlur: function(mix) { + return this.convolve([0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067, 0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292, 0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117, 0.00038771, 0.01330373, 0.11098164, 0.22508352, 0.11098164, 0.01330373, 0.00038771, 0.00019117, 0.00655965, 0.05472157, 0.11098164, 0.05472157, 0.00655965, 0.00019117, 0.00002292, 0.00078633, 0.00655965, 0.01330373, 0.00655965, 0.00078633, 0.00002292, 0.00000067, 0.00002292, 0.00019117, 0.00038771, 0.00019117, 0.00002292, 0.00000067], mix, 1); + }, + + sharpen: function(mix) { + return this.convolve([0, -1, 0, -1, 5, -1, 0, -1, 0], mix); + }, + + threshold: function(threshold) { + var data = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var pixels = data.data; + var r, g, b; + + for(var i = 0; i < pixels.length; i += 4) { + var r = pixels[i]; + var g = pixels[i + 1]; + var b = pixels[i + 2]; + var v = (0.2126 * r + 0.7152 * g + 0.0722 * b >= threshold) ? 255 : 0; + pixels[i] = pixels[i + 1] = pixels[i + 2] = v + } + + this.context.putImageData(data, 0, 0); + + return this; + }, + + sepia: function() { + var data = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height); + var pixels = data.data; + var r, g, b; + + for(var i = 0; i < pixels.length; i += 4) { + pixels[i + 0] = $.limitValue((pixels[i + 0] * .393) + (pixels[i + 1] * .769) + (pixels[i + 2] * .189), 0, 255); + pixels[i + 1] = $.limitValue((pixels[i + 0] * .349) + (pixels[i + 1] * .686) + (pixels[i + 2] * .168), 0, 255); + pixels[i + 2] = $.limitValue((pixels[i + 0] * .272) + (pixels[i + 1] * .534) + (pixels[i + 2] * .131), 0, 255); + } + + this.context.putImageData(data, 0, 0); + + return this; + }, + + measureText: function() { + return this.context.measureText.apply(this.context, arguments); + }, + + createRadialGradient: function() { + return this.context.createRadialGradient.apply(this.context, arguments); + }, + + createLinearGradient: function() { + return this.context.createLinearGradient.apply(this.context, arguments); + }, + + getImageData: function() { + return this.context.getImageData.apply(this.context, arguments); + }, + + /* framework */ + + framework: function(args, context) { + if(context) { + this.tempContext = context === true ? args : context; + } + + for(var name in args) { + if(this[name]) this[name](args[name], undefined, undefined); + } + + this.tempContext = null; + + return this; + }, + + onStep: function(callback, interval) { + var self = this.tempContext || this; + var lastTick = Date.now(); + + this.timer = setInterval(function() { + var delta = Date.now() - lastTick; + lastTick = Date.now(); + callback.call(self, delta, lastTick); + }, interval); + + return this; + }, + + onRender: function(callback) { + var self = this.tempContext || this; + + var lastTick = Date.now(); + + function step() { + var delta = Date.now() - lastTick; + lastTick = Date.now(); + requestAnimationFrame(step) + callback.call(self, delta, lastTick); + }; + + requestAnimationFrame(step); + + return this; + }, + + onMouseMove: function(callback) { + var self = this.tempContext || this; + + if(!MOBILE) this.canvas.addEventListener("mousemove", function(e) { + var pos = $.mousePosition(e); + callback.call(self, pos.x, pos.y); + }); + + else this.canvas.addEventListener("touchmove", function(e) { + e.preventDefault(); + var pos = $.mousePosition(e); + callback.call(self, pos.x, pos.y); + }); + + return this; + }, + + onMouseDown: function(callback) { + var self = this.tempContext || this; + + if(!MOBILE) { + this.canvas.addEventListener("mousedown", function(e) { + var pos = $.mousePosition(e); + callback.call(self, pos.x, pos.y, e.button); + }); + } else { + this.canvas.addEventListener("touchstart", function(e) { + var pos = $.mousePosition(e); + callback.call(self, pos.x, pos.y, e.button); + }); + } + + return this; + }, + + onMouseUp: function(callback) { + var self = this.tempContext || this; + + if(!MOBILE) { + this.canvas.addEventListener("mouseup", function(e) { + var pos = $.mousePosition(e); + callback.call(self, pos.x, pos.y, e.button); + }); + } else { + this.canvas.addEventListener("touchend", function(e) { + var pos = $.mousePosition(e); + callback.call(self, pos.x, pos.y, e.button); + }); + } + + return this; + }, + + + onSwipe: function(callback, threshold, timeout) { + var self = this.tempContext || this; + + var swipeThr = threshold || 35; + var swipeTim = timeout || 350; + + var swipeSP = 0; + var swipeST = 0; + var swipeEP = 0; + var swipeET = 0; + + function swipeStart(e) { + e.preventDefault(); + swipeSP = $.mousePosition(e); + swipeST = Date.now(); + } + + function swipeUpdate(e) { + e.preventDefault(); + swipeEP = $.mousePosition(e); + swipeET = Date.now(); + } + + function swipeEnd(e) { + e.preventDefault(); + + var xDif = (swipeSP.x - swipeEP.x); + var yDif = (swipeSP.y - swipeEP.y); + var x = (xDif * xDif); + var y = (yDif * yDif); + var swipeDist = Math.sqrt(x + y); + var swipeTime = (swipeET - swipeST); + var swipeDir = undefined; + + if(swipeDist > swipeThr && swipeTime < swipeTim) { + if(Math.abs(xDif) > Math.abs(yDif)) { + if(xDif > 0) { + swipeDir = "left"; + } else { + swipeDir = "right"; + } + } else { + if(yDif > 0) { + swipeDir = "up"; + } else { + swipeDir = "down"; + } + } + callback.call(self, swipeDir); + } + } + + this.canvas.addEventListener("touchstart", function(e) { + swipeStart(e); + }); + this.canvas.addEventListener("touchmove", function(e) { + swipeUpdate(e); + }); + this.canvas.addEventListener("touchend", function(e) { + swipeEnd(e); + }); + this.canvas.addEventListener("mousedown", function(e) { + swipeStart(e); + }); + this.canvas.addEventListener("mousemove", function(e) { + swipeUpdate(e); + }); + this.canvas.addEventListener("mouseup", function(e) { + swipeEnd(e); + }); + + return this; + }, + + onKeyDown: function(callback) { + document.addEventListener("keydown", function(e) { + if(e.which >= 48 && e.which <= 90) var keyName = String.fromCharCode(e.which).toLowerCase(); + else var keyName = $.keycodes[e.which]; + callback.call(self, keyName); + }); + return this; + }, + + onKeyUp: function(callback) { + document.addEventListener("keyup", function(e) { + if(e.which >= 48 && e.which <= 90) var keyName = String.fromCharCode(e.which).toLowerCase(); + else var keyName = $.keycodes[e.which]; + callback.call(self, keyName); + }); + return this; + }, + + onResize: function(callback) { + var self = this; + + window.addEventListener("resize", function() { + callback.call(self, window.innerWidth, window.innerHeight); + }); + + callback.call(self, window.innerWidth, window.innerHeight); + + return this; + }, + + onDropImage: function(callback) { + var self = this; + document.addEventListener('drop', function(e) { + e.stopPropagation(); + e.preventDefault(); + + var file = e.dataTransfer.files[0]; + + if(!(/image/i).test(file.type)) return false; + var reader = new FileReader(); + + reader.onload = function(e) { + var image = new Image; + + image.onload = function() { + callback.call(self, this); + }; + + image.src = e.target.result; + }; + + reader.readAsDataURL(file); + + }); + + document.addEventListener("dragover", function(e) { + e.preventDefault(); + }); + + return this; + } + + }; + + /* extend wrapper with drawing context methods */ + + var methods = ["arc", "arcTo", "beginPath", "bezierCurveTo", "clearRect", "clip", "closePath", "createImageData", "createLinearGradient", "createRadialGradient", "createPattern", "drawFocusRing", "drawImage", "fill", "fillRect", "fillText", "getImageData", "isPointInPath", "lineTo", "measureText", "moveTo", "putImageData", "quadraticCurveTo", "rect", "restore", "rotate", "save", "scale", "setTransform", "stroke", "strokeRect", "strokeText", "transform", "translate"]; + for(var i = 0; i < methods.length; i++) { + var name = methods[i]; + if(!$.Wrapper.prototype[name]) $.Wrapper.prototype[name] = Function("this.context." + name + ".apply(this.context, arguments); return this;"); + }; + + /* create setters and getters */ + + var properties = ["canvas", "fillStyle", "font", "globalAlpha", "globalCompositeOperation", "lineCap", "lineJoin", "lineWidth", "miterLimit", "shadowOffsetX", "shadowOffsetY", "shadowBlur", "shadowColor", "strokeStyle", "textAlign", "textBaseline"]; + for(var i = 0; i < properties.length; i++) { + var name = properties[i]; + if(!$.Wrapper.prototype[name]) $.Wrapper.prototype[name] = Function("if(arguments.length) { this.context." + name + " = arguments[0]; return this; } else { return this.context." + name + "; }"); + }; + + /* color */ + + $.Color = function() { + if(arguments.length) this.parse(arguments); + } + + $.Color.prototype = { + parse: function(args) { + if(typeof args[0] === "string") { + var rgb = $.hexToRgb(args[0]); + this[0] = rgb[0]; + this[1] = rgb[1]; + this[2] = rgb[2]; + this[3] = 255; + } else { + this[0] = args[0]; + this[1] = args[1]; + this[2] = args[2]; + this[3] = typeof args[3] === "undefined" ? 255 : args[3]; + } + }, + + toArray: function() { + return [this[0], this[1], this[2], this[3]]; + }, + + toRgb: function() { + return "rgb(" + this[0] + ", " + this[1] + ", " + this[2] + ")"; + }, + + toRgba: function() { + return "rgb(" + this[0] + ", " + this[1] + ", " + this[2] + ", " + this[3] + ")"; + }, + + toHex: function() { + return $.rgbToHex(this[0], this[1], this[2]); + }, + + toHsl: function() { + return $.rgbToHsl(this[0], this[1], this[2]); + }, + + toHsv: function() { + return $.rgbToHsv(this[0], this[1], this[2]); + } + + }; + + window["cq"] = window["CanvasQuery"] = $; + + if(typeof define === "function" && define.amd) { + define([], function() { + return $; + }); + } + +})(window); \ No newline at end of file diff --git a/dat.gui.min.js b/dat.gui.min.js new file mode 100644 index 0000000..87b9039 --- /dev/null +++ b/dat.gui.min.js @@ -0,0 +1,82 @@ +var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(e,a){a=a||document;var b=a.createElement("link");b.type="text/css";b.rel="stylesheet";b.href=e;a.getElementsByTagName("head")[0].appendChild(b)},inject:function(e,a){a=a||document;var b=document.createElement("style");b.type="text/css";b.innerHTML=e;a.getElementsByTagName("head")[0].appendChild(b)}}}(); +dat.utils.common=function(){var e=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(b){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(a[f])||(b[f]=a[f])},this);return b},defaults:function(b){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(b[f])&&(b[f]=a[f])},this);return b},compose:function(){var b=a.call(arguments);return function(){for(var d=a.call(arguments),f=b.length-1;0<=f;f--)d=[b[f].apply(this,d)];return d[0]}}, +each:function(a,d,f){if(e&&a.forEach===e)a.forEach(d,f);else if(a.length===a.length+0)for(var c=0,p=a.length;cthis.__max&&(a=this.__max);void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step);return b.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.__step=a;return this}});return b}(dat.controllers.Controller,dat.utils.common); +dat.controllers.NumberControllerBox=function(e,a,b){var d=function(f,c,e){function k(){var a=parseFloat(n.__input.value);b.isNaN(a)||n.setValue(a)}function l(a){var c=r-a.clientY;n.setValue(n.getValue()+c*n.__impliedStep);r=a.clientY}function q(){a.unbind(window,"mousemove",l);a.unbind(window,"mouseup",q)}this.__truncationSuspended=!1;d.superclass.call(this,f,c,e);var n=this,r;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",k);a.bind(this.__input, +"blur",function(){k();n.__onFinishChange&&n.__onFinishChange.call(n,n.getValue())});a.bind(this.__input,"mousedown",function(c){a.bind(window,"mousemove",l);a.bind(window,"mouseup",q);r=c.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)};d.superclass=e;b.extend(d.prototype,e.prototype,{updateDisplay:function(){var a=this.__input,c;if(this.__truncationSuspended)c= +this.getValue();else{c=this.getValue();var b=Math.pow(10,this.__precision);c=Math.round(c*b)/b}a.value=c;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common); +dat.controllers.NumberControllerSlider=function(e,a,b,d,f){function c(a,c,d,b,f){return b+(a-c)/(d-c)*(f-b)}var p=function(d,b,f,e,r){function y(d){d.preventDefault();var b=a.getOffset(h.__background),f=a.getWidth(h.__background);h.setValue(c(d.clientX,b.left,b.left+f,h.__min,h.__max));return!1}function g(){a.unbind(window,"mousemove",y);a.unbind(window,"mouseup",g);h.__onFinishChange&&h.__onFinishChange.call(h,h.getValue())}p.superclass.call(this,d,b,{min:f,max:e,step:r});var h=this;this.__background= +document.createElement("div");this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(c){a.bind(window,"mousemove",y);a.bind(window,"mouseup",g);y(c)});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=e;p.useDefaultStyles=function(){b.inject(f)};d.extend(p.prototype,e.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(e,a,b){var d=function(b,c,e){d.superclass.call(this,b,c);var k=this;this.__button=document.createElement("div");this.__button.innerHTML=void 0===e?"Fire":e;a.bind(this.__button,"click",function(a){a.preventDefault();k.fire();return!1});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};d.superclass=e;b.extend(d.prototype,e.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.__onFinishChange&&this.__onFinishChange.call(this, +this.getValue());this.getValue().call(this.object)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.controllers.BooleanController=function(e,a,b){var d=function(b,c){d.superclass.call(this,b,c);var e=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},!1);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};d.superclass=e;b.extend(d.prototype,e.prototype,{setValue:function(a){a=d.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 d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.color.toString=function(e){return function(a){if(1==a.a||e.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(e,a){var b,d,f=[{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:e},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:e},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:e},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:e}}},{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(c){return a.isNumber(c.r)&&a.isNumber(c.g)&&a.isNumber(c.b)&&a.isNumber(c.a)?{space:"RGB",r:c.r,g:c.g,b:c.b,a:c.a}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(c){return a.isNumber(c.r)&& +a.isNumber(c.g)&&a.isNumber(c.b)?{space:"RGB",r:c.r,g:c.g,b:c.b}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(c){return a.isNumber(c.h)&&a.isNumber(c.s)&&a.isNumber(c.v)&&a.isNumber(c.a)?{space:"HSV",h:c.h,s:c.s,v:c.v,a:c.a}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(d){return a.isNumber(d.h)&&a.isNumber(d.s)&&a.isNumber(d.v)?{space:"HSV",h:d.h,s:d.s,v:d.v}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d=!1; +var c=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(e,a,b,d,f,c,p){return function(k,l,q,n){var r=k[l];if(p.isArray(q)||p.isObject(q))return new e(k,l,q);if(p.isNumber(r))return p.isNumber(q)&&p.isNumber(n)?new b(k,l,q,n):new a(k,l,{min:q,max:n});if(p.isString(r))return new d(k,l);if(p.isFunction(r))return new f(k,l,"");if(p.isBoolean(r))return new c(k,l)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(e,a,b){var d= +function(b,c){function e(){k.setValue(k.__input.value)}d.superclass.call(this,b,c);var k=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",e);a.bind(this.__input,"change",e);a.bind(this.__input,"blur",function(){k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;b.extend(d.prototype, +e.prototype,{updateDisplay:function(){a.isActive(this.__input)||(this.__input.value=this.getValue());return d.superclass.prototype.updateDisplay.call(this)}});return d}(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(e,a,b,d,f){function c(a,b,d,c){a.style.background="";f.each(l,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+d+" 0%, "+c+" 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 k=function(e,n){function r(b){t(b);a.bind(window,"mousemove",t);a.bind(window, +"mouseup",l)}function l(){a.unbind(window,"mousemove",t);a.unbind(window,"mouseup",l)}function g(){var a=d(this.value);!1!==a?(s.__color.__state=a,s.setValue(s.__color.toOriginal())):this.value=s.__color.toString()}function h(){a.unbind(window,"mousemove",u);a.unbind(window,"mouseup",h)}function t(b){b.preventDefault();var d=a.getWidth(s.__saturation_field),c=a.getOffset(s.__saturation_field),e=(b.clientX-c.left+document.body.scrollLeft)/d;b=1-(b.clientY-c.top+document.body.scrollTop)/d;1 +b&&(b=0);1e&&(e=0);s.__color.v=b;s.__color.s=e;s.setValue(s.__color.toOriginal());return!1}function u(b){b.preventDefault();var d=a.getHeight(s.__hue_field),c=a.getOffset(s.__hue_field);b=1-(b.clientY-c.top+document.body.scrollTop)/d;1b&&(b=0);s.__color.h=360*b;s.setValue(s.__color.toOriginal());return!1}k.superclass.call(this,e,n);this.__color=new b(this.getValue());this.__temp=new b(0);var s=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(s.__selector,"drag")})});var v=document.createElement("div");f.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});f.extend(this.__field_knob.style, +{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(0.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});f.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});f.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});f.extend(v.style,{width:"100%",height:"100%", +background:"none"});c(v,"top","rgba(0,0,0,0)","#000");f.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});p(this.__hue_field);f.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",r);a.bind(this.__field_knob,"mousedown",r);a.bind(this.__hue_field,"mousedown",function(b){u(b);a.bind(window, +"mousemove",u);a.bind(window,"mouseup",h)});this.__saturation_field.appendChild(v);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()};k.superclass=e;f.extend(k.prototype,e.prototype,{updateDisplay:function(){var a=d(this.getValue());if(!1!==a){var e=!1; +f.each(b.COMPONENTS,function(b){if(!f.isUndefined(a[b])&&!f.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return e=!0,{}},this);e&&f.extend(this.__color.__state,a)}f.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var k=0.5>this.__color.v||0.5a&&(a+=1);return{h:360*a,s:e/c,v:c/255}},rgb_to_hex:function(a,b,d){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,b);return a=this.hex_with_component(a,0,d)},component_from_hex:function(a,b){return a>>8*b&255},hex_with_component:function(a,b,d){return d<<(e=8*b)|a&~(255< + + + + + + + +screen record bookmarklet +
    +
    + + + + + + + -- cgit v1.2.3-70-g09d2