diff options
Diffstat (limited to 'client/assets/javascripts/rectangles/engine/scenery')
4 files changed, 401 insertions, 0 deletions
diff --git a/client/assets/javascripts/rectangles/engine/scenery/_scenery.js b/client/assets/javascripts/rectangles/engine/scenery/_scenery.js new file mode 100644 index 0000000..867bb6f --- /dev/null +++ b/client/assets/javascripts/rectangles/engine/scenery/_scenery.js @@ -0,0 +1,45 @@ + +var Scenery = new function(){ + + var base = this; + + base.images = [] + + base.mouse = new mouse ({ use_offset: false }) + + base.init = function(){ + base.resize.init() + + var urls = [ + "http://okfocus.s3.amazonaws.com/office/ducks/duck1.jpg", + "http://okfocus.s3.amazonaws.com/office/ducks/duck2.jpg", + "http://okfocus.s3.amazonaws.com/office/ducks/duck3.jpg", + "http://okfocus.s3.amazonaws.com/office/ducks/duck4.jpg", + "http://okfocus.s3.amazonaws.com/office/ducks/duck5.jpg", + ] + var loader = new Loader(function(){ + base.load(loader.images) + }) + loader.preloadImages(urls) + } + + base.load = function(images){ + images.forEach(function(img){ + img.width = 300 + img.height = ~~(300 * img.naturalHeight/img.naturalWidth) + }) + + Rooms.forEach(function(room){ + room.walls.forEach(function(wall){ + var img = choice(images) + if (wall.fits(img)) { + var scene_img = new Scenery.image (wall, img) + base.images.push(scene_img) + scene_img.init() + } + }) + }) + } + + return base +} diff --git a/client/assets/javascripts/rectangles/engine/scenery/image/_image.js b/client/assets/javascripts/rectangles/engine/scenery/image/_image.js new file mode 100644 index 0000000..dadb2d2 --- /dev/null +++ b/client/assets/javascripts/rectangles/engine/scenery/image/_image.js @@ -0,0 +1,52 @@ +Scenery.image = function (wall, img) { + + var base = this + + base.wall = wall + base.img = img + base.dimensions = new vec2(img.width, img.height) + base.center = wall.center() + base.bounds = wall.bounds_for(img) + + // should be proportional to distance from wall + var cursor_amp = 1.5 + + base.init = function(){ + base.build() + base.bind() + } + + base.build = function(){ + base.mx_img = new MX.Image({ + src: img.src, + x: base.center.a, + y: Rooms.list[wall.room].height/2 - img.height/2 - 20, + z: base.center.b, + scale: 300/img.naturalWidth, + rotationY: wall_rotation[ wall.side ], + backface: false, + }) + scene.add( base.mx_img ) + base.move = new Scenery.image.move (base) + } + + base.bind = function(){ + base.move.bind() +// base.resize.bind() + $(base.mx_img.el).bind({ + mouseenter: function(e){ +// console.log('entered an image') + // show the resize points for this image + Scenery.resize.show(base) + Scenery.image.hovering = true + }, + mouseleave: function(e){ +// console.log('left an image') + Scenery.resize.defer_hide(base) + Scenery.image.hovering = false + } + }) + } + + return base +} diff --git a/client/assets/javascripts/rectangles/engine/scenery/image/move.js b/client/assets/javascripts/rectangles/engine/scenery/image/move.js new file mode 100644 index 0000000..e79ede9 --- /dev/null +++ b/client/assets/javascripts/rectangles/engine/scenery/image/move.js @@ -0,0 +1,103 @@ + + +Scenery.image.move = function(base){ + + var x, y, z, bounds + var dragging = false + + this.bind = function(){ + Scenery.mouse.bind_el(base.mx_img.el) + Scenery.mouse.on("down", down) + Scenery.mouse.on("enter", switch_wall) + Scenery.mouse.on("drag", drag) + Scenery.mouse.on("up", up) + } + + this.unbind = function(){ + Scenery.mouse.bind_el(base.mx_img.el) + Scenery.mouse.off("down", down) + Scenery.mouse.off("enter", switch_wall) + Scenery.mouse.off("drag", drag) + Scenery.mouse.off("up", up) + } + + function down (e, cursor){ + if (e.target != base.mx_img.el) return; + dragging = true + x = base.mx_img.x + y = base.mx_img.y + z = base.mx_img.z + bounds = base.bounds + document.body.classList.add("dragging") + } + + function drag (e, cursor){ + if (! dragging) return + + base.mx_img.y = bounds.y.clamp( y - cursor.y.magnitude()*cursor_amp ) + switch (base.wall.side) { + case FRONT: + case BACK: + base.mx_img.x = bounds.x.clamp( x + cos(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) + break + case LEFT: + case RIGHT: + base.mx_img.z = bounds.x.clamp( z + sin(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) + break + } + + Scenery.resize.move_dots() + } + + function up (e, cursor){ + dragging = false + document.body.classList.remove("dragging") + } + + function switch_wall (e, new_wall, cursor){ + if (! dragging) return + if (new_wall.uid == base.wall.uid) return + if (! new_wall.fits(base.img)) return + + base.bounds = bounds = new_wall.bounds_for(base.img) + base.center = new_wall.center() + + x = base.center.a + z = base.center.b + + var wall_group = base.wall.side | new_wall.side + + if (base.wall.side !== new_wall.side && wall_group !== FRONT_BACK && wall_group !== LEFT_RIGHT) { + switch (base.wall.side) { + case FRONT: + z = bounds.x.a + break + case BACK: + z = bounds.x.b + break + case LEFT: + x = bounds.x.a + break + case RIGHT: + x = bounds.x.b + break + } + } + + cursor.x.a = cursor.x.b + + base.mx_img.move({ + x: x, + z: z, + rotationY: wall_rotation[ new_wall.side ] + }) + + base.wall = new_wall + + Scenery.resize.rotate_dots() + Scenery.resize.move_dots() + } + + return this + +}
\ No newline at end of file diff --git a/client/assets/javascripts/rectangles/engine/scenery/image/resize.js b/client/assets/javascripts/rectangles/engine/scenery/image/resize.js new file mode 100644 index 0000000..a0a98c5 --- /dev/null +++ b/client/assets/javascripts/rectangles/engine/scenery/image/resize.js @@ -0,0 +1,201 @@ +Scenery.resize = new function(){ + + var base = this + + var obj + var x, y, z, bounds + var dragging = false + var dimensions, position + + var dots = [], dot, selected_dot + + base.init = function(){ + base.build() + base.bind() + } + + // create 9 dots at the corners of the div + base.build = function(){ + [ TOP, + TOP_RIGHT, + RIGHT, + BOTTOM_RIGHT, + BOTTOM, + BOTTOM_LEFT, + LEFT, + TOP_LEFT ].forEach(base.build_dot) + } + + // generate a dot element + base.build_dot = function(side) { + var dot = new MX.Object3D('.dot') + dot.width = dot.height = dot_side + dot.side = side + $(dot.el).on({ + mouseenter: function(){ base.hovering = true }, + mouseleave: function(){ base.hovering = false }, + }) + dots.push(dot) + } + + base.add_dots = function(){ + dots.forEach(function(dot){ + scene.add(dot) + }) + } + + // rotate the dots as appropriate + base.rotate_dots = function(){ + rotationY = wall_rotation[obj.wall.side] + dots.forEach(function(dot){ + dot.rotationY = rotationY + }) + } + + // move all the dots to the object's current position + base.move_dots = function(){ + x = obj.mx_img.x + sin(rotationY) * dot_distance_from_picture + y = obj.mx_img.y + z = obj.mx_img.z - cos(rotationY) * dot_distance_from_picture + + dots.forEach(function(dot){ + base.move_dot(dot) + }) + } + + // move a dot .. to the initial position of the image + base.move_dot = function(dot){ + dot.x = x + dot.y = y + dot.z = z + + if (dot.side & TOP) { + dot.y += obj.mx_img.height * obj.mx_img.scale / 2 + } + if (dot.side & BOTTOM) { + dot.y -= obj.mx_img.height * obj.mx_img.scale / 2 + } + if (dot.side & LEFT) { + dot.x -= cos(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 + dot.z -= sin(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 + } + if (dot.side & RIGHT) { + dot.x += cos(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 + dot.z += sin(rotationY) * (obj.mx_img.width * obj.mx_img.scale) / 2 + } + } + + // pick a new object to focus on and show the dots + base.show = function(new_object) { + if (obj === new_object) return + + obj = new_object + + base.add_dots() + base.rotate_dots() + base.move_dots() + } + + // dismiss the dots on blur + var dotsHideTimeout; + base.defer_hide = function(){ + clearTimeout(dotsHideTimeout) + + dotsHideTimeout = setTimeout(function(){ + if (Scenery.image.hovering || Scenery.resize.hovering || Scenery.mouse.down) return + Scenery.resize.hide() + }, dot_hide_delay) + } + base.hide = function () { + obj = null + dots.forEach(function(dot){ + scene.remove(dot) + }) + } + + base.bind = function(){ + dots.forEach(function(dot){ + Scenery.mouse.bind_el(dot.el) + $(dot.el).bind({ + mouseenter: function(e){ + Scenery.resize.hovering = true + }, + mouseleave: function(e){ + Scenery.resize.hovering = false + base.defer_hide() + } + }) + }) + Scenery.mouse.on("down", down) + Scenery.mouse.on("drag", drag) + Scenery.mouse.on("up", up) + } + + this.unbind = function(){ + dots.forEach(function(dot){ + Scenery.mouse.unbind_el(dot.el) + }) + Scenery.mouse.off("down", down) + Scenery.mouse.off("drag", drag) + Scenery.mouse.off("up", up) + } + + function down (e, cursor){ + var selection = dots.filter(function(dot){return e.target == dot.el}) + if (! selection.length) return + + selected_dot = selection[0] + dragging = true + + dimensions = new vec2(obj.mx_img.width, obj.mx_img.height) + position = new vec3(obj.mx_img.x, obj.mx_img.y, obj.mx_img.z) + + console.log("down on", sidesToString(selected_dot.side)) + + document.body.classList.add("dragging") + } + + function drag (e, cursor){ + if (! dragging) return + // cursor.x.magnitude()*cursor_amp + + var x_sign = selected_dot.side & LEFT ? -1 : selected_dot.side & RIGHT ? 1 : 0 + var y_sign = selected_dot.side & TOP ? -1 : selected_dot.side & BOTTOM ? 1 : 0 + + var translation = new vec2( x_sign * cursor.x.magnitude() * cursor_amp, y_sign * cursor.y.magnitude() * cursor_amp ) + + if (selected_dot.side & LEFT_RIGHT) { + obj.mx_img.width = dimensions.a + translation.a + obj.mx_img.x = position.a + x_sign * cos(rotationY) * translation.a/2 * obj.mx_img.scale + obj.mx_img.z = position.c + x_sign * sin(rotationY) * translation.a/2 * obj.mx_img.scale + } + if (selected_dot.side & TOP_BOTTOM) { + obj.mx_img.height = dimensions.b + translation.b + obj.mx_img.y = position.b - y_sign * translation.b/2 * obj.mx_img.scale + } + +// bounds = obj.wall.bounds_for(dimensions) + +// base.mx_img.y = bounds.y.clamp( y - cursor.y.magnitude()*cursor_amp ) +// switch (base.wall.side) { +// case FRONT: +// case BACK: +// base.mx_img.x = bounds.x.clamp( x + cos(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) +// break +// case LEFT: +// case RIGHT: +// base.mx_img.z = bounds.x.clamp( z + sin(wall_rotation[base.wall.side]) * cursor.x.magnitude()*cursor_amp ) +// break +// } + + base.move_dots() + + } + + function up (e, cursor){ + dragging = false + selected_dot = null + document.body.classList.remove("dragging") + } + +} |
