diff options
| author | Jules Laplace <jules@okfoc.us> | 2014-08-26 18:59:24 -0400 |
|---|---|---|
| committer | Jules Laplace <jules@okfoc.us> | 2014-08-26 18:59:24 -0400 |
| commit | 2bf7351025b29d1bc8ec2e5792dcb0532c4deb95 (patch) | |
| tree | 5f882097bac55fdd9a9f32e8eb80373d16073bd9 | |
| parent | ebc00f78cedc7712686af353225bb5d418b5b2d4 (diff) | |
color picker thingie
| -rw-r--r-- | public/assets/javascripts/rectangles/models/wall.js | 70 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/editor/LightControl.js | 262 | ||||
| -rw-r--r-- | public/assets/javascripts/ui/editor/WallpaperPicker.js | 4 | ||||
| -rw-r--r-- | public/assets/javascripts/util.js | 5 | ||||
| -rwxr-xr-x | public/assets/stylesheets/app.css | 61 | ||||
| -rw-r--r-- | views/controls/editor/light-control.ejs | 13 |
6 files changed, 339 insertions, 76 deletions
diff --git a/public/assets/javascripts/rectangles/models/wall.js b/public/assets/javascripts/rectangles/models/wall.js index 8723c3c..1dd0ebf 100644 --- a/public/assets/javascripts/rectangles/models/wall.js +++ b/public/assets/javascripts/rectangles/models/wall.js @@ -82,7 +82,16 @@ } }) }) - this.outline() + + // flip the mx order + var shouldFlip = this.side & (LEFT | BACK) + if (! shouldFlip) { + this.mx.reverse() + } + + var wallColor = "rgba(255,255,255,0.95)" + var outlineColor = "rgba(0,0,0,1.0)" + this.outline(wallColor, outlineColor) } @@ -207,44 +216,39 @@ }) } - Wall.prototype.outline = function(){ + Wall.prototype.outline = function(wallColor, outlineColor){ var useX = this.side & FRONT_BACK - var shouldFlip = this.side & (LEFT | BACK) var mx = this.mx - if (! shouldFlip) { - mx = mx.reverse() - } - var len = this.mx.length - - var backgroundColor = "rgba(255,255,255,0.95)" - var borderColor = "rgba(0,0,0,1.0)" - - zz = window.zz || 0 + var outlineString = "1px solid " + outlineColor + zz = 0 mx.forEach(function(mx, i){ - if (mx.outlined) return - mx.outlined = true - mx.el.style.backgroundColor = backgroundColor - - // all walls get bottom lines - mx.el.style.borderBottom = "1px solid " + borderColor - - // all walls get top lines - mx.el.style.borderTop = "1px solid " + borderColor - - // walls on initial sides get left lines - // if their left edge lines up with the rect edge - if (i == 0) { - mx.el.style.borderLeft = "1px solid " + borderColor - } - - // walls on terminal sides get right lines.... - // if their right edge lines up with the rect edge - if (i == len-1) { - mx.el.style.borderRight = "1px solid " + borderColor - } + // if (mx.outlined) return + // mx.outlined = true + if (wallColor) { + mx.el.style.backgroundColor = wallColor + } + if (outlineColor) { + // all walls get bottom lines + mx.el.style.borderBottom = outlineString + + // all walls get top lines + mx.el.style.borderTop = outlineString + + // walls on initial sides get left lines + // if their left edge lines up with the rect edge + if (i == 0) { + mx.el.style.borderLeft = outlineString + } + + // walls on terminal sides get right lines.... + // if their right edge lines up with the rect edge + if (i == len-1) { + mx.el.style.borderRight = outlineString + } + } }) } diff --git a/public/assets/javascripts/ui/editor/LightControl.js b/public/assets/javascripts/ui/editor/LightControl.js index c3e80c2..b1c5b85 100644 --- a/public/assets/javascripts/ui/editor/LightControl.js +++ b/public/assets/javascripts/ui/editor/LightControl.js @@ -4,40 +4,254 @@ var LightControl = View.extend({ events: { "mousedown": "stopPropagation", + "click #wall-color": "editWallColor", + "click #outline-color": "editOutlineColor", + "click label": "clickLabel", + "input #shadow-control": "updateShadow", + "input #brightness-control": "updateBrightness", + "input #outline-hue": "updateShadow", + "input #wall-hue": "updateShadow", }, - + + initialize: function(){ + this.colorPicker = new LabColorPicker(this, 180, 180) + this.$el.prepend( this.colorPicker.canvas ) + + this.$wallSwatch = this.$("#wall-color") + this.$outlineSwatch = this.$("#outline-color") + this.$brightnessControl = this.$("#brightness-control") + + this.setMode("wall") + + this.setWallColor([255,255,255], false) + this.setOutlineColor([0,0,0]) + }, + toggle: function(state){ this.$el.toggleClass("active", state); - - // toggle the class that makes the cursor a paintbucket - // $("body").removeClass("pastePaper"); }, + show: function(){ this.toggle(true) }, + hide: function(){ this.toggle(false) }, + + pick: function(rgb, Lab){ + this.labColor = Lab + switch (this.mode) { + case "wall": + this.setWallColor(rgb) + break + case "outline": + this.setOutlineColor(rgb) + break + } + }, + + wallColor: [255,255,255], + outlineColor: [0,0,0], + + setMode: function (mode) { + var color, brightness + this.mode = mode + switch (mode) { + case "wall": + this.$wallSwatch.addClass("selected") + this.$outlineSwatch.removeClass("selected") + color = this.wallColor + break + case "outline": + this.$outlineSwatch.addClass("selected") + this.$wallSwatch.removeClass("selected") + color = this.outlineColor + break + } + this.labColor = this.colorPicker.load(color) + this.$brightnessControl.val( this.labColor[0] ) + }, + + clickLabel: function(e){ + $(e.currentTarget).prev(".swatch").trigger("click") + }, + editWallColor: function(){ + this.setMode("wall") + }, + editOutlineColor: function(){ + this.setMode("outline") + }, + + setWallColor: function(rgb, repaint){ + repaint = typeof repaint != "undefined" ? repaint : true + var rgbColor = rgb_string(rgb) + var rgbaColor = rgba_string(rgb, 0.95) + this.wallColor = rgb + this.$wallSwatch.css("background-color", rgbColor) + Rooms.walls.forEach(function(wall){ + wall.outline(rgbaColor, null) + }) + }, -/* - $("#shadow-control").on({ - mousedown: function(){ app.dragging = true }, - change: function(){ - var hex = (~~($(this).int() / 100 * 0xff)).toString(10) - if (hex.length == 1) hex = "0" + hex; - var color = "rgba(" + [hex, hex, hex, "1.0"] + ")" - $(".face").css("border-color", color) - } - }) - - $("#brightness-control").on({ - mousedown: function(){ app.dragging = true }, - change: function(){ - var hex = (~~($(this).int() / 100 * 0xff)).toString(10) - var color = "rgba(" + [hex, hex, hex, "0.9"] + ")" - $("body,.face").css("background-color", color) - } - }) -*/ + setOutlineColor: function(rgb){ + repaint = typeof repaint != "undefined" ? repaint : true + var rgbColor = rgb_string(rgb) + this.outlineColor = rgb + this.$outlineSwatch.css("background-color", rgbColor) + Rooms.walls.forEach(function(wall){ + wall.outline(null, rgbColor) + }) + }, + + updateBrightness: function(){ + this.labColor[0] = parseFloat( this.$brightnessControl.val() ) + var rgb = this.colorPicker.setLab( this.labColor ) + this.pick(rgb, this.labColor) + }, }) + +var LabColorPicker = function (parent, w, h) { + var base = this + var canvas = this.canvas = document.createElement('canvas') + var ctx = this.ctx = canvas.getContext('2d') + var imageData = ctx.createImageData(w,h) + var data = imageData.data + +// var cursor = this.cursor = document.createElement("div") +// cursor.className = "colorPickerCursor" + + canvas.width = w + canvas.height = h + canvas.className = "colorPicker" + + var down = false + + var ww = w-1 + var hh = h-1 + + var L_range = [0, 110] + var a_range = [-86.185, 98.254] + var b_range = [-107.863, 94.482] + + var rgb = [0,0,0] + + var val = 80 + + this.mouse = new mouse({ + el: canvas, + down: function(e, cursor){ + cursor.x.a = -cursor.x.a + base.pick(cursor.x.a, cursor.y.a) + }, + drag: function(e, cursor){ + cursor.x.b = -cursor.x.b + base.pick(cursor.x.b, cursor.y.b) + } + }) + + this.setLab = function(Lab) { + val = Lab[0] + this.paint() + var rgb = xyz2rgb(hunterlab2xyz(Lab[0], Lab[1], Lab[2])).map(Math.round) + return rgb + } + this.pick = function(i, j){ + var x = mix( i/ww, a_range[0], a_range[1] ) + var y = mix( j/hh, b_range[0], b_range[1] ) + var rgb = xyz2rgb(hunterlab2xyz(val, x, y)).map(Math.round) + parent.pick( rgb, [val,x,y] ) + } + this.load = function(rgba){ + var Lab = xyz2hunterlab(rgb2xyz(rgba)) + var val = clamp( Lab[0], L_range[0], L_range[1] ) + var x = mix( norm(Lab[1], a_range[0], a_range[1]), 0, ww ) + var y = mix( norm(Lab[2], b_range[0], b_range[1]), 0, hh ) + // move the cursor + this.setLab(Lab) + return Lab + } + this.paint = function() { + val = clamp(val, L_range[0], L_range[1]) + var x, y, t + for (var i = 0; i < w; i++) { + for (var j = 0; j < h; j++) { + x = mix( i/ww, a_range[0], a_range[1] ) + y = mix( j/hh, b_range[0], b_range[1] ) + t = (j*w + i) * 4 + rgb = xyz2rgb(hunterlab2xyz(val, x, y)) + data[t] = Math.round( rgb[0] ) + data[t+1] = Math.round( rgb[1] ) + data[t+2] = Math.round( rgb[2] ) + data[t+3] = 255 + } + } + ctx.putImageData(imageData,0,0) + } + + function hunterlab2xyz (L,a,b) { + var_Y = L / 10 + var_X = a / 17.5 * L / 10 + var_Z = b / 7 * L / 10 + + Y = Math.pow(var_Y, 2) + X = ( var_X + Y ) / 1.02 + Z = -( var_Z - Y ) / 0.847 + xyz = [X,Y,Z] + } + function xyz2rgb(){ + var var_X = xyz[0] / 100 //X from 0 to 95.047 (Observer = 2°, Illuminant = D65) + var var_Y = xyz[1] / 100 //Y from 0 to 100.000 + var var_Z = xyz[2] / 100 //Z from 0 to 108.883 + + var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986 + var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415 + var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570 + + if ( var_R > 0.0031308 ) var_R = 1.055 * Math.pow( var_R, 1 / 2.4 ) - 0.055 + else var_R = 12.92 * var_R + if ( var_G > 0.0031308 ) var_G = 1.055 * Math.pow( var_G, 1 / 2.4 ) - 0.055 + else var_G = 12.92 * var_G + if ( var_B > 0.0031308 ) var_B = 1.055 * Math.pow( var_B, 1 / 2.4 ) - 0.055 + else var_B = 12.92 * var_B + + rgb[0] = clamp(var_R * 255, 0, 255) + rgb[1] = clamp(var_G * 255, 0, 255) + rgb[2] = clamp(var_B * 255, 0, 255) + return rgb + } + function rgb2xyz(RGB){ + var var_R = ( RGB[0] / 255 ) // R from 0 to 255 + var var_G = ( RGB[1] / 255 ) // G from 0 to 255 + var var_B = ( RGB[2] / 255 ) // B from 0 to 255 + + if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4 + else var_R = var_R / 12.92 + if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4 + else var_G = var_G / 12.92 + if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4 + else var_B = var_B / 12.92 + + var_R = var_R * 100 + var_G = var_G * 100 + var_B = var_B * 100 + + //Observer. = 2°, Illuminant = D65 + var x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805 + var y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722 + var z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505 + return [x,y,z] + } + function xyz2hunterlab (XYZ) { + var X = XYZ[0] + var Y = XYZ[1] + var Z = XYZ[2] + var L = 10 * sqrt( Y ) + var a = 17.5 * ( ( ( 1.02 * X ) - Y ) / sqrt( Y ) ) + var b = 7 * ( ( Y - ( 0.847 * Z ) ) / sqrt( Y ) ) + return [L,a,b] + } + + // this.paint(val) +} diff --git a/public/assets/javascripts/ui/editor/WallpaperPicker.js b/public/assets/javascripts/ui/editor/WallpaperPicker.js index 9ee441b..2309e22 100644 --- a/public/assets/javascripts/ui/editor/WallpaperPicker.js +++ b/public/assets/javascripts/ui/editor/WallpaperPicker.js @@ -7,6 +7,10 @@ var WallpaperPicker = View.extend({ }, initialize: function(){ + this.el.innerHTML = "wallpaper coming soon" + this.el.style.padding = "10px" + this.el.style.fontWeight = "300" + return var wm = new WallpaperManager() app.on('wallpaper-ready', function(){ var black = [0,0,0,1.0] diff --git a/public/assets/javascripts/util.js b/public/assets/javascripts/util.js index b92dcf3..7812a4d 100644 --- a/public/assets/javascripts/util.js +++ b/public/assets/javascripts/util.js @@ -12,7 +12,10 @@ function sanitize (s){ return (s || "").replace(new RegExp("[<>&]", 'g'), "") } function capitalize (s){ return s.split(" ").map(capitalizeWord).join(" ") } function capitalizeWord (s){ return s.charAt(0).toUpperCase() + s.slice(1) } function slugify (s){ return (s || "").toLowerCase().replace(/\s/g,"-").replace(/[^-_a-zA-Z0-9]/g, '-').replace(/-+/g,"-") } - +function rgb_string (rgb) { return "rgb(" + rgb.map(Math.round).join(",") + ")" } +function rgba_string (rgb,a) { return "rgba(" + rgb.map(Math.round).join(",") + "," + a + ")" } +function hex_string (rgb) { return "#" + rgb.map(Math.round).map(function(n){ var s = n.toString(16); return s.length == 1 ? "0"+s : s }).join("") } +function parse_rgba_string (s) { return s.match(/(\d+)/g).slice(0,3) } var E = Math.E var PI = Math.PI diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index b1be797..ff35ca4 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -636,6 +636,9 @@ iframe.embed { background-size: 100% 100%; } + +/* AUTOSAVE MONITOR */ + #minotaur { position: absolute; top: 26px; @@ -655,6 +658,7 @@ iframe.embed { content: 'SAVING'; } + .rapper { position:relative; } @@ -1092,6 +1096,9 @@ iframe.embed { transition:opacity 0.3s ease-in-out; } + +/* WALLPAPER PICKER */ + .wallpaper{ right: 80px; margin-top: 77px; @@ -1149,6 +1156,9 @@ iframe.embed { transform: translateX(3px) translateY(-3px); } + +/* COLOR PICKER */ + .lightcontrol { margin-top: 13%; right: 80px; @@ -1158,35 +1168,54 @@ iframe.embed { transform: translateX(400px); transition: -webkit-transform 0.2s ease-in-out; } - .lightcontrol.active { -webkit-transform: translateX(0px); transform: translateX(0px); } - -.lightcontrol .slider { - +.lightcontrol .slider { } h4 { font-weight:300; font-size:11px; } input[type=range] { - -webkit-appearance: none; - -moz-appearance: none; - background-color: black; - width: 180px; - height:3px; + -webkit-appearance: none; + -moz-appearance: none; + background-color: black; + width: 180px; + height:3px; } - input[type="range"]::-webkit-slider-thumb { - -webkit-appearance: none; - background-color: #000; - width: 10px; - height: 10px; - border-radius:10px; - cursor:pointer; + -webkit-appearance: none; + background-color: #000; + width: 10px; + height: 10px; + border-radius:10px; + cursor:pointer; } +.colorPicker { + cursor: crosshair; +} +.swatch { + width: 20px; + height: 20px; + border: 1px solid black; + display: inline-block; +} +.swatch.selected { + border-width: 2px; +} +.color-swatches { + margin-top: 10px; +} +.color-swatches label { + font-size: 11px; + font-weight: 300; + position: relative; + top: -6px; + margin-right: 15px; +} + .settings.info { right: auto; diff --git a/views/controls/editor/light-control.ejs b/views/controls/editor/light-control.ejs index ddd282b..4324087 100644 --- a/views/controls/editor/light-control.ejs +++ b/views/controls/editor/light-control.ejs @@ -1,8 +1,16 @@ <div class="vvbox lightcontrol"> + <div class="slider"> - <input type="range" min="0" max="100" value="0" id="outline-hue" /> - <h4>Outline Hue</h4> + <input type="range" min="0" max="110" value="0" id="brightness-control" /> + <h4>Brightness</h4> </div> + + <div class="color-swatches"> + <div class="swatch" id="wall-color"></div> <label>wall color</label> + <div class="swatch" id="outline-color"></div> <label>outline color</label> + </div> + +<!-- <div class="slider"> <input type="range" min="0" max="100" value="100" id="wall-hue" /> <h4>Wall Hue</h4> @@ -15,4 +23,5 @@ <input type="range" min="0" max="100" value="0" id="shadow-control" /> <h4>Shadow</h4> </div> +--> </div> |
