diff options
Diffstat (limited to 'public')
21 files changed, 451 insertions, 272 deletions
diff --git a/public/assets/javascripts/app.js b/public/assets/javascripts/app.js index b4eb9e6..5620cdc 100644 --- a/public/assets/javascripts/app.js +++ b/public/assets/javascripts/app.js @@ -71,6 +71,8 @@ app.launch = function () { // loader.preloadImages([]) loader.ready() + + window.scrollTo(0,0) } app.on = function(){ diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js index 2c231ae..9af2c8d 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -33,7 +33,11 @@ MX.Movements = function (cam) { var pos = { x: 0, y: 0, z: 0, rotationX: 0, rotationY: 0 } - $(document).one("keydown", function(){ $("#keyhint").fadeOut(250) }) + $(document).one("keydown", function(){ + $("#keyhint").fadeOut(250); + $('.reader #minimap').addClass('active'); + }) + function clampRotation( vr ) { if (Rooms.mover.noclip) { return clamp(vr, PI/-2, PI/2 ) diff --git a/public/assets/javascripts/rectangles/engine/map/_map.js b/public/assets/javascripts/rectangles/engine/map/_map.js index 64372c5..202803a 100644 --- a/public/assets/javascripts/rectangles/engine/map/_map.js +++ b/public/assets/javascripts/rectangles/engine/map/_map.js @@ -15,6 +15,7 @@ var Map = function(opt){ var base = this base.el = opt.el + base.$el = $(base.el) if (! base.el) return diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js index f6cc8e4..436712a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js +++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -5,6 +5,7 @@ var Scenery = new function(){ base.list = {} base.nextMedia = null + base.nextWallpaper = null base.mouse = new mouse ({ use_offset: false, mousedownUsesCapture: true }) @@ -28,6 +29,7 @@ var Scenery = new function(){ case 'text': scene_media = new Scenery.types.text (opt) + scene_media.focused = true break } base.list[scene_media.id] = scene_media diff --git a/public/assets/javascripts/rectangles/engine/scenery/move.js b/public/assets/javascripts/rectangles/engine/scenery/move.js index 12705d3..f57ddba 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/move.js +++ b/public/assets/javascripts/rectangles/engine/scenery/move.js @@ -14,6 +14,7 @@ Scenery.move = function(base){ } this.unbind = function(){ + base.focused = false Scenery.mouse.unbind_el(base.mx.el) Scenery.mouse.off("down", down) Scenery.mouse.off("enter", switch_wall) @@ -31,6 +32,11 @@ Scenery.move = function(base){ // load the modal app.controller.pick(base) + if (! base.focused) { + e.clickAccepted = false + base.focused = true + return + } if (! (editor.permissions.move || editor.permissions.resize) ) { e.clickAccepted = false return diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js index 82b6bf9..1c2eb56 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/randomize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -1,13 +1,16 @@ /* // get the list of media we want to place - var media_data = $(".mediaContainer").toArray().map(function(el){ + var media_objs = $(".mediaContainer").toArray().map(function(el){ return $(el).data("media") }) - Scenery.randomize( media_data ) + Scenery.randomize.add( media_objs ) */ -Scenery.randomize = function (media_data) { - var media_list = media_data.map(function(media){ +Scenery.randomize = {}; + +// Given a list of media objects, generate their ideal dimensions +Scenery.randomize.get_dimensions = function (media_objs){ + var media_list = media_objs.map(function(media){ var width, height if (media.width > media.height) { width = Math.min(DEFAULT_PICTURE_WIDTH, media.width) @@ -22,37 +25,59 @@ Scenery.randomize = function (media_data) { media: media, } }) + return media_list +} +// Build the lookup of empty walls. +// Takes a list of walls to use, or undefined to use all empty walls. +// Returns a lookup of walls to use, keyed by wall ID. +Scenery.randomize.get_empty_walls = function(wall_list){ // get a list of all walls - var walls = {} - Walls.forEach(function(wall){ + var walls = {}; + + (wall_list || Walls.list).forEach(function(wall){ walls[wall.id] = wall }) // remove the walls that already have stuff on them - Scenery.forEach(function(scenery){ - delete walls[scenery.wall.id] - }) + if (! wall_list) { + Scenery.forEach(function(scenery){ + if (scenery.was_randomly_placed) { + // remove it and reuse this wall? + Scenery.remove( scenery.id ) + } + else { + delete walls[scenery.wall.id] + } + }) + } + + return walls +} +// Randomly place a set of media objects on empty walls. +// Only one object per wall will be added. +// Optionally takes a list of walls to use. +Scenery.randomize.add = function (media_objs, wall_list) { + var media_list = Scenery.randomize.get_dimensions(media_objs) + var walls = Scenery.randomize.get_empty_walls(wall_list) + var wall_ids = _.keys(walls) - if (! wall_ids.length) { - return - } + if (! wall_ids.length) { return } // randomize walls shuffle(wall_ids) + shuffle(media_list) // assign each of the media to the walls, until we run out of either media_list.some(function(media){ - if (wall_ids.length == 0) { - return true - } + // bail if we're out of walls + if (wall_ids.length == 0) { return true } var i, fits = -1 for (i = 0; i < wall_ids.length; i++) { if (walls[wall_ids[i]].surface.fits(media.dimensions)) { - // walls[wall_ids[i]] fits = i break } @@ -62,11 +87,12 @@ Scenery.randomize = function (media_data) { var wall = walls[wall_ids[fits]] wall_ids.splice(fits, 1) - Scenery.add({ + var scenery = Scenery.add({ media: media.media, wall: wall, index: 0, }) + scenery.was_randomly_placed = true } else { // artwork won't fit anywhere?? diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index e424829..5af7f3f 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -6,7 +6,7 @@ Scenery.resize = new function(){ var obj var x, y, z, bounds var dragging = false - var naturalDimension, dimension, position, scale + var naturalDimension, naturalDimensionCopy, dimension, position, scale var oldState var dots = [], dot, selected_dot @@ -143,6 +143,11 @@ Scenery.resize = new function(){ dimension = obj.dimensions position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z) oldState = obj.serialize() + + if (obj.type == "text") { + naturalDimensionCopy = naturalDimension.clone() + positionCopy = position.clone() + } document.body.classList.add("dragging") } @@ -163,15 +168,23 @@ Scenery.resize = new function(){ mag = y_sign * mag * sign(height) } - obj.set_scale( ( dimension.a + mag ) / naturalDimension.a ) + if (obj.type == "text") { + obj.mx.width = obj.media.width = naturalDimension.a = naturalDimensionCopy.a + (mag * 2) + obj.mx.height = obj.media.height = naturalDimension.b = naturalDimensionCopy.b + (mag * 2) + dimension.a = naturalDimension.a * obj.scale + dimension.b = naturalDimension.b * obj.scale + } + else { + obj.set_scale( ( dimension.a + mag ) / naturalDimension.a ) + } - if (selected_dot.side & LEFT_RIGHT) { - obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign) - obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign) - } - if (selected_dot.side & TOP_BOTTOM) { - obj.mx.y = position.b - mag/2 * y_sign - } + if (selected_dot.side & LEFT_RIGHT) { + obj.mx.x = position.a + cos(rotationY) * mag/2 * (x_sign) + obj.mx.z = position.c + sin(rotationY) * mag/2 * (x_sign) + } + if (selected_dot.side & TOP_BOTTOM) { + obj.mx.y = position.b - mag/2 * y_sign + } base.move_dots() @@ -181,11 +194,26 @@ Scenery.resize = new function(){ function up (e, cursor){ if (! dragging) return dragging = false - selected_dot = null if (! editor.permissions.resize) { return } - obj.scale = obj.mx.ops.scale = obj.mx.scale - obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale) + if (obj.type == "text") { + var newHeight = $(obj.mx.inner).height() + if (selected_dot.side & BOTTOM) { + obj.mx.y = position.b + (naturalDimensionCopy.b - newHeight) / 2 * obj.scale + } + else { + obj.mx.y = dots[0].y - newHeight/2*obj.scale + } + obj.mx.height = obj.media.height = naturalDimension.b = newHeight + dimension.a = naturalDimension.a * obj.scale + dimension.b = naturalDimension.b * obj.scale + base.move_dots() + } + else { + obj.scale = obj.mx.ops.scale = obj.mx.scale + obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale) + } + UndoStack.push({ type: 'update-scenery', undo: oldState, @@ -196,6 +224,7 @@ Scenery.resize = new function(){ Minotaur.watch( app.router.editorView.settings ) document.body.classList.remove("dragging") + selected_dot = null } } diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js index 10ba2b0..cd3f981 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/_object.js @@ -28,6 +28,45 @@ Scenery.types.base = Fiber.extend(function(base){ this.dimensions = this.naturalDimensions.clone().mul(this.scale) }, + place: function(opt){ + if (opt.data) { + if (opt.wall) { + var position = opt.wall.mxToPosition(opt.data.position) + opt.index = opt.wall.surface.index_for_x( position.a, 0 ) + } + this.set_wall(opt) + this.deserialize(opt.data) + } + else { + this.set_wall(opt) + if (this.wall && ! this.bounds) { + this.find_minimum_scale(opt) + if (! this.bounds) return + } + + this.recenter() + if (opt.position) { + this.translateTo(opt.position) + } + var mx_position = this.wall.positionToMx( this.position, this.dimensions ) + this.mx.move(mx_position) + } + }, + + find_minimum_scale: function(opt){ + var bounds = this.wall.surface.bounds_at_index_with_dimensions(opt.index || 0, new vec2(50, 50)) + var scale = 1 + if (! bounds || bounds.width() < 50 || bounds.height < 50) return + if (this.naturalDimensions.a > bounds.width()) { + scale = bounds.width() / (this.naturalDimensions.a + 10) + } + if (this.naturalDimensions.b > bounds.height()) { + scale = Math.min(scale, bounds.height() / (this.naturalDimensions.b + 10)) + } + this.set_scale(scale) + this.set_wall(opt) + }, + recenter: function () { if (! this.bounds) return var center = this.bounds.center() @@ -77,6 +116,9 @@ Scenery.types.base = Fiber.extend(function(base){ }, remove: function(){ + if (this.removed) return + this.removed = true + UndoStack.push({ type: 'destroy-scenery', undo: this.serialize(), diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/image.js b/public/assets/javascripts/rectangles/engine/scenery/types/image.js index 848f8d4..0e5e77c 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/image.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/image.js @@ -13,26 +13,7 @@ Scenery.types.image = Scenery.types.base.extend(function(base){ this.build() this.bind() - - if (opt.data) { - if (opt.wall) { - var position = opt.wall.mxToPosition(opt.data.position) - opt.index = opt.wall.surface.index_for_x( position.a, 0 ) - } - this.set_wall(opt) - this.deserialize(opt.data) - } - else { - this.set_wall(opt) - if (this.bounds) { - this.recenter() - if (opt.position) { - this.translateTo(opt.position) - } - var mx_position = this.wall.positionToMx( this.position, this.dimensions ) - this.mx.move(mx_position) - } - } + this.place(opt) }, build: function(){ diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/text.js b/public/assets/javascripts/rectangles/engine/scenery/types/text.js index dd1385f..6e11da2 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/text.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/text.js @@ -13,26 +13,7 @@ Scenery.types.text = Scenery.types.base.extend(function(base){ this.build() this.bind() - - if (opt.data) { - if (opt.wall) { - var position = opt.wall.mxToPosition(opt.data.position) - opt.index = opt.wall.surface.index_for_x( position.a, 0 ) - } - this.set_wall(opt) - this.deserialize(opt.data) - } - else { - this.set_wall(opt) - if (this.bounds) { - this.recenter() - if (opt.position) { - this.translateTo(opt.position) - } - var mx_position = this.wall.positionToMx( this.position, this.dimensions ) - this.mx.move(mx_position) - } - } + this.place(opt) }, build: function(){ diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js index d83cc63..d1b1763 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/video.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js @@ -6,32 +6,14 @@ Scenery.types.video = Scenery.types.base.extend(function(base){ type: 'video', init: function(opt){ + opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width) base.init.call(this, opt) this.build() this.bind() - - if (opt.data) { - if (opt.wall) { - var position = opt.wall.mxToPosition(opt.data.position) - opt.index = opt.wall.surface.index_for_x( position.a, 0 ) - } - this.set_wall(opt) - this.deserialize(opt.data) - } - else { - this.set_wall(opt) - if (this.bounds) { - this.recenter() - if (opt.position) { - this.translateTo(opt.position) - } - var mx_position = this.wall.positionToMx( this.position, this.dimensions ) - this.mx.move(mx_position) - } - } + this.place(opt) }, build: function(){ diff --git a/public/assets/javascripts/rectangles/models/vec3.js b/public/assets/javascripts/rectangles/models/vec3.js index 4e00b0c..c44dfe6 100644 --- a/public/assets/javascripts/rectangles/models/vec3.js +++ b/public/assets/javascripts/rectangles/models/vec3.js @@ -15,6 +15,9 @@ vec3.prototype.sub = function(v){ this.c -= v.c return this } +vec3.prototype.clone = function(){ + return new vec3(this.a, this.b, this.c) +} // input: mat4 projection matrix vec3.prototype.apply_projection = function (m) { diff --git a/public/assets/javascripts/ui/builder/BuilderInfo.js b/public/assets/javascripts/ui/builder/BuilderInfo.js index e1c90c8..7606361 100644 --- a/public/assets/javascripts/ui/builder/BuilderInfo.js +++ b/public/assets/javascripts/ui/builder/BuilderInfo.js @@ -47,6 +47,7 @@ var BuilderInfo = View.extend({ this.$noSelection.toggle( ! this.room ) this.$el.toggleClass("active", state) if (state) { + this.$viewHeight.unitVal( window.viewHeight ) this.parent.cursor.message("builder") } else { diff --git a/public/assets/javascripts/ui/editor/ColorControl.js b/public/assets/javascripts/ui/editor/ColorControl.js index d1a8c7b..0c5463e 100644 --- a/public/assets/javascripts/ui/editor/ColorControl.js +++ b/public/assets/javascripts/ui/editor/ColorControl.js @@ -4,8 +4,6 @@ var ColorControl = View.extend({ events: { "mousedown": "stopPropagation", - "mousedown #brightness-control": "beginBrightness", - "input #brightness-control": "updateBrightness", "click .color-swatches span": "setSurface", "click .colors span": "setHue", }, @@ -32,6 +30,7 @@ var ColorControl = View.extend({ this.colorPicker = new LabColorPicker(this, 155, 155) this.$("#color-picker").append( this.colorPicker.canvas ) this.$("#color-picker").append( this.colorPicker.cursor ) + this.$(".slider").append( this.colorPicker.brightness ) this.$swatches = this.$(".swatch") this.$labels = this.$(".swatch + label") @@ -41,8 +40,7 @@ var ColorControl = View.extend({ floor: this.$("#floor-color"), ceiling: this.$("#ceiling-color"), } - this.$brightnessControl = this.$("#brightness-control") - + this.$colors = this.$(".colors") this.colors.forEach(function(color){ var $swatch = $("<span>") @@ -134,7 +132,6 @@ var ColorControl = View.extend({ color = Walls.colors[ mode ] this.labColor = this.colorPicker.load(color) - this.$brightnessControl.val( this.labColor[0] ) }, setSurface: function(e){ @@ -144,174 +141,8 @@ var ColorControl = View.extend({ setHue: function(e){ var color = $(e.currentTarget).data('color') - this.labColor = this.colorPicker.load(color) - this.$brightnessControl.val( this.labColor[0] ) - this.pick(color, this.labColor) - }, - - beginBrightness: function(){ - this.begin() - $(window).one("mouseup", this.finalize.bind(this)) - }, - - 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 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){ - parent.begin() - 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) - }, - up: function(){ - parent.finalize() - } - }) - - 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){ - i = clamp(i, 0, w) - j = clamp(j, 0, h) - 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) - this.moveCursor(i, j) - 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 ) - - this.moveCursor(x,y) - this.setLab(Lab) - return Lab - } - this.moveCursor = function(x,y){ - cursor.style.left = x + "px" - cursor.style.top = y + "px" - } - 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 = Math.pow( ( var_R + 0.055 ) / 1.055, 2.4) - else var_R = var_R / 12.92 - if ( var_G > 0.04045 ) var_G = Math.pow( ( var_G + 0.055 ) / 1.055, 2.4) - else var_G = var_G / 12.92 - if ( var_B > 0.04045 ) var_B = Math.pow( ( 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] || 1e-6 // otherwise divide-by-zero error when converting rgb(0,0,0) - 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] - } -} +}) diff --git a/public/assets/javascripts/ui/editor/MediaEditor.js b/public/assets/javascripts/ui/editor/MediaEditor.js index db5878f..de93f6e 100644 --- a/public/assets/javascripts/ui/editor/MediaEditor.js +++ b/public/assets/javascripts/ui/editor/MediaEditor.js @@ -65,7 +65,7 @@ var MediaEditor = FormView.extend({ var media = scenery.media - console.log(media) + // console.log(media) this.$name.val(media.title || filenameFromUrl(media.url) ) this.$description.val(media.description) diff --git a/public/assets/javascripts/ui/editor/MediaViewer.js b/public/assets/javascripts/ui/editor/MediaViewer.js index dd17613..9593ab7 100644 --- a/public/assets/javascripts/ui/editor/MediaViewer.js +++ b/public/assets/javascripts/ui/editor/MediaViewer.js @@ -13,6 +13,7 @@ var MediaViewer = ModalView.extend({ 'click .foundToggle': "foundToggle", 'click .userToggle': "userToggle", 'click #deleteMedia': "deleteArmed", + 'click #randomize': "randomize", 'click .mediaContainer': "pick", 'click .viewMore': "load", }, @@ -119,10 +120,15 @@ var MediaViewer = ModalView.extend({ }, randomize: function(){ - var media_data = $(".mediaContainer").toArray().map(function(el){ + var $divs = this.$myMediaContainer.find(".mediaContainer").toArray() + if ($divs.length < 3) { + $divs = $divs.concat( this.$foundMediaContainer.find(".mediaContainer").toArray() ) + } + var media_objs = $divs.map(function(el){ return $(el).data("media") }) - Scenery.randomize( media_data ) + Scenery.randomize.add( media_objs ) + this.hide() }, populate: function(data){ diff --git a/public/assets/javascripts/ui/editor/TextEditor.js b/public/assets/javascripts/ui/editor/TextEditor.js index 51077af..2949943 100644 --- a/public/assets/javascripts/ui/editor/TextEditor.js +++ b/public/assets/javascripts/ui/editor/TextEditor.js @@ -25,6 +25,11 @@ var TextEditor = FormView.extend({ this.$fontSize = this.$("[name=font-size]") this.$textBody = this.$("[name=text-body]") this.$textAlign = this.$("[name=text-align]") + + app.on("cancel-scenery", function(){ + this.createMode(true) + $("body").toggleClass("addText", false) + }.bind(this)) }, toggle: function(state){ @@ -70,11 +75,13 @@ var TextEditor = FormView.extend({ if (this.tainted) { Minotaur.watch( app.router.editorView.settings ) } - if (this.scenery.mx) { this.scenery.mx.bound = false this.scenery.mx.el.classList.remove("picked") } + if (! this.scenery.media || ! this.scenery.media.description || this.scenery.media.description == "") { + this.scenery.remove() + } } this.tainted = false this.scenery = null @@ -138,6 +145,7 @@ var TextEditor = FormView.extend({ destroy: function(){ this.tainted = false this.scenery.remove() + this.hide() }, }) diff --git a/public/assets/javascripts/ui/lib/LabColorPicker.js b/public/assets/javascripts/ui/lib/LabColorPicker.js new file mode 100644 index 0000000..0e1563a --- /dev/null +++ b/public/assets/javascripts/ui/lib/LabColorPicker.js @@ -0,0 +1,178 @@ +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" + + var brightnessControl = this.brightness = document.createElement("input") + var $brightnessControl = $(brightnessControl) + brightnessControl.setAttribute("type", "range") + brightnessControl.setAttribute("min", "0") + brightnessControl.setAttribute("max", "110") + brightnessControl.setAttribute("value", "0") + + canvas.width = w + canvas.height = h + canvas.className = "colorPicker" + + 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){ + parent.begin() + 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) + }, + up: function(){ + parent.finalize() + } + }) + + $brightnessControl.on({ + "mousedown": function(){ base.beginBrightness() }, + "input": function(){ base.updateBrightness() }, + }) + + 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){ + i = clamp(i, 0, w) + j = clamp(j, 0, h) + 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) + this.moveCursor(i, j) + 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 ) + + this.moveCursor(x,y) + this.setLab(Lab) + this.setBrightness(Lab) + + return Lab + } + this.moveCursor = function(x,y){ + cursor.style.left = x + "px" + cursor.style.top = y + "px" + } + 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) + } + + this.beginBrightness = function(){ + parent.begin() + $(window).one("mouseup", parent.finalize.bind(parent)) + } + this.updateBrightness = function(){ + parent.labColor[0] = parseFloat( $brightnessControl.val() ) + var rgb = base.setLab( parent.labColor ) + parent.pick(rgb, parent.labColor) + } + this.setBrightness = function(Lab){ + $brightnessControl.val(Lab[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 = Math.pow( ( var_R + 0.055 ) / 1.055, 2.4) + else var_R = var_R / 12.92 + if ( var_G > 0.04045 ) var_G = Math.pow( ( var_G + 0.055 ) / 1.055, 2.4) + else var_G = var_G / 12.92 + if ( var_B > 0.04045 ) var_B = Math.pow( ( 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] || 1e-6 // otherwise divide-by-zero error when converting rgb(0,0,0) + 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] + } +} diff --git a/public/assets/javascripts/ui/reader/MediaPlayer.js b/public/assets/javascripts/ui/reader/MediaPlayer.js index e40c6ff..42e7596 100644 --- a/public/assets/javascripts/ui/reader/MediaPlayer.js +++ b/public/assets/javascripts/ui/reader/MediaPlayer.js @@ -46,7 +46,7 @@ var MediaPlayer = FormView.extend({ if (media.type == "image") { if ( ! media.description && (! media.title || media.title == filenameFromUrl(media.url)) ) { this.hide() - return + return false } } @@ -78,6 +78,7 @@ var MediaPlayer = FormView.extend({ break } + return true }, hide: function(scenery){ diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js index aea681a..617a145 100644 --- a/public/assets/javascripts/ui/reader/ReaderView.js +++ b/public/assets/javascripts/ui/reader/ReaderView.js @@ -58,7 +58,7 @@ var ReaderView = View.extend({ return } - // don't build anything until we're in landscape mode, otherwise ios might crash + // don't build anything until we're in landscape mode, otherwise ios might crash!! var orientationFn = orientationchange.bind(this) window.addEventListener('orientationchange', orientationFn) function orientationchange (e) { @@ -119,7 +119,8 @@ var ReaderView = View.extend({ }, pick: function(scenery){ - this.mediaPlayer.pick(scenery) + var has_info = this.mediaPlayer.pick(scenery) + $("#minimap").toggleClass('active', ! has_info) app.tube("pick-scenery", { scenery: scenery }) }, @@ -128,6 +129,7 @@ var ReaderView = View.extend({ }, hideExtras: function(){ + $("#minimap").addClass('active') this.mediaPlayer.hide() app.tube("close-scenery") } diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index e6b5570..7b53cca 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -953,7 +953,7 @@ border-left: 1px solid black; } .editing .mx-scenery:hover, .editing .mx-scenery.picked { - border: 1px dashed #000; + border: 15px dashed yellow; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; @@ -990,7 +990,9 @@ border-left: 1px solid black; pointer-events: none; } .mx-text { +/* overflow: hidden; + */ } .mx-text .inner { width: 100%; @@ -1574,7 +1576,27 @@ border-left: 1px solid black; -webkit-transition:opacity 0.3s ease-in-out; transition:opacity 0.3s ease-in-out; } +.reader #minimap { + right: 20px; + left: auto; + -webkit-transform:translateX(180px); + -moz-transform:translateX(180px); + transform:translateX(180px); + -webkit-transition:0.6s -webkit-transform; + -moz-transition:0.6s -moz-transform; + transition:0.6s transform; +} + +.reader #minimap.active { + -webkit-transform:translateX(0px); + -moz-transform:translateX(0px); + transform:translateX(0px); + left: auto; +} +.mobile .reader #minimap{ + display:none; +} /* WALLPAPER PICKER */ @@ -2168,6 +2190,21 @@ input[type="range"]::-webkit-slider-thumb { margin-top:5px; width: 100%; } +#randomize { + background: white; + display: inline-block; + color: black; + text-decoration:none; + border:1px solid black; + text-align: center; + font-size: 13px; + padding: 3px; + cursor: pointer; +} +#randomize:hover { + color: white; + background: black; +} .warn { background:red; display: inline-block; @@ -2375,6 +2412,8 @@ form li textarea { background-position: center; margin-top: 63px; } + + .hero .circle { font-size: 20px; font-weight: 300; @@ -2542,12 +2581,21 @@ a[data-role="forgot-password"] { .aboutRoom.vvbox .txt { padding: 5px 0 3px 0; } - -.aboutRoom h1 a{ +.aboutRoom h1 a { text-decoration: none; font-style: italic; font-weight:500; } +.aboutRoom .profilePic { + width: 34px; + height: 34px; + float: none; + display: inline-block; + vertical-align: middle; +} +.aboutRoom .authorName { + vertical-align: middle; +} .desktop .aboutRoom h1 a:hover { text-decoration:underline; @@ -2993,3 +3041,48 @@ a[data-role="forgot-password"] { width: 55%; } } + + +@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 1) { + .hero{ + height: 500pt; + } + .mobile #scene:after{ + content:url(/assets/img/360.png); + z-index: 3; + position: fixed; + bottom: -3px; + right: -3px; + } + #keyhint { + display:none; + } + .topLinks a[data-role="new-project-modal"], .topLinks a[data-role="show-layouts-modal"] { + display:none; + } +} + +@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (-webkit-min-device-pixel-ratio: 2) { + .hero{ + height: 500pt; + } + .mobile #scene:after{ + content:url(/assets/img/360.png); + z-index: 3; + position: fixed; + bottom: -3px; + right: -3px; + } + #keyhint { + display:none; + } + .topLinks a[data-role="new-project-modal"], .topLinks a[data-role="show-layouts-modal"] { + display:none; + } +} + +@media (max-height: 650px) { + .settings { + right: 80px; + } +}
\ No newline at end of file |
