From 7afac43f11d1ccae6f3b8d1febcd293db11bd2b7 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 1 Oct 2014 15:42:21 -0400 Subject: randomly place images on the walls --- .../rectangles/engine/scenery/randomize.js | 77 ++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 public/assets/javascripts/rectangles/engine/scenery/randomize.js (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js') diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js new file mode 100644 index 0000000..4f1144a --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -0,0 +1,77 @@ +/* + // get the list of media we want to place + var media_data = $(".mediaContainer").toArray().map(function(el){ + return $(el).data("media") + }) + Scenery.randomize( media_data ) +*/ + +Scenery.randomize = function (media_data) { + var media_list = media_data.map(function(media){ + var width, height + if (media.width > media.height) { + width = Math.min(300, media.width) + height = media.height/media.width * width + } + else { + height = Math.min(300, media.height) + width = media.width/media.height * height + } + return { + dimensions: new vec2( width, height ), + media: media, + } + }) + + // get a list of all walls + var walls = {} + Walls.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] + }) + + var wall_ids = _.keys(walls) + if (! wall_ids.length) { + return + } + + // randomize walls + shuffle(wall_ids) + + // 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 + } + + 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 + } + } + + if (fits != -1) { + var wall = walls[wall_ids[fits]] + wall_ids.splice(fits, 1) + + Scenery.add({ + media: media.media, + wall: wall, + index: 0, + }) + } + else { + // artwork won't fit anywhere?? + } + + return false + }) +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 10a98d58fcba585dc13d251497c6028d04de0031 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 13 Oct 2014 13:34:52 -0400 Subject: larger default size --- public/assets/javascripts/rectangles/engine/scenery/randomize.js | 4 ++-- public/assets/javascripts/rectangles/engine/scenery/types/image.js | 2 +- public/assets/javascripts/rectangles/engine/scenery/types/video.js | 2 +- public/assets/javascripts/rectangles/util/constants.js | 3 ++- views/controls/builder/info.ejs | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js') diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js index 4f1144a..82b6bf9 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/randomize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -10,11 +10,11 @@ Scenery.randomize = function (media_data) { var media_list = media_data.map(function(media){ var width, height if (media.width > media.height) { - width = Math.min(300, media.width) + width = Math.min(DEFAULT_PICTURE_WIDTH, media.width) height = media.height/media.width * width } else { - height = Math.min(300, media.height) + height = Math.min(DEFAULT_PICTURE_WIDTH, media.height) width = media.width/media.height * height } return { diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/image.js b/public/assets/javascripts/rectangles/engine/scenery/types/image.js index bed847b..10fc917 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/image.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/image.js @@ -7,7 +7,7 @@ Scenery.types.image = Scenery.types.base.extend(function(base){ init: function(opt){ - opt.scale = opt.scale || (opt.data && opt.data.scale) || 300 / max(300, opt.media.width) + opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width) base.init.call(this, opt) diff --git a/public/assets/javascripts/rectangles/engine/scenery/types/video.js b/public/assets/javascripts/rectangles/engine/scenery/types/video.js index b723f56..a669a90 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/types/video.js +++ b/public/assets/javascripts/rectangles/engine/scenery/types/video.js @@ -6,7 +6,7 @@ Scenery.types.video = Scenery.types.base.extend(function(base){ type: 'video', init: function(opt){ - opt.scale = opt.scale || (opt.data && opt.data.scale) || 300 / max(300, opt.media.width) + opt.scale = opt.scale || (opt.data && opt.data.scale) || DEFAULT_PICTURE_WIDTH / max(DEFAULT_PICTURE_WIDTH, opt.media.width) base.init.call(this, opt) diff --git a/public/assets/javascripts/rectangles/util/constants.js b/public/assets/javascripts/rectangles/util/constants.js index 198cc41..a38325e 100644 --- a/public/assets/javascripts/rectangles/util/constants.js +++ b/public/assets/javascripts/rectangles/util/constants.js @@ -20,7 +20,8 @@ var height_min = 200, side_min = 10, side_max = 5000, resize_margin = 8, - cursor_amp = 1.5 + cursor_amp = 1.5, + DEFAULT_PICTURE_WIDTH = 400 var painting_distance_from_wall = 10, dot_distance_from_picture = 3 diff --git a/views/controls/builder/info.ejs b/views/controls/builder/info.ejs index 3c5d4b7..205938f 100644 --- a/views/controls/builder/info.ejs +++ b/views/controls/builder/info.ejs @@ -40,7 +40,7 @@ -- cgit v1.2.3-70-g09d2 From 3022e063a4b501cd581f1cb70c2dc709e4a3294c Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 10 Nov 2014 12:28:54 -0500 Subject: making random placement api more general --- .../rectangles/engine/scenery/randomize.js | 51 ++++++++++++++-------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js') diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js index 82b6bf9..1c8ec4f 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/randomize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -1,13 +1,17 @@ /* // 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 ) + var walls = [] + Scenery.randomize.add( media_objs, walls ) */ -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 +26,50 @@ 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){ + (wall_list || Walls).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){ + 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. +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) // 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 - } + media_list.all(function(media){ + // bail if we're out of walls + if (wall_ids.length == 0) { return false } 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 } @@ -72,6 +89,6 @@ Scenery.randomize = function (media_data) { // artwork won't fit anywhere?? } - return false + return true }) } \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 57ec98db0520b0cc6fe563b983959bf6cb33d1fd Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 10 Nov 2014 12:32:37 -0500 Subject: allow for calling random placement api multiple times --- .../assets/javascripts/rectangles/engine/scenery/randomize.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js') diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js index 1c8ec4f..e6d662a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/randomize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -42,7 +42,13 @@ Scenery.randomize.get_empty_walls = function(wall_list){ // remove the walls that already have stuff on them if (! wall_list) { Scenery.forEach(function(scenery){ - delete walls[scenery.wall.id] + if (scenery.was_randomly_placed) { + // remove it and reuse this wall? + Scenery.remove( scenery.id ) + } + else { + delete walls[scenery.wall.id] + } }) } @@ -79,11 +85,12 @@ Scenery.randomize.add = function (media_objs, wall_list) { 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?? -- cgit v1.2.3-70-g09d2 From a1860ea42334447f49649a3491bad605237a23d5 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 10 Nov 2014 12:48:53 -0500 Subject: randomize button on media drawer (unstyled) --- .../javascripts/rectangles/engine/scenery/randomize.js | 16 +++++++++------- public/assets/javascripts/ui/editor/MediaViewer.js | 10 ++++++++-- views/controls/editor/media-drawer.ejs | 1 + 3 files changed, 18 insertions(+), 9 deletions(-) (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js') diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js index e6d662a..1c2eb56 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/randomize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -3,8 +3,7 @@ var media_objs = $(".mediaContainer").toArray().map(function(el){ return $(el).data("media") }) - var walls = [] - Scenery.randomize.add( media_objs, walls ) + Scenery.randomize.add( media_objs ) */ Scenery.randomize = {}; @@ -34,8 +33,9 @@ Scenery.randomize.get_dimensions = function (media_objs){ // 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 = {} - (wall_list || Walls).forEach(function(wall){ + var walls = {}; + + (wall_list || Walls.list).forEach(function(wall){ walls[wall.id] = wall }) @@ -57,6 +57,7 @@ Scenery.randomize.get_empty_walls = function(wall_list){ // 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) @@ -66,11 +67,12 @@ Scenery.randomize.add = function (media_objs, wall_list) { // randomize walls shuffle(wall_ids) + shuffle(media_list) // assign each of the media to the walls, until we run out of either - media_list.all(function(media){ + media_list.some(function(media){ // bail if we're out of walls - if (wall_ids.length == 0) { return false } + if (wall_ids.length == 0) { return true } var i, fits = -1 @@ -96,6 +98,6 @@ Scenery.randomize.add = function (media_objs, wall_list) { // artwork won't fit anywhere?? } - return true + return false }) } \ No newline at end of file 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/views/controls/editor/media-drawer.ejs b/views/controls/editor/media-drawer.ejs index 3e64cc3..5846bf4 100644 --- a/views/controls/editor/media-drawer.ejs +++ b/views/controls/editor/media-drawer.ejs @@ -14,6 +14,7 @@ -->

