summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/rectangles/engine/scenery/randomize.js
diff options
context:
space:
mode:
Diffstat (limited to 'public/assets/javascripts/rectangles/engine/scenery/randomize.js')
-rw-r--r--public/assets/javascripts/rectangles/engine/scenery/randomize.js115
1 files changed, 115 insertions, 0 deletions
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..6581f38
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/scenery/randomize.js
@@ -0,0 +1,115 @@
+/*
+ // get the list of media we want to place
+ var media_objs = $(".mediaContainer").toArray().map(function(el){
+ return $(el).data("media")
+ })
+ Scenery.randomize.add( media_objs )
+*/
+
+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)
+ height = media.height/media.width * width
+ }
+ else {
+ height = Math.min(DEFAULT_PICTURE_WIDTH, media.height)
+ width = media.width/media.height * height
+ }
+ return {
+ dimensions: new vec2( width, height ),
+ 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 = {}, removed = [];
+
+ (wall_list || Walls.list).forEach(function(wall){
+ walls[wall.id] = wall
+ })
+
+ // remove the walls that already have stuff on them
+ if (! 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 {
+ delete walls[scenery.wall.id]
+ }
+ })
+ }
+
+ return { walls: walls, removed: removed }
+}
+
+// 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 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 }
+
+ // 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){
+ // 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)) {
+ fits = i
+ break
+ }
+ }
+
+ if (fits != -1) {
+ var wall = walls[wall_ids[fits]]
+ wall_ids.splice(fits, 1)
+
+ var scenery = Scenery.add({
+ media: media.media,
+ wall: wall,
+ index: 0,
+ })
+ scenery.was_randomly_placed = true
+ added.push(scenery.serialize())
+ }
+ else {
+ // artwork won't fit anywhere??
+ }
+
+ return false
+ })
+
+ UndoStack.push({
+ type: "randomize-scenery",
+ undo: { added: added, removed: removed },
+ redo: { added: added, removed: removed },
+ })
+
+} \ No newline at end of file