diff options
Diffstat (limited to 'public/assets/javascripts/rectangles/engine')
9 files changed, 139 insertions, 89 deletions
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(){ |