+

Randomize

You have no media yet. Upload some!
-- cgit v1.2.3-70-g09d2 From 15058f6c83da00b54f676b9fafbb758ddef0be84 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 1 Dec 2014 13:46:57 -0500 Subject: undo random scenery placement --- .../rectangles/engine/scenery/_scenery.js | 3 +++ .../rectangles/engine/scenery/randomize.js | 18 ++++++++++--- .../javascripts/rectangles/engine/scenery/undo.js | 30 +++++++++++++++++++++- 3 files changed, 47 insertions(+), 4 deletions(-) (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js') diff --git a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js index d03e0e1..d52fe21 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/_scenery.js +++ b/public/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -99,6 +99,7 @@ var Scenery = new function(){ } base.deserialize = function(scenery_data){ + var added = [] scenery_data.forEach(function(data){ var wall = Walls.lookup[data.wall_id] || Walls.first() var scene_media = base.add({ @@ -107,7 +108,9 @@ var Scenery = new function(){ media: data.media, id: data.id }) + added.push(scene_media) }) + return added } return base diff --git a/public/assets/javascripts/rectangles/engine/scenery/randomize.js b/public/assets/javascripts/rectangles/engine/scenery/randomize.js index 1c2eb56..6581f38 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/randomize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js @@ -33,7 +33,7 @@ Scenery.randomize.get_dimensions = function (media_objs){ // 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 = {}; + var walls = {}, removed = []; (wall_list || Walls.list).forEach(function(wall){ walls[wall.id] = wall @@ -44,6 +44,7 @@ Scenery.randomize.get_empty_walls = function(wall_list){ Scenery.forEach(function(scenery){ if (scenery.was_randomly_placed) { // remove it and reuse this wall? + removed.push( scenery.serialize() ) Scenery.remove( scenery.id ) } else { @@ -52,7 +53,7 @@ Scenery.randomize.get_empty_walls = function(wall_list){ }) } - return walls + return { walls: walls, removed: removed } } // Randomly place a set of media objects on empty walls. @@ -60,7 +61,10 @@ Scenery.randomize.get_empty_walls = function(wall_list){ // 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 empty_data = Scenery.randomize.get_empty_walls(wall_list) + var walls = empty_data.walls + var removed = empty_data.removed + var added = [] var wall_ids = _.keys(walls) if (! wall_ids.length) { return } @@ -93,6 +97,7 @@ Scenery.randomize.add = function (media_objs, wall_list) { index: 0, }) scenery.was_randomly_placed = true + added.push(scenery.serialize()) } else { // artwork won't fit anywhere?? @@ -100,4 +105,11 @@ Scenery.randomize.add = function (media_objs, wall_list) { return false }) + + UndoStack.push({ + type: "randomize-scenery", + undo: { added: added, removed: removed }, + redo: { added: added, removed: removed }, + }) + } \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/engine/scenery/undo.js b/public/assets/javascripts/rectangles/engine/scenery/undo.js index 8b85d02..1232780 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/undo.js +++ b/public/assets/javascripts/rectangles/engine/scenery/undo.js @@ -121,7 +121,7 @@ }) }, }, - + // { @@ -166,6 +166,34 @@ Minotaur.watch( app.router.editorView.settings ) }, }, + { + type: "randomize-scenery", + undo: function(state){ + state.added.forEach(function(_scenery){ + Scenery.remove(_scenery.id) + }) + var scenery_list = Scenery.deserialize(state.removed) + scenery_list.forEach(function(scenery){ + scenery.was_randomly_placed = true + }) + Scenery.resize.hide() + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + }, + redo: function(state){ + state.removed.forEach(function(_scenery){ + Scenery.remove(_scenery.id) + }) + var scenery_list = Scenery.deserialize(state.added) + scenery_list.forEach(function(scenery){ + scenery.was_randomly_placed = true + }) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + }, + }, ]) })() -- cgit v1.2.3-70-g09d2