├── .gitignore ├── src ├── images │ ├── bg.jpg │ ├── en.png │ ├── hello.jpg │ ├── timg2.jpg │ ├── Potter.jpg │ ├── hello2.jpg │ ├── export │ │ ├── UI.png │ │ ├── bg.jpg │ │ └── Potter.jpg │ └── portraits.jpg ├── index.html ├── css │ └── index.css └── js │ ├── index.js │ ├── SLIC.js │ └── dat.gui.min.js ├── docs ├── images │ ├── bg.jpg │ ├── en.png │ ├── Potter.jpg │ ├── hello.jpg │ ├── hello2.jpg │ ├── timg2.jpg │ ├── export │ │ ├── UI.png │ │ ├── bg.jpg │ │ └── Potter.jpg │ └── portraits.jpg ├── e5e0f8e9a2c264e35d5f7daf09755fd9.jpg ├── index.html └── app.bundle.js ├── dist ├── e5e0f8e9a2c264e35d5f7daf09755fd9.jpg ├── index.html └── app.bundle.js ├── webpack.dev.js ├── webpack.prod.js ├── README.md ├── webpack.common.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /src/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/bg.jpg -------------------------------------------------------------------------------- /src/images/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/en.png -------------------------------------------------------------------------------- /docs/images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/bg.jpg -------------------------------------------------------------------------------- /docs/images/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/en.png -------------------------------------------------------------------------------- /src/images/hello.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/hello.jpg -------------------------------------------------------------------------------- /src/images/timg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/timg2.jpg -------------------------------------------------------------------------------- /docs/images/Potter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/Potter.jpg -------------------------------------------------------------------------------- /docs/images/hello.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/hello.jpg -------------------------------------------------------------------------------- /docs/images/hello2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/hello2.jpg -------------------------------------------------------------------------------- /docs/images/timg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/timg2.jpg -------------------------------------------------------------------------------- /src/images/Potter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/Potter.jpg -------------------------------------------------------------------------------- /src/images/hello2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/hello2.jpg -------------------------------------------------------------------------------- /docs/images/export/UI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/export/UI.png -------------------------------------------------------------------------------- /docs/images/export/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/export/bg.jpg -------------------------------------------------------------------------------- /docs/images/portraits.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/portraits.jpg -------------------------------------------------------------------------------- /src/images/export/UI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/export/UI.png -------------------------------------------------------------------------------- /src/images/export/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/export/bg.jpg -------------------------------------------------------------------------------- /src/images/portraits.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/portraits.jpg -------------------------------------------------------------------------------- /docs/images/export/Potter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/images/export/Potter.jpg -------------------------------------------------------------------------------- /src/images/export/Potter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/src/images/export/Potter.jpg -------------------------------------------------------------------------------- /dist/e5e0f8e9a2c264e35d5f7daf09755fd9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/dist/e5e0f8e9a2c264e35d5f7daf09755fd9.jpg -------------------------------------------------------------------------------- /docs/e5e0f8e9a2c264e35d5f7daf09755fd9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xs7/Pixelate/HEAD/docs/e5e0f8e9a2c264e35d5f7daf09755fd9.jpg -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | devtool: 'inline-source-map', 6 | devServer: { 7 | contentBase: './dist' 8 | } 9 | }); 10 | -------------------------------------------------------------------------------- /webpack.prod.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); 3 | const common = require('./webpack.common.js'); 4 | 5 | module.exports = merge(common, { 6 | plugins: [ 7 | new UglifyJSPlugin() 8 | ] 9 | }); 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pixel 2 | Pixelate Image 3 | ## Demo 4 | [Try it](https://xs7.github.io/Pixelate/index.html) 5 | 6 | ![UI](https://xs7.github.io/Pixelate/images/export/UI.png) 7 | 8 | 9 | ## Example 10 | ![potter](https://xs7.github.io/Pixelate/images/jing.jpg) 11 | ![potter-export](https://xs7.github.io/Pixelate/images/export/jing.jpg) 12 | ![potter](https://xs7.github.io/Pixelate/images/Potter.jpg) 13 | ![potter-export](https://xs7.github.io/Pixelate/images/export/Potter.jpg) 14 | ![bg](https://xs7.github.io/Pixelate/images/bg.jpg) 15 | ![bg-export](https://xs7.github.io/Pixelate/images/export/bg.jpg) 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Pixelate tool 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Pixelate tool 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Pixelate tool 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const { CleanWebpackPlugin } = require('clean-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const webpack = require('webpack'); 5 | 6 | module.exports = { 7 | entry: { 8 | app: './src/js/index.js' 9 | }, 10 | plugins: [ 11 | new CleanWebpackPlugin(), 12 | new HtmlWebpackPlugin({ 13 | title: "custom template", 14 | template: './src/index.html', 15 | filename: 'index.html' 16 | }) 17 | ], 18 | output: { 19 | filename: '[name].bundle.js', 20 | path: path.resolve(__dirname, 'dist') 21 | }, 22 | module: { 23 | rules: [{ 24 | test: /\.css/, 25 | use: [ 26 | 'style-loader', 27 | 'css-loader' 28 | ] 29 | }, 30 | { 31 | test: /\.m?js$/, 32 | exclude: /(node_modules|bower_components)/, 33 | use: { 34 | loader: 'babel-loader', 35 | options: { 36 | presets: ['@babel/preset-env'] 37 | } 38 | } 39 | }, 40 | { 41 | test: /\.(png|svg|jpg|gif)$/, 42 | use: [ 43 | 'file-loader' 44 | ] 45 | } 46 | ] 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /src/css/index.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: #99CCCC; 3 | } 4 | 5 | canvas{ 6 | display: block; 7 | /* margin: 0 auto; */ 8 | position: absolute; 9 | top: 50%; 10 | left:50%; 11 | 12 | } 13 | 14 | #canvas{ 15 | -moz-box-shadow:0px 0px 8px #333333; 16 | -webkit-box-shadow:0px 0px 8px #333333; 17 | box-shadow:0px 0px 8px #333333; 18 | } 19 | #loadingbox{ 20 | width: 100px; 21 | height: 100px; 22 | border-radius: 30px; 23 | background-color: rgba(255,255,255,0.9); 24 | position: absolute; 25 | top: 50%; 26 | left:50%; 27 | transform: translate(-50%,-50%); 28 | box-shadow: 2px 2px 2px #fff; 29 | } 30 | @keyframes rotate{ 31 | from { 32 | transform: translate(-50%,-50%) rotate(0deg); 33 | } 34 | to { 35 | transform: translate(-50%,-50%) rotate(359deg); 36 | } 37 | } 38 | .circle{ 39 | width: 50px; 40 | height: 50px; 41 | border-radius: 50%; 42 | border: 5px solid #99CCCC; 43 | top: 50%; 44 | left:50%; 45 | position: absolute; 46 | transform: translate(-50%,-50%); 47 | border-right: 5px solid transparent; 48 | animation: 1s rotate infinite; 49 | } 50 | .hidden{ 51 | visibility: hidden; 52 | } 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pixel", 3 | "version": "1.0.0", 4 | "description": "Pixelate Image\r ## Demo\r [Try it](https://xs7.github.io/Pixel/index.html)", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --open --config webpack.dev.js", 8 | "build": "webpack --config webpack.prod.js", 9 | "dev": "webpack --config webpack.dev.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/xs7/Pixel.git" 14 | }, 15 | "author": "xs", 16 | "license": "ISC", 17 | "bugs": { 18 | "url": "https://github.com/xs7/Pixel/issues" 19 | }, 20 | "homepage": "https://github.com/xs7/Pixel#readme", 21 | "devDependencies": { 22 | "@babel/core": "^7.5.5", 23 | "@babel/preset-env": "^7.5.5", 24 | "babel-loader": "^8.0.6", 25 | "clean-webpack-plugin": "^3.0.0", 26 | "css-loader": "^3.1.0", 27 | "file-loader": "^4.1.0", 28 | "html-webpack-plugin": "^3.2.0", 29 | "style-loader": "^0.23.1", 30 | "uglifyjs-webpack-plugin": "^2.2.0", 31 | "webpack": "^4.38.0", 32 | "webpack-cli": "^3.3.6", 33 | "webpack-dev-server": "^3.7.2", 34 | "webpack-merge": "^4.2.1" 35 | }, 36 | "dependencies": { 37 | "babel-preset-es2015": "^6.24.1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/js/index.js: -------------------------------------------------------------------------------- 1 | import SLIC from "./SLIC.js" 2 | import "../css/index.css" 3 | import dat from "./dat.gui.min.js" 4 | import exampleImage from '../images/portraits.jpg' 5 | 6 | var filedom = document.getElementById('filebtn') 7 | let canvas = document.getElementById("canvas") 8 | let loadingbox = document.getElementById("loadingbox") 9 | let context = canvas.getContext("2d") 10 | let canvas_centers = document.getElementById("canvas_centers") 11 | let context_centers = canvas_centers.getContext("2d") 12 | let canvas_contours = document.getElementById("canvas_contours") 13 | let context_contours = canvas_contours.getContext("2d") 14 | var padtext 15 | /* canvas.onclick = function (event) { 16 | // console.log(click) 17 | let x = event.offsetX 18 | let y = event.offsetY 19 | let imageData = context.getImageData(x, y, 1, 1) 20 | // 获取该点像素数据 21 | let pixel = imageData.data 22 | let r = pixel[0] 23 | let g = pixel[1] 24 | let b = pixel[2] 25 | let a = pixel[3] / 255 26 | 27 | let rHex = r.toString(16) 28 | r < 16 && (rHex = "0" + rHex) 29 | let gHex = g.toString(16) 30 | g < 16 && (gHex = "0" + gHex) 31 | let bHex = b.toString(16) 32 | b < 16 && (bHex = "0" + bHex) 33 | let rgbaColor = "rgba(" + r + "," + g + "," + b + "," + a + ")" 34 | let rgbColor = "rgb(" + r + "," + g + "," + b + ")" 35 | let hexColor = "#" + rHex + gHex + bHex 36 | let result = { 37 | rgba: rgbaColor, 38 | rgb: rgbColor, 39 | hex: hexColor, 40 | r: r, 41 | g: g, 42 | b: b, 43 | a: a 44 | } 45 | console.log(result.r,result.g,result,b) 46 | } 47 | */ 48 | 49 | //Init data and result 50 | 51 | let config = { 52 | blockSize: 20, 53 | weight: 30, 54 | iters: 10, 55 | stride: 10, 56 | withGrid: true, 57 | withCenters: false, 58 | withContours: false, 59 | } 60 | // let weight = 30 61 | // let iters = 10 62 | // let stride = 10 63 | // var withGrid = false 64 | // var withContours = false 65 | // var withCenters = false 66 | var pixelImage 67 | var slic 68 | let filename = "portraits" 69 | let filetype = "image/jpeg" 70 | 71 | 72 | 73 | //paiting pixel in canvas 74 | function displayImg() { 75 | let imgData = context.createImageData(canvas.width, canvas.height) 76 | for (let i = 0; i < pixelImage.length; i++) 77 | imgData.data[i] = pixelImage[i] 78 | context.putImageData(imgData, 0, 0) 79 | 80 | if (config.withGrid) { 81 | context.strokeStyle = "white" 82 | context.lineWidth = 1 83 | for (let i = 0; i < canvas.width; i += config.stride) { 84 | context.beginPath() 85 | context.moveTo(i, 0) 86 | context.lineTo(i, canvas.height) 87 | context.stroke() 88 | } 89 | for (let i = 0; i < canvas.height; i += config.stride) { 90 | context.beginPath() 91 | context.moveTo(0, i) 92 | context.lineTo(canvas.width, i) 93 | context.stroke() 94 | } 95 | } 96 | } 97 | 98 | function displayCenters() { 99 | if (config.withCenters) { 100 | canvas_centers.style.display = "block" 101 | canvas_centers.width = canvas_centers.width 102 | slic.showCenters(context_centers) 103 | } else { 104 | canvas_centers.style.display = "none" 105 | } 106 | 107 | } 108 | function displayContours() { 109 | if (config.withContours) { 110 | canvas_contours.style.display = "block" 111 | canvas_contours.width = canvas_contours.width 112 | slic.showContours(context_contours) 113 | } else { 114 | canvas_contours.style.display = "none" 115 | } 116 | } 117 | 118 | function dealImg(img) { 119 | canvas.width = img.width 120 | canvas.height = img.height 121 | canvas.style.width = img.width + "px" 122 | canvas.style.height = img.height + "px" 123 | canvas.style.marginLeft = (-img.width / 2) + "px" 124 | canvas.style.marginTop = (-img.height / 2) + "px" 125 | 126 | canvas_centers.width = img.width 127 | canvas_centers.height = img.height 128 | canvas_centers.style.width = img.width + "px" 129 | canvas_centers.style.height = img.height + "px" 130 | canvas_centers.style.marginLeft = (-img.width / 2) + "px" 131 | canvas_centers.style.marginTop = (-img.height / 2) + "px" 132 | 133 | canvas_contours.width = img.width 134 | canvas_contours.height = img.height 135 | canvas_contours.style.width = img.width + "px" 136 | canvas_contours.style.height = img.height + "px" 137 | canvas_contours.style.marginLeft = (-img.width / 2) + "px" 138 | canvas_contours.style.marginTop = (-img.height / 2) + "px" 139 | 140 | context.drawImage(img, 0, 0, canvas.width, canvas.height) 141 | 142 | let canvasData = context.getImageData(0, 0, canvas.width, canvas.height) 143 | let binaryData = canvasData.data 144 | let nr_superpixels = 500 145 | config.blockSize = padtext.blockSize = Math.round(Math.sqrt((canvas.width * canvas.height) / nr_superpixels)) 146 | console.log("blockSize: ", padtext.blockSize) 147 | slic = new SLIC(binaryData, canvas.width, canvas.height) 148 | pixelImage = slic.pixelDeal(config.blockSize, config.iters, config.stride, config.weight) 149 | displayImg() 150 | 151 | } 152 | 153 | 154 | function initGUI() { 155 | //GUI 156 | var padText = function () { 157 | this['Upload Image'] = function () { 158 | console.log("upload image") 159 | filedom.click() 160 | } 161 | this.blockSize = config.blockSize 162 | this.weight = config.weight 163 | this.iters = config.iters 164 | this.stride = config.stride 165 | this.grid = config.withGrid 166 | this.Centers = config.withCenters 167 | this.Contours = config.withContours 168 | this['Export image'] = function () { 169 | 170 | var MIME_TYPE = filetype 171 | var imgURL = canvas.toDataURL(filetype) 172 | var link = document.createElement('a') 173 | link.download = filename 174 | link.href = imgURL 175 | link.dataset.downloadurl = [MIME_TYPE, link.download, link.href].join(':') 176 | document.body.appendChild(link) 177 | link.click() 178 | document.body.removeChild(link) 179 | } 180 | } 181 | 182 | //GUI 183 | padtext = new padText() 184 | var gui = new dat.GUI() 185 | gui.add(padtext, 'Upload Image') 186 | 187 | 188 | // iters 189 | var iters_controller = gui.add(padtext, 'iters', 5, 20) 190 | iters_controller.onFinishChange(function (value) { 191 | console.log("new iters: ", Math.round(value)) 192 | if (slic == undefined) { 193 | alert("Upload image first") 194 | } 195 | else { 196 | pixelImage = slic.changeIters(Math.round(value)) 197 | displayImg() 198 | displayCenters() 199 | displayContours() 200 | 201 | } 202 | }) 203 | 204 | //stride for pixel 205 | var stride_controller = gui.add(padtext, 'stride', 5, 20) 206 | stride_controller.onFinishChange(function (value) { 207 | console.log("new stride: ", Math.round(value)) 208 | if (slic == undefined) { 209 | alert("Upload image first") 210 | } else { 211 | config.stride = Math.round(value) 212 | pixelImage = slic.changeStride(config.stride) 213 | displayImg() 214 | } 215 | }) 216 | 217 | //blocksize 218 | var blockSize_controller = gui.add(padtext, 'blockSize', 10, 30) 219 | blockSize_controller.listen() 220 | blockSize_controller.onFinishChange(function (value) { 221 | console.log("new blockSize: ", Math.round(value)) 222 | if (slic == undefined) { 223 | alert("Upload image first") 224 | } else { 225 | pixelImage = slic.changeBlockSize(Math.round(value)) 226 | displayImg() 227 | displayCenters() 228 | displayContours() 229 | } 230 | }) 231 | 232 | padtext.blockSize = 9 233 | 234 | //weight 235 | var weight_controller = gui.add(padtext, 'weight', 1, 40) 236 | weight_controller.onFinishChange(function (value) { 237 | console.log("new iters: ", Math.round(value)) 238 | if (slic == undefined) { 239 | alert("Upload image first") 240 | } 241 | else { 242 | pixelImage = slic.changeWeight(Math.round(value)) 243 | displayImg() 244 | displayCenters() 245 | displayContours() 246 | } 247 | }) 248 | 249 | padtext.weight = 8 250 | 251 | //grid 252 | var grid_controller = gui.add(padtext, 'grid') 253 | grid_controller.onFinishChange(function (value) { 254 | console.log(value) 255 | config.withGrid = value 256 | displayImg() 257 | }) 258 | 259 | //centers 260 | var centers_controller = gui.add(padtext, 'Centers') 261 | centers_controller.onFinishChange(function (value) { 262 | console.log(value) 263 | config.withCenters = value 264 | displayCenters(value) 265 | }) 266 | 267 | 268 | //contours 269 | var contours_controller = gui.add(padtext, 'Contours') 270 | contours_controller.onFinishChange(function (value) { 271 | console.log(value) 272 | config.withContours = value 273 | displayContours(value) 274 | }) 275 | 276 | //dowload img 277 | gui.add(padtext, 'Export image') 278 | 279 | 280 | // read file 281 | filedom.addEventListener("change", function (e) { 282 | let f = this.files[0] 283 | filename = f.name 284 | filetype = f.type 285 | if (!f.type.match("image.*")) { 286 | return 287 | } 288 | let reader = new FileReader() 289 | reader.onload = function (event) { 290 | let bytes = this.result 291 | let img = new Image() 292 | img.src = "" + bytes 293 | img.onload = function () { 294 | dealImg(img) 295 | } 296 | } 297 | reader.readAsDataURL(f) 298 | }) 299 | } 300 | 301 | function hidden(dom,flag) { 302 | if (flag) 303 | dom.className = 'hidden' 304 | else 305 | dom.className = '' 306 | } 307 | 308 | window.onload = function () { 309 | initGUI() 310 | hidden(loadingbox,false) 311 | let img = new Image() 312 | img.src = exampleImage 313 | img.onload = function () { 314 | dealImg(img) 315 | hidden(canvas,false) 316 | hidden(loadingbox,true) 317 | } 318 | 319 | } 320 | -------------------------------------------------------------------------------- /src/js/SLIC.js: -------------------------------------------------------------------------------- 1 | export default class SLIC { 2 | constructor(imageArray, width, height) { 3 | this.rgbImage = Uint8ClampedArray.from(imageArray) 4 | this.imageArray = Array.from(imageArray) 5 | this.width = width 6 | this.height = height 7 | console.log("Total pixel :", this.width * this.height) 8 | console.log("width :", width) 9 | console.log("height: ", height) 10 | } 11 | 12 | 13 | rgb2lab(sR, sG, sB) { 14 | //rgb2xyz 15 | let R = sR / 255 16 | let G = sG / 255 17 | let B = sB / 255 18 | 19 | let r, g, b 20 | if (R <= 0.04045) r = R / 12.92 21 | else r = Math.pow((R + 0.055) / 1.055, 2.4) 22 | if (G <= 0.04045) g = G / 12.92 23 | else g = Math.pow((G + 0.055) / 1.055, 2.4) 24 | if (B <= 0.04045) b = B / 12.92 25 | else b = Math.pow((B + 0.055) / 1.055, 2.4) 26 | 27 | let X, Y, Z 28 | X = r * 0.4124564 + g * 0.3575761 + b * 0.1804375 29 | Y = r * 0.2126729 + g * 0.7151522 + b * 0.0721750 30 | Z = r * 0.0193339 + g * 0.1191920 + b * 0.9503041 31 | 32 | //xyz2lab 33 | let epsilon = 0.008856 //actual CIE standard 34 | let kappa = 903.3 //actual CIE standard 35 | 36 | let Xr = 0.950456 //reference white 37 | let Yr = 1.0 //reference white 38 | let Zr = 1.088754 //reference white 39 | let xr = X / Xr 40 | let yr = Y / Yr 41 | let zr = Z / Zr 42 | 43 | let fx, fy, fz 44 | if (xr > epsilon) fx = Math.pow(xr, 1.0 / 3.0) 45 | else fx = (kappa * xr + 16.0) / 116.0 46 | if (yr > epsilon) fy = Math.pow(yr, 1.0 / 3.0) 47 | else fy = (kappa * yr + 16.0) / 116.0 48 | if (zr > epsilon) fz = Math.pow(zr, 1.0 / 3.0) 49 | else fz = (kappa * zr + 16.0) / 116.0 50 | 51 | let lval = 116.0 * fy - 16.0 52 | let aval = 500.0 * (fx - fy) 53 | let bval = 200.0 * (fy - fz) 54 | 55 | return { l: lval, a: aval, b: bval } 56 | } 57 | 58 | lab2rgb(sL, sA, sB) { 59 | 60 | } 61 | 62 | 63 | showCenters(ctx) { 64 | 65 | // let canvas = document.getElementById("canvas") 66 | // let ctx = canvas.getContext("2d") 67 | //ctx.fillStyle = "#FF0000" 68 | ctx.fillStyle = "#" + ("00000" + ((Math.random() * 16777215 + 0.5) >> 0).toString(16)).slice(-6) 69 | for (let i = 0; i < this.centers.length; i++) { 70 | //console.log(this.centers[i].x + " " + this.centers[i].y) 71 | ctx.fillRect(this.centers[i].y, this.centers[i].x, 5, 5) 72 | } 73 | } 74 | 75 | showContours(ctx) { 76 | let dx8 = [-1, -1, 0, 1, 1, 1, 0, -1] 77 | let dy8 = [0, -1, -1, -1, 0, 1, 1, 1] 78 | 79 | let contours = [] 80 | let istaken = Array.from({ length: this.height }).map(linearray => 81 | linearray = Array.from({ length: this.width }).map(item => item = false)) 82 | 83 | for (let i = 0; i < this.height; i++) { 84 | for (let j = 0; j < this.width; j++) { 85 | let nr_p = 0 86 | 87 | /* Compare the pixel to its 8 neighbours. */ 88 | for (let k = 0; k < 8; k++) { 89 | let x = i + dx8[k], y = j + dy8[k] 90 | 91 | if (x >= 0 && x < this.height && y >= 0 && y < this.width) { 92 | if (istaken[x][y] == false && this.clusterID[i * this.width + j] != this.clusterID[x * this.width + y]) { 93 | nr_p += 1 94 | } 95 | } 96 | } 97 | 98 | /* Add the pixel to the contour list if desired. */ 99 | if (nr_p >= 2) { 100 | contours.push({ 101 | x: i, 102 | y: j 103 | }) 104 | istaken[i][j] = true 105 | } 106 | } 107 | } 108 | for (let i = 0; i < contours.length; i++) { 109 | // let ctx = this.canvas.getContext("2d") 110 | ctx.fillStyle = "#ffffff" 111 | ctx.fillRect(contours[i].y, contours[i].x, 2, 2) 112 | } 113 | } 114 | 115 | 116 | findLocalMinimum(hpos, wpos) { 117 | let min_grad = Number.MAX_VALUE 118 | let loc_min = {} 119 | 120 | for (let i = hpos - 1; i <= hpos + 1 && i >= 0 && i < this.height - 1; i++) { 121 | for (let j = wpos - 1; j <= wpos + 1 && j >= 0 && j < this.width - 1; j++) { 122 | let i1 = this.imageArray[4 * (i * this.width + j + 1)]//right pixel 123 | let i2 = this.imageArray[4 * ((i + 1) * this.width + j + 1)] // bottom pixel 124 | let i3 = this.imageArray[4 * (i * this.width + j)] // self 125 | if (Math.sqrt(Math.pow(i1 - i3, 2)) + Math.sqrt(Math.pow(i2 - i3, 2)) < min_grad) { 126 | min_grad = Math.abs(i1 - i3) + Math.abs(i2 - i3) 127 | loc_min.x = i 128 | loc_min.y = j 129 | } 130 | } 131 | } 132 | return loc_min 133 | } 134 | 135 | computeDist(centerPos, pixX, pixY) { 136 | // if(pixX <=2) 137 | // console.log(pixX, pixY) 138 | 139 | let center = this.centers[centerPos] 140 | // let v1=Math.pow(center.l - this.image[pixX][pixY][0],2) 141 | // let v2=Math.pow(center.a - this.image[pixX][pixY][1],2) 142 | // let v3=Math.pow(center.b - this.image[pixX][pixY][2],2) 143 | 144 | // let temp=(Math.pow(center.l - this.image[pixX][pixY][0],2) + Math.pow(center.a - this.image[pixX][pixY][1],2)+ Math.pow(center.b - this.image[pixX][pixY][2],2)) 145 | 146 | let dc = Math.sqrt(Math.pow(center.l - this.imageArray[4 * (pixX * this.width + pixY)], 2) 147 | + Math.pow(center.a - this.imageArray[4 * (pixX * this.width + pixY) + 1], 2) 148 | + Math.pow(center.b - this.imageArray[4 * (pixX * this.width + pixY) + 2], 2)) 149 | let ds = Math.sqrt(Math.pow(center.x - pixX, 2) + Math.pow(center.y - pixY, 2)) 150 | 151 | return Math.pow(dc / this.weight, 2) + Math.pow(ds / this.step, 2) 152 | } 153 | 154 | computePixel() { 155 | console.log("computing.............................") 156 | //Initialize cluster centers by sampling pixels at regualr grid step 157 | this.clusterID = Array.from({ length: this.width * this.height }).map(item => item = -1) 158 | this.centers = new Array() 159 | 160 | for (let i = this.step; i < this.height; i += this.step) { 161 | for (let j = this.step; j < this.width; j += this.step) { 162 | let center = this.findLocalMinimum(i, j) 163 | center.l = (this.imageArray)[4 * (center.x * this.width + center.y)] 164 | center.a = (this.imageArray)[4 * (center.x * this.width + center.y) + 1] 165 | center.b = (this.imageArray)[4 * (center.x * this.width + center.y) + 2] 166 | this.centers.push(center) 167 | } 168 | } 169 | 170 | //Interations 171 | for (let i = 0; i < this.iters; i++) { 172 | // minimum distance to centers 173 | let distances = Array.from({ length: this.width * this.height }).map(item => item = Number.MAX_VALUE) 174 | 175 | for (let j = 0; j < this.centers.length; j++) { 176 | for (let m = this.centers[j].x - this.step; m < this.centers[j].x + this.step; m++) { 177 | for (let n = this.centers[j].y - this.step; n < this.centers[j].y + this.step; n++) { 178 | if (m >= 0 && m < this.height && n >= 0 && n < this.width) { 179 | //console.log(this.centers[j].x, this.centers[j].y, intStep) 180 | let d = this.computeDist(j, m, n) 181 | if (d < distances[m * this.width + n]) { 182 | distances[m * this.width + n] = d 183 | this.clusterID[m * this.width + n] = j 184 | } 185 | } 186 | } 187 | } 188 | } 189 | 190 | 191 | let oldcenters = JSON.parse(JSON.stringify(this.centers)) 192 | //clear old value 193 | for (var ele of this.centers) { 194 | ele.c = ele.l = ele.a = ele.b = ele.x = ele.y = 0 195 | } 196 | 197 | //compute new cluster centers 198 | 199 | for (let j = 0; j < this.height; j++) 200 | for (let k = 0; k < this.width; k++) { 201 | let c = this.clusterID[j * this.width + k] 202 | if (c != -1) { 203 | this.centers[c].l += this.imageArray[4 * (j * this.width + k)] 204 | this.centers[c].a += this.imageArray[4 * (j * this.width + k) + 1] 205 | this.centers[c].b += this.imageArray[4 * (j * this.width + k) + 2] 206 | this.centers[c].x += j 207 | this.centers[c].y += k 208 | this.centers[c].c += 1 209 | } 210 | } 211 | 212 | for (var index in this.centers) { 213 | if (this.centers[index].c == 0 || this.centers[index].x == undefined || this.centers[index].y == undefined) { 214 | // this.centers[index]= JSON.parse(JSON.stringify(oldcenters[index])) 215 | // console.log("--") 216 | // console.log(index,this.centers[index].c,this.centers[index].x,this.centers[index].y) 217 | this.centers[index] = JSON.parse(JSON.stringify(oldcenters[index])) 218 | // console.log(index,this.centers[index].c,this.centers[index].x,this.centers[index].y) 219 | 220 | let canvas = document.getElementById("canvas") 221 | let context = canvas.getContext("2d") 222 | context.fillRect(this.centers[index].y, this.centers[index].x, 10, 10) 223 | } 224 | else { 225 | this.centers[index].l /= this.centers[index].c 226 | this.centers[index].a /= this.centers[index].c 227 | this.centers[index].b /= this.centers[index].c 228 | this.centers[index].x = Math.floor(this.centers[index].x / this.centers[index].c) 229 | this.centers[index].y = Math.floor(this.centers[index].y / this.centers[index].c) 230 | } 231 | } 232 | } 233 | console.log("compute done.............................") 234 | } 235 | 236 | pickPixel() { 237 | console.log("paiting...................") 238 | // pick pixel 239 | let row = Math.ceil(this.height / this.stride) 240 | let col = Math.ceil(this.width / this.stride) 241 | let resultImage = new Uint8ClampedArray(this.width * this.height * 4) 242 | 243 | // iteration for every pix rectangle 244 | for (let m = 0; m < row; m++) { 245 | for (let n = 0; n < col; n++) { 246 | 247 | let startj = m * this.stride 248 | let startk = n * this.stride 249 | let counts = {} 250 | 251 | for (let j = startj; j < startj + this.stride && j < this.height; j++) { 252 | for (let k = startk; k < startk + this.stride && k < this.width; k++) { 253 | let c = this.clusterID[j * this.width + k] 254 | if (c != -1) { 255 | if (counts[c]) { 256 | counts[c]++ 257 | } else { 258 | counts[c] = 1 259 | } 260 | } 261 | } 262 | } 263 | let centerpos = -1 264 | let max = Number.MIN_VALUE 265 | for (let pos in counts) { 266 | if (counts[pos] > max) { 267 | max = counts[pos] 268 | centerpos = pos 269 | } 270 | } 271 | 272 | for (let j = startj; j < startj + this.stride && j < this.height; j++) { 273 | for (let k = startk; k < startk + this.stride && k < this.width; k++) { 274 | resultImage[4 * (j * this.width + k)] = this.rgbImage[4 * (this.centers[centerpos].x * this.width + this.centers[centerpos].y)] 275 | resultImage[4 * (j * this.width + k) + 1] = this.rgbImage[4 * (this.centers[centerpos].x * this.width + this.centers[centerpos].y) + 1] 276 | resultImage[4 * (j * this.width + k) + 2] = this.rgbImage[4 * (this.centers[centerpos].x * this.width + this.centers[centerpos].y) + 2] 277 | resultImage[4 * (j * this.width + k) + 3] = this.rgbImage[4 * (this.centers[centerpos].x * this.width + this.centers[centerpos].y) + 3] 278 | } 279 | } 280 | } 281 | } 282 | console.log("paiting done...................") 283 | return resultImage 284 | } 285 | 286 | //pixelate image 287 | pixelDeal(step, iters, stride, weight) { 288 | this.step = step 289 | this.iters = iters 290 | this.stride = stride 291 | this.weight = weight 292 | console.log("step :", step) 293 | console.log("iters :", iters) 294 | console.log("weight :", weight) 295 | console.log("stride :", stride) 296 | 297 | //tranlate rgb to lab 298 | for (let i = 0; i < this.width * this.height; i += 4) { 299 | let labColor = this.rgb2lab(this.imageArray[i], this.imageArray[i + 1], this.imageArray[i + 2]) 300 | this.imageArray[i] = labColor.l 301 | this.imageArray[i + 2] = labColor.a 302 | this.imageArray[i + 3] = labColor.b 303 | } 304 | this.computePixel() 305 | let result = this.pickPixel() 306 | 307 | return result 308 | } 309 | changeBlockSize(blockSize) { 310 | this.step = blockSize 311 | this.computePixel() 312 | let result = this.pickPixel() 313 | return result 314 | } 315 | changeWeight(weight) { 316 | this.weight = weight 317 | this.computePixel() 318 | let result = this.pickPixel() 319 | return result 320 | } 321 | changeStride(stride) { 322 | this.stride = stride 323 | let result = this.pickPixel() 324 | return result 325 | } 326 | changeIters(iters) { 327 | this.iters = iters 328 | this.computePixel() 329 | let result = this.pickPixel() 330 | return result 331 | } 332 | 333 | 334 | } -------------------------------------------------------------------------------- /src/js/dat.gui.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dat-gui JavaScript Controller Library 3 | * http://code.google.com/p/dat-gui 4 | * 5 | * Copyright 2011 Data Arts Team, Google Creative Lab 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | */ 13 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e.dat={})}(this,function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),o=Math.round(e.r),i=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+o+","+i+","+r+")":"CSS_RGBA"===n?"rgba("+o+","+i+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+o+","+i+","+r+"]":"RGBA_ARRAY"===n?"["+o+","+i+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+o+",g:"+i+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space?this.__state[t]:(I.recalculateRGB(this,t,n),this.__state[t])},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function o(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space?this.__state[t]:(I.recalculateHSV(this),this.__state[t])},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function i(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(U);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return t.indexOf(".")>-1?t.length-t.indexOf(".")-1:0}function s(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}function a(e,t,n,o,i){return o+(e-t)/(n-t)*(i-o)}function l(e,t,n,o){e.style.background="",S.each(ee,function(i){e.style.cssText+="background: "+i+"linear-gradient("+t+", "+n+" 0%, "+o+" 100%); "})}function d(e){e.style.background="",e.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);",e.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);",e.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}function c(e,t,n){var o=document.createElement("li");return t&&o.appendChild(t),n?e.__ul.insertBefore(o,n):e.__ul.appendChild(o),e.onResize(),o}function u(e){X.unbind(window,"resize",e.__resizeHandler),e.saveToLocalStorageIfPossible&&X.unbind(window,"unload",e.saveToLocalStorageIfPossible)}function _(e,t){var n=e.__preset_select[e.__preset_select.selectedIndex];n.innerHTML=t?n.value+"*":n.value}function h(e,t,n){if(n.__li=t,n.__gui=e,S.extend(n,{options:function(t){if(arguments.length>1){var o=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:o,factoryArgs:[S.toArray(arguments)]})}if(S.isArray(t)||S.isObject(t)){var i=n.__li.nextElementSibling;return n.remove(),f(e,n.object,n.property,{before:i,factoryArgs:[t]})}},name:function(e){return n.__li.firstElementChild.firstElementChild.innerHTML=e,n},listen:function(){return n.__gui.listen(n),n},remove:function(){return n.__gui.remove(n),n}}),n instanceof q){var o=new Q(n.object,n.property,{min:n.__min,max:n.__max,step:n.__step});S.each(["updateDisplay","onChange","onFinishChange","step","min","max"],function(e){var t=n[e],i=o[e];n[e]=o[e]=function(){var e=Array.prototype.slice.call(arguments);return i.apply(o,e),t.apply(n,e)}}),X.addClass(t,"has-slider"),n.domElement.insertBefore(o.domElement,n.domElement.firstElementChild)}else if(n instanceof Q){var i=function(t){if(S.isNumber(n.__min)&&S.isNumber(n.__max)){var o=n.__li.firstElementChild.firstElementChild.innerHTML,i=n.__gui.__listening.indexOf(n)>-1;n.remove();var r=f(e,n.object,n.property,{before:n.__li.nextElementSibling,factoryArgs:[n.__min,n.__max,n.__step]});return r.name(o),i&&r.listen(),r}return t};n.min=S.compose(i,n.min),n.max=S.compose(i,n.max)}else n instanceof K?(X.bind(t,"click",function(){X.fakeEvent(n.__checkbox,"click")}),X.bind(n.__checkbox,"click",function(e){e.stopPropagation()})):n instanceof Z?(X.bind(t,"click",function(){X.fakeEvent(n.__button,"click")}),X.bind(t,"mouseover",function(){X.addClass(n.__button,"hover")}),X.bind(t,"mouseout",function(){X.removeClass(n.__button,"hover")})):n instanceof $&&(X.addClass(t,"color"),n.updateDisplay=S.compose(function(e){return t.style.borderLeftColor=n.__color.toString(),e},n.updateDisplay),n.updateDisplay());n.setValue=S.compose(function(t){return e.getRoot().__preset_select&&n.isModified()&&_(e.getRoot(),!0),t},n.setValue)}function p(e,t){var n=e.getRoot(),o=n.__rememberedObjects.indexOf(t.object);if(-1!==o){var i=n.__rememberedObjectIndecesToControllers[o];if(void 0===i&&(i={},n.__rememberedObjectIndecesToControllers[o]=i),i[t.property]=t,n.load&&n.load.remembered){var r=n.load.remembered,s=void 0;if(r[e.preset])s=r[e.preset];else{if(!r[se])return;s=r[se]}if(s[o]&&void 0!==s[o][t.property]){var a=s[o][t.property];t.initialValue=a,t.setValue(a)}}}}function f(e,t,n,o){if(void 0===t[n])throw new Error('Object "'+t+'" has no property "'+n+'"');var i=void 0;if(o.color)i=new $(t,n);else{var r=[t,n].concat(o.factoryArgs);i=ne.apply(e,r)}o.before instanceof z&&(o.before=o.before.__li),p(e,i),X.addClass(i.domElement,"c");var s=document.createElement("span");X.addClass(s,"property-name"),s.innerHTML=i.property;var a=document.createElement("div");a.appendChild(s),a.appendChild(i.domElement);var l=c(e,a,o.before);return X.addClass(l,he.CLASS_CONTROLLER_ROW),i instanceof $?X.addClass(l,"color"):X.addClass(l,H(i.getValue())),h(e,l,i),e.__controllers.push(i),i}function m(e,t){return document.location.href+"."+t}function g(e,t,n){var o=document.createElement("option");o.innerHTML=t,o.value=t,e.__preset_select.appendChild(o),n&&(e.__preset_select.selectedIndex=e.__preset_select.length-1)}function b(e,t){t.style.display=e.useLocalStorage?"block":"none"}function v(e){var t=e.__save_row=document.createElement("li");X.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),X.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",X.addClass(n,"button gears");var o=document.createElement("span");o.innerHTML="Save",X.addClass(o,"button"),X.addClass(o,"save");var i=document.createElement("span");i.innerHTML="New",X.addClass(i,"button"),X.addClass(i,"save-as");var r=document.createElement("span");r.innerHTML="Revert",X.addClass(r,"button"),X.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){g(e,n,n===e.preset)}):g(e,se,!1),X.bind(s,"change",function(){for(var t=0;t=0;n--)t=[e[n].apply(this,t)];return t[0]}},each:function(e,t,n){if(e)if(A&&e.forEach&&e.forEach===A)e.forEach(t,n);else if(e.length===e.length+0){var o=void 0,i=void 0;for(o=0,i=e.length;o1?S.toArray(arguments):arguments[0];return S.each(O,function(t){if(t.litmus(e))return S.each(t.conversions,function(t,n){if(T=t.read(e),!1===L&&!1!==T)return L=T,T.conversionName=n,T.conversion=t,S.BREAK}),S.BREAK}),L},B=void 0,N={hsv_to_rgb:function(e,t,n){var o=Math.floor(e/60)%6,i=e/60-Math.floor(e/60),r=n*(1-t),s=n*(1-i*t),a=n*(1-(1-i)*t),l=[[n,a,r],[s,n,r],[r,n,a],[r,s,n],[a,r,n],[n,r,s]][o];return{r:255*l[0],g:255*l[1],b:255*l[2]}},rgb_to_hsv:function(e,t,n){var o=Math.min(e,t,n),i=Math.max(e,t,n),r=i-o,s=void 0,a=void 0;return 0===i?{h:NaN,s:0,v:0}:(a=r/i,s=e===i?(t-n)/r:t===i?2+(n-e)/r:4+(e-t)/r,(s/=6)<0&&(s+=1),{h:360*s,s:a,v:i/255})},rgb_to_hex:function(e,t,n){var o=this.hex_with_component(0,2,e);return o=this.hex_with_component(o,1,t),o=this.hex_with_component(o,0,n)},component_from_hex:function(e,t){return e>>8*t&255},hex_with_component:function(e,t,n){return n<<(B=8*t)|e&~(255<this.__max&&(n=this.__max),void 0!==this.__step&&n%this.__step!=0&&(n=Math.round(n/this.__step)*this.__step),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"setValue",this).call(this,n)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),t}(),Q=function(e){function t(e,n,o){function i(){l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())}function r(e){var t=d-e.clientY;l.setValue(l.getValue()+t*l.__impliedStep),d=e.clientY}function s(){X.unbind(window,"mousemove",r),X.unbind(window,"mouseup",s),i()}F(this,t);var a=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,o));a.__truncationSuspended=!1;var l=a,d=void 0;return a.__input=document.createElement("input"),a.__input.setAttribute("type","text"),X.bind(a.__input,"change",function(){var e=parseFloat(l.__input.value);S.isNaN(e)||l.setValue(e)}),X.bind(a.__input,"blur",function(){i()}),X.bind(a.__input,"mousedown",function(e){X.bind(window,"mousemove",r),X.bind(window,"mouseup",s),d=e.clientY}),X.bind(a.__input,"keydown",function(e){13===e.keyCode&&(l.__truncationSuspended=!0,this.blur(),l.__truncationSuspended=!1,i())}),a.updateDisplay(),a.domElement.appendChild(a.__input),a}return D(t,W),P(t,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():s(this.getValue(),this.__precision),j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),q=function(e){function t(e,n,o,i,r){function s(e){e.preventDefault();var t=_.__background.getBoundingClientRect();return _.setValue(a(e.clientX,t.left,t.right,_.__min,_.__max)),!1}function l(){X.unbind(window,"mousemove",s),X.unbind(window,"mouseup",l),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}function d(e){var t=e.touches[0].clientX,n=_.__background.getBoundingClientRect();_.setValue(a(t,n.left,n.right,_.__min,_.__max))}function c(){X.unbind(window,"touchmove",d),X.unbind(window,"touchend",c),_.__onFinishChange&&_.__onFinishChange.call(_,_.getValue())}F(this,t);var u=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,{min:o,max:i,step:r})),_=u;return u.__background=document.createElement("div"),u.__foreground=document.createElement("div"),X.bind(u.__background,"mousedown",function(e){document.activeElement.blur(),X.bind(window,"mousemove",s),X.bind(window,"mouseup",l),s(e)}),X.bind(u.__background,"touchstart",function(e){1===e.touches.length&&(X.bind(window,"touchmove",d),X.bind(window,"touchend",c),d(e))}),X.addClass(u.__background,"slider"),X.addClass(u.__foreground,"slider-fg"),u.updateDisplay(),u.__background.appendChild(u.__foreground),u.domElement.appendChild(u.__background),u}return D(t,W),P(t,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",j(t.prototype.__proto__||Object.getPrototypeOf(t.prototype),"updateDisplay",this).call(this)}}]),t}(),Z=function(e){function t(e,n,o){F(this,t);var i=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n)),r=i;return i.__button=document.createElement("div"),i.__button.innerHTML=void 0===o?"Fire":o,X.bind(i.__button,"click",function(e){return e.preventDefault(),r.fire(),!1}),X.addClass(i.__button,"button"),i.domElement.appendChild(i.__button),i}return D(t,z),P(t,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),t}(),$=function(e){function t(e,n){function o(e){u(e),X.bind(window,"mousemove",u),X.bind(window,"touchmove",u),X.bind(window,"mouseup",r),X.bind(window,"touchend",r)}function i(e){_(e),X.bind(window,"mousemove",_),X.bind(window,"touchmove",_),X.bind(window,"mouseup",s),X.bind(window,"touchend",s)}function r(){X.unbind(window,"mousemove",u),X.unbind(window,"touchmove",u),X.unbind(window,"mouseup",r),X.unbind(window,"touchend",r),c()}function s(){X.unbind(window,"mousemove",_),X.unbind(window,"touchmove",_),X.unbind(window,"mouseup",s),X.unbind(window,"touchend",s),c()}function a(){var e=R(this.value);!1!==e?(p.__color.__state=e,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function c(){p.__onFinishChange&&p.__onFinishChange.call(p,p.__color.toOriginal())}function u(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__saturation_field.getBoundingClientRect(),n=e.touches&&e.touches[0]||e,o=n.clientX,i=n.clientY,r=(o-t.left)/(t.right-t.left),s=1-(i-t.top)/(t.bottom-t.top);return s>1?s=1:s<0&&(s=0),r>1?r=1:r<0&&(r=0),p.__color.v=s,p.__color.s=r,p.setValue(p.__color.toOriginal()),!1}function _(e){-1===e.type.indexOf("touch")&&e.preventDefault();var t=p.__hue_field.getBoundingClientRect(),n=1-((e.touches&&e.touches[0]||e).clientY-t.top)/(t.bottom-t.top);return n>1?n=1:n<0&&(n=0),p.__color.h=360*n,p.setValue(p.__color.toOriginal()),!1}F(this,t);var h=V(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n));h.__color=new I(h.getValue()),h.__temp=new I(0);var p=h;h.domElement=document.createElement("div"),X.makeSelectable(h.domElement,!1),h.__selector=document.createElement("div"),h.__selector.className="selector",h.__saturation_field=document.createElement("div"),h.__saturation_field.className="saturation-field",h.__field_knob=document.createElement("div"),h.__field_knob.className="field-knob",h.__field_knob_border="2px solid ",h.__hue_knob=document.createElement("div"),h.__hue_knob.className="hue-knob",h.__hue_field=document.createElement("div"),h.__hue_field.className="hue-field",h.__input=document.createElement("input"),h.__input.type="text",h.__input_textShadow="0 1px 1px ",X.bind(h.__input,"keydown",function(e){13===e.keyCode&&a.call(this)}),X.bind(h.__input,"blur",a),X.bind(h.__selector,"mousedown",function(){X.addClass(this,"drag").bind(window,"mouseup",function(){X.removeClass(p.__selector,"drag")})}),X.bind(h.__selector,"touchstart",function(){X.addClass(this,"drag").bind(window,"touchend",function(){X.removeClass(p.__selector,"drag")})});var f=document.createElement("div");return S.extend(h.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"}),S.extend(h.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:h.__field_knob_border+(h.__color.v<.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1}),S.extend(h.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1}),S.extend(h.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"}),S.extend(f.style,{width:"100%",height:"100%",background:"none"}),l(f,"top","rgba(0,0,0,0)","#000"),S.extend(h.__hue_field.style,{width:"15px",height:"100px",border:"1px solid #555",cursor:"ns-resize",position:"absolute",top:"3px",right:"3px"}),d(h.__hue_field),S.extend(h.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:h.__input_textShadow+"rgba(0,0,0,0.7)"}),X.bind(h.__saturation_field,"mousedown",o),X.bind(h.__saturation_field,"touchstart",o),X.bind(h.__field_knob,"mousedown",o),X.bind(h.__field_knob,"touchstart",o),X.bind(h.__hue_field,"mousedown",i),X.bind(h.__hue_field,"touchstart",i),h.__saturation_field.appendChild(f),h.__selector.appendChild(h.__field_knob),h.__selector.appendChild(h.__saturation_field),h.__selector.appendChild(h.__hue_field),h.__hue_field.appendChild(h.__hue_knob),h.domElement.appendChild(h.__input),h.domElement.appendChild(h.__selector),h.updateDisplay(),h}return D(t,z),P(t,[{key:"updateDisplay",value:function(){var e=R(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||this.__color.s>.5?255:0,o=255-n;S.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toHexString(),border:this.__field_knob_border+"rgb("+n+","+n+","+n+")"}),this.__hue_knob.style.marginTop=100*(1-this.__color.h/360)+"px",this.__temp.s=1,this.__temp.v=1,l(this.__saturation_field,"left","#fff",this.__temp.toHexString()),this.__input.value=this.__color.toString(),S.extend(this.__input.style,{backgroundColor:this.__color.toHexString(),color:"rgb("+n+","+n+","+n+")",textShadow:this.__input_textShadow+"rgba("+o+","+o+","+o+",.7)"})}}]),t}(),ee=["-moz-","-o-","-webkit-","-ms-",""],te={load:function(e,t){var n=t||document,o=n.createElement("link");o.type="text/css",o.rel="stylesheet",o.href=e,n.getElementsByTagName("head")[0].appendChild(o)},inject:function(e,t){var n=t||document,o=document.createElement("style");o.type="text/css",o.innerHTML=e;var i=n.getElementsByTagName("head")[0];try{i.appendChild(o)}catch(e){}}},ne=function(e,t){var n=e[t];return S.isArray(arguments[2])||S.isObject(arguments[2])?new Y(e,t,arguments[2]):S.isNumber(n)?S.isNumber(arguments[2])&&S.isNumber(arguments[3])?S.isNumber(arguments[4])?new q(e,t,arguments[2],arguments[3],arguments[4]):new q(e,t,arguments[2],arguments[3]):S.isNumber(arguments[4])?new Q(e,t,{min:arguments[2],max:arguments[3],step:arguments[4]}):new Q(e,t,{min:arguments[2],max:arguments[3]}):S.isString(n)?new J(e,t):S.isFunction(n)?new Z(e,t,""):S.isBoolean(n)?new K(e,t):null},oe=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(e){setTimeout(e,1e3/60)},ie=function(){function e(){F(this,e),this.backgroundElement=document.createElement("div"),S.extend(this.backgroundElement.style,{backgroundColor:"rgba(0,0,0,0.8)",top:0,left:0,display:"none",zIndex:"1000",opacity:0,WebkitTransition:"opacity 0.2s linear",transition:"opacity 0.2s linear"}),X.makeFullscreen(this.backgroundElement),this.backgroundElement.style.position="fixed",this.domElement=document.createElement("div"),S.extend(this.domElement.style,{position:"fixed",display:"none",zIndex:"1001",opacity:0,WebkitTransition:"-webkit-transform 0.2s ease-out, opacity 0.2s linear",transition:"transform 0.2s ease-out, opacity 0.2s linear"}),document.body.appendChild(this.backgroundElement),document.body.appendChild(this.domElement);var t=this;X.bind(this.backgroundElement,"click",function(){t.hide()})}return P(e,[{key:"show",value:function(){var e=this;this.backgroundElement.style.display="block",this.domElement.style.display="block",this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)",this.layout(),S.defer(function(){e.backgroundElement.style.opacity=1,e.domElement.style.opacity=1,e.domElement.style.webkitTransform="scale(1)"})}},{key:"hide",value:function(){var e=this,t=function t(){e.domElement.style.display="none",e.backgroundElement.style.display="none",X.unbind(e.domElement,"webkitTransitionEnd",t),X.unbind(e.domElement,"transitionend",t),X.unbind(e.domElement,"oTransitionEnd",t)};X.bind(this.domElement,"webkitTransitionEnd",t),X.bind(this.domElement,"transitionend",t),X.bind(this.domElement,"oTransitionEnd",t),this.backgroundElement.style.opacity=0,this.domElement.style.opacity=0,this.domElement.style.webkitTransform="scale(1.1)"}},{key:"layout",value:function(){this.domElement.style.left=window.innerWidth/2-X.getWidth(this.domElement)/2+"px",this.domElement.style.top=window.innerHeight/2-X.getHeight(this.domElement)/2+"px"}}]),e}(),re=function(e){if(e&&"undefined"!=typeof window){var t=document.createElement("style");return t.setAttribute("type","text/css"),t.innerHTML=e,document.head.appendChild(t),e}}(".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity .1s linear;-o-transition:opacity .1s linear;-moz-transition:opacity .1s linear;transition:opacity .1s linear;border:0;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button.close-top{position:relative}.dg.main .close-button.close-bottom{position:absolute}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-y:visible}.dg.a.has-save>ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{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;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n");te.inject(re);var se="Default",ae=function(){try{return!!window.localStorage}catch(e){return!1}}(),le=void 0,de=!0,ce=void 0,ue=!1,_e=[],he=function e(t){var n=this,o=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),X.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],o=S.defaults(o,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),o=S.defaults(o,{resizable:o.autoPlace,hideable:o.autoPlace}),S.isUndefined(o.load)?o.load={preset:se}:o.preset&&(o.load.preset=o.preset),S.isUndefined(o.parent)&&o.hideable&&_e.push(this),o.resizable=S.isUndefined(o.parent)&&o.resizable,o.autoPlace&&S.isUndefined(o.scrollable)&&(o.scrollable=!0);var i=ae&&"true"===localStorage.getItem(m(this,"isLocal")),r=void 0,s=void 0;if(Object.defineProperties(this,{parent:{get:function(){return o.parent}},scrollable:{get:function(){return o.scrollable}},autoPlace:{get:function(){return o.autoPlace}},closeOnTop:{get:function(){return o.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:o.load.preset},set:function(e){n.parent?n.getRoot().preset=e:o.load.preset=e,E(this),n.revert()}},width:{get:function(){return o.width},set:function(e){o.width=e,w(n,e)}},name:{get:function(){return o.name},set:function(e){o.name=e,s&&(s.innerHTML=o.name)}},closed:{get:function(){return o.closed},set:function(t){o.closed=t,o.closed?X.addClass(n.__ul,e.CLASS_CLOSED):X.removeClass(n.__ul,e.CLASS_CLOSED),this.onResize(),n.__closeButton&&(n.__closeButton.innerHTML=t?e.TEXT_OPEN:e.TEXT_CLOSED)}},load:{get:function(){return o.load}},useLocalStorage:{get:function(){return i},set:function(e){ae&&(i=e,e?X.bind(window,"unload",r):X.unbind(window,"unload",r),localStorage.setItem(m(n,"isLocal"),e))}}}),S.isUndefined(o.parent)){if(this.closed=o.closed||!1,X.addClass(this.domElement,e.CLASS_MAIN),X.makeSelectable(this.domElement,!1),ae&&i){n.useLocalStorage=!0;var a=localStorage.getItem(m(this,"gui"));a&&(o.load=JSON.parse(a))}this.__closeButton=document.createElement("div"),this.__closeButton.innerHTML=e.TEXT_CLOSED,X.addClass(this.__closeButton,e.CLASS_CLOSE_BUTTON),o.closeOnTop?(X.addClass(this.__closeButton,e.CLASS_CLOSE_TOP),this.domElement.insertBefore(this.__closeButton,this.domElement.childNodes[0])):(X.addClass(this.__closeButton,e.CLASS_CLOSE_BOTTOM),this.domElement.appendChild(this.__closeButton)),X.bind(this.__closeButton,"click",function(){n.closed=!n.closed})}else{void 0===o.closed&&(o.closed=!0);var l=document.createTextNode(o.name);X.addClass(l,"controller-name"),s=c(n,l);X.addClass(this.__ul,e.CLASS_CLOSED),X.addClass(s,"title"),X.bind(s,"click",function(e){return e.preventDefault(),n.closed=!n.closed,!1}),o.closed||(this.closed=!1)}o.autoPlace&&(S.isUndefined(o.parent)&&(de&&(ce=document.createElement("div"),X.addClass(ce,"dg"),X.addClass(ce,e.CLASS_AUTO_PLACE_CONTAINER),document.body.appendChild(ce),de=!1),ce.appendChild(this.domElement),X.addClass(this.domElement,e.CLASS_AUTO_PLACE)),this.parent||w(n,o.width)),this.__resizeHandler=function(){n.onResizeDebounced()},X.bind(window,"resize",this.__resizeHandler),X.bind(this.__ul,"webkitTransitionEnd",this.__resizeHandler),X.bind(this.__ul,"transitionend",this.__resizeHandler),X.bind(this.__ul,"oTransitionEnd",this.__resizeHandler),this.onResize(),o.resizable&&y(this),r=function(){ae&&"true"===localStorage.getItem(m(n,"isLocal"))&&localStorage.setItem(m(n,"gui"),JSON.stringify(n.getSaveObject()))},this.saveToLocalStorageIfPossible=r,o.parent||function(){var e=n.getRoot();e.width+=1,S.defer(function(){e.width-=1})}()};he.toggleHide=function(){ue=!ue,S.each(_e,function(e){e.domElement.style.display=ue?"none":""})},he.CLASS_AUTO_PLACE="a",he.CLASS_AUTO_PLACE_CONTAINER="ac",he.CLASS_MAIN="main",he.CLASS_CONTROLLER_ROW="cr",he.CLASS_TOO_TALL="taller-than-window",he.CLASS_CLOSED="closed",he.CLASS_CLOSE_BUTTON="close-button",he.CLASS_CLOSE_TOP="close-top",he.CLASS_CLOSE_BOTTOM="close-bottom",he.CLASS_DRAG="drag",he.DEFAULT_WIDTH=245,he.TEXT_CLOSED="Close Controls",he.TEXT_OPEN="Open Controls",he._keydownHandler=function(e){"text"===document.activeElement.type||72!==e.which&&72!==e.keyCode||he.toggleHide()},X.bind(window,"keydown",he._keydownHandler,!1),S.extend(he.prototype,{add:function(e,t){return f(this,e,t,{factoryArgs:Array.prototype.slice.call(arguments,2)})},addColor:function(e,t){return f(this,e,t,{color:!0})},remove:function(e){this.__ul.removeChild(e.__li),this.__controllers.splice(this.__controllers.indexOf(e),1);var t=this;S.defer(function(){t.onResize()})},destroy:function(){if(this.parent)throw new Error("Only the root GUI should be removed with .destroy(). For subfolders, use gui.removeFolder(folder) instead.");this.autoPlace&&ce.removeChild(this.domElement);var e=this;S.each(this.__folders,function(t){e.removeFolder(t)}),X.unbind(window,"keydown",he._keydownHandler,!1),u(this)},addFolder:function(e){if(void 0!==this.__folders[e])throw new Error('You already have a folder in this GUI by the name "'+e+'"');var t={name:e,parent:this};t.autoPlace=this.autoPlace,this.load&&this.load.folders&&this.load.folders[e]&&(t.closed=this.load.folders[e].closed,t.load=this.load.folders[e]);var n=new he(t);this.__folders[e]=n;var o=c(this,n.domElement);return X.addClass(o,"folder"),n},removeFolder:function(e){this.__ul.removeChild(e.domElement.parentElement),delete this.__folders[e.name],this.load&&this.load.folders&&this.load.folders[e.name]&&delete this.load.folders[e.name],u(e);var t=this;S.each(e.__folders,function(t){e.removeFolder(t)}),S.defer(function(){t.onResize()})},open:function(){this.closed=!1},close:function(){this.closed=!0},onResize:function(){var e=this.getRoot();if(e.scrollable){var t=X.getOffset(e.__ul).top,n=0;S.each(e.__ul.childNodes,function(t){e.autoPlace&&t===e.__save_row||(n+=X.getHeight(t))}),window.innerHeight-t-20GUI\'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'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&v(e),-1===e.__rememberedObjects.indexOf(t)&&e.__rememberedObjects.push(t)}),this.autoPlace&&w(this,this.width)},getRoot:function(){for(var e=this;e.parent;)e=e.parent;return e},getSaveObject:function(){var e=this.load;return e.closed=this.closed,this.__rememberedObjects.length>0&&(e.preset=this.preset,e.remembered||(e.remembered={}),e.remembered[this.preset]=x(this)),e.folders={},S.each(this.__folders,function(t,n){e.folders[n]=t.getSaveObject()}),e},save:function(){this.load.remembered||(this.load.remembered={}),this.load.remembered[this.preset]=x(this),_(this,!1),this.saveToLocalStorageIfPossible()},saveAs:function(e){this.load.remembered||(this.load.remembered={},this.load.remembered[se]=x(this,!0)),this.load.remembered[e]=x(this),this.preset=e,g(this,e,!0),this.saveToLocalStorageIfPossible()},revert:function(e){S.each(this.__controllers,function(t){this.getRoot().load.remembered?p(e||this.getRoot(),t):t.setValue(t.initialValue),t.__onFinishChange&&t.__onFinishChange.call(t,t.getValue())},this),S.each(this.__folders,function(e){e.revert(e)}),e||_(this.getRoot(),!1)},listen:function(e){var t=0===this.__listening.length;this.__listening.push(e),t&&C(this.__listening)},updateDisplay:function(){S.each(this.__controllers,function(e){e.updateDisplay()}),S.each(this.__folders,function(e){e.updateDisplay()})}});var pe={Color:I,math:N,interpret:R},fe={Controller:z,BooleanController:K,OptionController:Y,StringController:J,NumberController:W,NumberControllerBox:Q,NumberControllerSlider:q,FunctionController:Z,ColorController:$},me={dom:X},ge={GUI:he},be=he,ve={color:pe,controllers:fe,dom:me,gui:ge,GUI:be};e.color=pe,e.controllers=fe,e.dom=me,e.gui=ge,e.GUI=be,e.default=ve,Object.defineProperty(e,"__esModule",{value:!0})}); 14 | -------------------------------------------------------------------------------- /dist/app.bundle.js: -------------------------------------------------------------------------------- 1 | !function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=7)}([function(e,t,n){var i,o,r,s;function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}s=function(e){"use strict";function t(e,t){var n=e.__state.conversionName.toString(),i=Math.round(e.r),o=Math.round(e.g),r=Math.round(e.b),s=e.a,a=Math.round(e.h),l=e.s.toFixed(1),d=e.v.toFixed(1);if(t||"THREE_CHAR_HEX"===n||"SIX_CHAR_HEX"===n){for(var c=e.hex.toString(16);c.length<6;)c="0"+c;return"#"+c}return"CSS_RGB"===n?"rgb("+i+","+o+","+r+")":"CSS_RGBA"===n?"rgba("+i+","+o+","+r+","+s+")":"HEX"===n?"0x"+e.hex.toString(16):"RGB_ARRAY"===n?"["+i+","+o+","+r+"]":"RGBA_ARRAY"===n?"["+i+","+o+","+r+","+s+"]":"RGB_OBJ"===n?"{r:"+i+",g:"+o+",b:"+r+"}":"RGBA_OBJ"===n?"{r:"+i+",g:"+o+",b:"+r+",a:"+s+"}":"HSV_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+"}":"HSVA_OBJ"===n?"{h:"+a+",s:"+l+",v:"+d+",a:"+s+"}":"unknown format"}function n(e,t,n){Object.defineProperty(e,t,{get:function(){return"RGB"===this.__state.space||I.recalculateRGB(this,t,n),this.__state[t]},set:function(e){"RGB"!==this.__state.space&&(I.recalculateRGB(this,t,n),this.__state.space="RGB"),this.__state[t]=e}})}function i(e,t){Object.defineProperty(e,t,{get:function(){return"HSV"===this.__state.space||I.recalculateHSV(this),this.__state[t]},set:function(e){"HSV"!==this.__state.space&&(I.recalculateHSV(this),this.__state.space="HSV"),this.__state[t]=e}})}function o(e){if("0"===e||S.isUndefined(e))return 0;var t=e.match(z);return S.isNull(t)?0:parseFloat(t[1])}function r(e){var t=e.toString();return-1>8*t&255},hex_with_component:function(e,t,n){return n<<(R=8*t)|e&~(255<this.__max&&(t=this.__max),void 0!==this.__step&&t%this.__step!=0&&(t=Math.round(t/this.__step)*this.__step),w(ae.prototype.__proto__||Object.getPrototypeOf(ae.prototype),"setValue",this).call(this,t)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),ae),K=(x(se,W),N(se,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():function(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}(this.getValue(),this.__precision),w(se.prototype.__proto__||Object.getPrototypeOf(se.prototype),"updateDisplay",this).call(this)}}]),se),Y=(x(re,W),N(re,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",w(re.prototype.__proto__||Object.getPrototypeOf(re.prototype),"updateDisplay",this).call(this)}}]),re),Q=(x(oe,F),N(oe,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),oe),q=(x(ie,F),N(ie,[{key:"updateDisplay",value:function(){var e=v(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||.5ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{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;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n"));var ue="Default",he=function(){try{return!!window.localStorage}catch(e){return!1}}(),fe=void 0,pe=!0,_e=void 0,me=!1,ge=[],be=function e(t){var n=this,i=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),V.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],i=S.defaults(i,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),i=S.defaults(i,{resizable:i.autoPlace,hideable:i.autoPlace}),S.isUndefined(i.load)?i.load={preset:ue}:i.preset&&(i.load.preset=i.preset),S.isUndefined(i.parent)&&i.hideable&&ge.push(this),i.resizable=S.isUndefined(i.parent)&&i.resizable,i.autoPlace&&S.isUndefined(i.scrollable)&&(i.scrollable=!0);var o,r=he&&"true"===localStorage.getItem(p(0,"isLocal")),s=void 0,a=void 0;if(Object.defineProperties(this,{parent:{get:function(){return i.parent}},scrollable:{get:function(){return i.scrollable}},autoPlace:{get:function(){return i.autoPlace}},closeOnTop:{get:function(){return i.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:i.load.preset},set:function(e){n.parent?n.getRoot().preset=e:i.load.preset=e,function(e){for(var t=0;tGUI\'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'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&function(e){var t=e.__save_row=document.createElement("li");V.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),V.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",V.addClass(n,"button gears");var i=document.createElement("span");i.innerHTML="Save",V.addClass(i,"button"),V.addClass(i,"save");var o=document.createElement("span");o.innerHTML="New",V.addClass(o,"button"),V.addClass(o,"save-as");var r=document.createElement("span");r.innerHTML="Revert",V.addClass(r,"button"),V.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){_(e,n,n===e.preset)}):_(e,ue,!1),V.bind(s,"change",function(){for(var t=0;t>0).toString(16)).slice(-6);for(var t=0;th&&(h=a[f],u=f);for(var p=r;p>8*t&255},hex_with_component:function(e,t,n){return n<<(R=8*t)|e&~(255<this.__max&&(t=this.__max),void 0!==this.__step&&t%this.__step!=0&&(t=Math.round(t/this.__step)*this.__step),w(ae.prototype.__proto__||Object.getPrototypeOf(ae.prototype),"setValue",this).call(this,t)}},{key:"min",value:function(e){return this.__min=e,this}},{key:"max",value:function(e){return this.__max=e,this}},{key:"step",value:function(e){return this.__step=e,this.__impliedStep=e,this.__precision=r(e),this}}]),ae),K=(x(se,W),N(se,[{key:"updateDisplay",value:function(){return this.__input.value=this.__truncationSuspended?this.getValue():function(e,t){var n=Math.pow(10,t);return Math.round(e*n)/n}(this.getValue(),this.__precision),w(se.prototype.__proto__||Object.getPrototypeOf(se.prototype),"updateDisplay",this).call(this)}}]),se),Y=(x(re,W),N(re,[{key:"updateDisplay",value:function(){var e=(this.getValue()-this.__min)/(this.__max-this.__min);return this.__foreground.style.width=100*e+"%",w(re.prototype.__proto__||Object.getPrototypeOf(re.prototype),"updateDisplay",this).call(this)}}]),re),Q=(x(oe,F),N(oe,[{key:"fire",value:function(){this.__onChange&&this.__onChange.call(this),this.getValue().call(this.object),this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}}]),oe),q=(x(ie,F),N(ie,[{key:"updateDisplay",value:function(){var e=v(this.getValue());if(!1!==e){var t=!1;S.each(I.COMPONENTS,function(n){if(!S.isUndefined(e[n])&&!S.isUndefined(this.__color.__state[n])&&e[n]!==this.__color.__state[n])return t=!0,{}},this),t&&S.extend(this.__color.__state,e)}S.extend(this.__temp.__state,this.__color.__state),this.__temp.a=1;var n=this.__color.v<.5||.5ul.close-top{margin-top:0}.dg.a.has-save>ul.close-bottom{margin-top:27px}.dg.a.has-save>ul.closed{margin-top:0}.dg.a .save-row{top:0;z-index:1002}.dg.a .save-row.close-top{position:relative}.dg.a .save-row.close-bottom{position:fixed}.dg li{-webkit-transition:height .1s ease-out;-o-transition:height .1s ease-out;-moz-transition:height .1s ease-out;transition:height .1s ease-out;-webkit-transition:overflow .1s linear;-o-transition:overflow .1s linear;-moz-transition:overflow .1s linear;transition:overflow .1s linear}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li>*{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px;overflow:hidden}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%;position:relative}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:7px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .cr.color{overflow:visible}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{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;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.color{border-left:3px solid}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2FA1D6}.dg .cr.number input[type=text]{color:#2FA1D6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2FA1D6;max-width:100%}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n"));var ue="Default",he=function(){try{return!!window.localStorage}catch(e){return!1}}(),fe=void 0,pe=!0,_e=void 0,me=!1,ge=[],be=function e(t){var n=this,i=t||{};this.domElement=document.createElement("div"),this.__ul=document.createElement("ul"),this.domElement.appendChild(this.__ul),V.addClass(this.domElement,"dg"),this.__folders={},this.__controllers=[],this.__rememberedObjects=[],this.__rememberedObjectIndecesToControllers=[],this.__listening=[],i=S.defaults(i,{closeOnTop:!1,autoPlace:!0,width:e.DEFAULT_WIDTH}),i=S.defaults(i,{resizable:i.autoPlace,hideable:i.autoPlace}),S.isUndefined(i.load)?i.load={preset:ue}:i.preset&&(i.load.preset=i.preset),S.isUndefined(i.parent)&&i.hideable&&ge.push(this),i.resizable=S.isUndefined(i.parent)&&i.resizable,i.autoPlace&&S.isUndefined(i.scrollable)&&(i.scrollable=!0);var o,r=he&&"true"===localStorage.getItem(p(0,"isLocal")),s=void 0,a=void 0;if(Object.defineProperties(this,{parent:{get:function(){return i.parent}},scrollable:{get:function(){return i.scrollable}},autoPlace:{get:function(){return i.autoPlace}},closeOnTop:{get:function(){return i.closeOnTop}},preset:{get:function(){return n.parent?n.getRoot().preset:i.load.preset},set:function(e){n.parent?n.getRoot().preset=e:i.load.preset=e,function(e){for(var t=0;tGUI\'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'),this.parent)throw new Error("You can only call remember on a top level GUI.");var e=this;S.each(Array.prototype.slice.call(arguments),function(t){0===e.__rememberedObjects.length&&function(e){var t=e.__save_row=document.createElement("li");V.addClass(e.domElement,"has-save"),e.__ul.insertBefore(t,e.__ul.firstChild),V.addClass(t,"save-row");var n=document.createElement("span");n.innerHTML=" ",V.addClass(n,"button gears");var i=document.createElement("span");i.innerHTML="Save",V.addClass(i,"button"),V.addClass(i,"save");var o=document.createElement("span");o.innerHTML="New",V.addClass(o,"button"),V.addClass(o,"save-as");var r=document.createElement("span");r.innerHTML="Revert",V.addClass(r,"button"),V.addClass(r,"revert");var s=e.__preset_select=document.createElement("select");if(e.load&&e.load.remembered?S.each(e.load.remembered,function(t,n){_(e,n,n===e.preset)}):_(e,ue,!1),V.bind(s,"change",function(){for(var t=0;t>0).toString(16)).slice(-6);for(var t=0;th&&(h=a[f],u=f);for(var p=r;p