From c6eea0f4887ba14e5a6ecfff8c9e8480ae6421c1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 2 Apr 2015 17:05:31 -0400 Subject: placing objects on the floor --- public/assets/javascripts/ui/editor/EditorSettings.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index b319404..460863e 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -77,6 +77,7 @@ var EditorSettings = FormView.extend({ data.privacy && this.$privacy.find("[value=" + data.privacy + "]").prop("checked", "checked") data.media && Scenery.deserialize(data.media) + data.sculpture && Sculpture.deserialize(data.sculpture) } }, @@ -112,6 +113,7 @@ var EditorSettings = FormView.extend({ clear: function(e){ e.preventDefault() Scenery.removeAll() + Sculpture.removeAll() }, destroy: function(){ @@ -191,6 +193,7 @@ var EditorSettings = FormView.extend({ fd.append( "walls", JSON.stringify( Walls.serialize() ) ) fd.append( "colors", JSON.stringify( Walls.colors ) ) fd.append( "media", JSON.stringify( Scenery.serialize() ) ) + fd.append( "sculpture", JSON.stringify( Sculpture.serialize() ) ) fd.append( "startPosition", JSON.stringify( this.startPosition || false ) ) fd.append( "lastPosition", JSON.stringify( app.position(scene.camera) ) ) -- cgit v1.2.3-70-g09d2 From 519ff21e00c5c48d06e1ddee0cdc1dc3d90a26f8 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 3 Apr 2015 18:40:04 -0400 Subject: pulling in move code / view code --- .../rectangles/engine/scenery/resize.js | 1 + .../rectangles/engine/sculpture/move.js | 158 ++++++++++++++++ .../rectangles/engine/sculpture/types/_object.js | 22 ++- .../rectangles/engine/sculpture/types/image.js | 18 -- public/assets/javascripts/ui/editor/EditorView.js | 10 +- .../javascripts/ui/editor/SculptureEditor.js | 200 +++++++++++++++++++++ views/partials/scripts.ejs | 2 + 7 files changed, 390 insertions(+), 21 deletions(-) create mode 100644 public/assets/javascripts/rectangles/engine/sculpture/move.js create mode 100644 public/assets/javascripts/ui/editor/SculptureEditor.js (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index 73fd82a..a5e255a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -49,6 +49,7 @@ Scenery.resize = new function(){ // rotate the dots as appropriate base.rotate_dots = function(){ + console.trace() rotationY = obj.wall.rotationY dots.forEach(function(dot){ dot.rotationY = rotationY diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js new file mode 100644 index 0000000..b5a4b40 --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js @@ -0,0 +1,158 @@ + +Sculpture.move = function(base){ + + var x, y, z, position, dimension, bounds + var dragging = false, moved = false + var oldState + + this.bind = function(){ + Sculpture.mouse.bind_el(base.mx.el) + Sculpture.mouse.on("down", down) + Sculpture.mouse.on("enter", switch_wall) + Sculpture.mouse.on("drag", drag) + Sculpture.mouse.on("up", up) + } + + this.unbind = function(){ + base.focused = false + Sculpture.mouse.unbind_el(base.mx.el) + Sculpture.mouse.off("down", down) + Sculpture.mouse.off("enter", switch_wall) + Sculpture.mouse.off("drag", drag) + Sculpture.mouse.off("up", up) + } + + function down (e, cursor){ + if (e.target != base.mx.el && (e.target != base.mx.overlay)) return; + if (editor.permissions.destroy) { + base.remove() + return + } + + // 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 + } + dragging = true + moved = false + x = base.mx.x + y = base.mx.y + z = base.mx.z + + bounds = base.bounds + dimension = base.dimensions + position = base.wall.mxToPosition( base.mx, dimension ) + + oldState = base.serialize() + document.body.classList.add("dragging") + } + + function drag (e, cursor){ + if (! dragging) return + + moved = true + + var flipX = base.wall.side & (FRONT | RIGHT) + + var delta = cursor.delta() + delta.mul( cursor_amp ) // TODO: this should be proportional to your distance from the wall + if (flipX) { delta.a *= -1 } + delta.b *= -1 + + var new_bounds = base.wall.surface.translate( bounds, dimension, position, delta ) + if (new_bounds) bounds = new_bounds + if (flipX) { delta.a *= -1 } + + base.mx.y = position.b + delta.b + dimension.b / 2 + switch (base.wall.side) { + case FRONT: + case BACK: + base.mx.x = position.a + delta.a * cos(base.wall.rotationY) + dimension.a / 2 + break + case LEFT: + case RIGHT: + base.mx.z = position.a + delta.a * sin(base.wall.rotationY) + dimension.a / 2 + break + } + + if (editor.permissions.resize) { + Sculpture.resize.move_dots() + } + } + + function up (e, cursor){ + if (! dragging || ! oldState) return + + if (moved) { + UndoStack.push({ + type: 'update-sculpture', + undo: oldState, + redo: base.serialize(), + }) + + // TODO: watch individual sculpture object here + Minotaur.watch( app.router.editorView.settings ) + } + + dragging = moved = false + oldState = null + document.body.classList.remove("dragging") + } + + function switch_wall (e, target, cursor){ + if (! dragging) return + if (target.wall.id == base.wall.id) return + + var old_wall_side = base.wall.side + var wall_group = old_wall_side | target.wall.side + var new_bounds = target.wall.surface.bounds_at_index_with_dimensions(target.index || 0, dimension) + + if (! new_bounds) return + + base.wall = target.wall + base.bounds = bounds = new_bounds + + position.a = bounds.x.midpoint() - dimension.a / 2 + + if (old_wall_side !== target.wall.side && wall_group !== FRONT_BACK && wall_group !== LEFT_RIGHT) { + switch (old_wall_side) { + case FRONT: + position.a = bounds.x.a + dimension.a / 2 + break + case BACK: + position.a = bounds.x.b - dimension.a / 2 + break + case LEFT: + position.a = bounds.x.a + dimension.a / 2 + break + case RIGHT: + position.a = bounds.x.b - dimension.a / 2 + break + } + } + + var mx_delta = base.wall.positionToMx( position, dimension ) + base.mx.move(mx_delta) + + if (editor.permissions.resize) { + Sculpture.resize.rotate_dots() + Sculpture.resize.move_dots() + } + + cursor.x.a = cursor.x.b + //var delta = cursor.delta() + drag(e, cursor) + + } + + return this + +} \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index fa6b0b1..6c93b41 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -8,8 +8,14 @@ Sculpture.types.base = Fiber.extend(function(base){ this.media = opt.media this.naturalDimensions = new vec2(this.media.width, this.media.height) + this.move = new Sculpture.move (this) + this.billboard = true + this.backface = true + this.set_scale( opt.scale || this.media.scale || 1.0 ) this.position = new vec2(0,0) + + this.isSculpture = true }, set_scale: function(scale){ @@ -30,11 +36,11 @@ Sculpture.types.base = Fiber.extend(function(base){ }, bind: function(){ - // this.move.bind() + this.move.bind() }, unbind: function(){ - // this.move.unbind() + this.move.unbind() }, remove: function(){ @@ -81,9 +87,21 @@ Sculpture.types.base = Fiber.extend(function(base){ position: app.position(this.mx), scale: this.scale, media: this.media, + billboard: this.billboard, + backface: this.backface, } return data }, + + deserialize: function(data){ + this.mx.move(data.position) + this.mx.ops.width = data.dimensions.a + this.mx.ops.height = data.dimensions.b + this.billboard = data.billboard + this.backface = data.backface + if (! this.backface) this.mx.el.classList.remove("backface-visible") + this.dimensions.deserialize(data.dimensions) + }, } return exports diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js index 9e8de58..3e5ab08 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/image.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/image.js @@ -27,29 +27,11 @@ Sculpture.types.image = Sculpture.types.base.extend(function(base){ if (opt.position) { opt.position.y = opt.position.y || this.scale * this.media.height/2 + 3 opt.position.rotationY = opt.position.rotationY || scene.camera.rotationY - this.billboard = true - this.backface = true } scene.add( this.mx ) }, - serialize: function(){ - var data = base.serialize.call(this) - data.billboard = this.billboard - data.backface = this.backface - return data - }, - - deserialize: function(data){ - this.mx.move(data.position) - this.mx.ops.width = data.dimensions.a - this.mx.ops.height = data.dimensions.b - this.billboard = data.billboard - this.backface = data.backface - if (! this.backface) this.mx.el.classList.remove("backface-visible") - this.dimensions.deserialize(data.dimensions) - }, } return exports diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index 50d3650..e5e2ca0 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -17,6 +17,7 @@ var EditorView = View.extend({ this.mediaUpload = new MediaUpload ({ parent: this }) this.mediaTumblr = new MediaTumblr ({ parent: this }) this.mediaEditor = new MediaEditor ({ parent: this }) + this.sculptureEditor = new SculptureEditor ({ parent: this }) this.wallpaperPicker = new WallpaperPicker ({ parent: this }) this.colorControl = new ColorControl ({ parent: this }) this.textEditor = new TextEditor ({ parent: this }) @@ -56,12 +57,19 @@ var EditorView = View.extend({ }, pick: function(scenery){ - if (scenery.type == "text") { + if (scenery.isSculpture) { this.mediaEditor.hide() + this.textEditor.hide() + this.sculptureEditor.pick(scenery) + } + else if (scenery.type == "text") { + this.mediaEditor.hide() + this.sculptureEditor.hide() this.textEditor.pick(scenery) } else { this.textEditor.hide() + this.sculptureEditor.hide() this.mediaEditor.pick(scenery) } }, diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js new file mode 100644 index 0000000..cce000e --- /dev/null +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -0,0 +1,200 @@ + +var SculptureEditor = FormView.extend({ + el: "#sculptureEditor", + + events: { + "keydown": 'taint', + "focus [name]": "clearMinotaur", + "click [data-role=play-media]": "togglePaused", + "mousedown [name=keyframe]": "stopPropagation", + "mousedown": "stopPropagation", + "change [name=keyframe]": "seek", + "change [name=autoplay]": "setAutoplay", + "change [name=loop]": "setLoop", + "change [name=mute]": "setMute", + "change [name=width]": 'changeWidth', + "change [name=height]": 'changeHeight', + "change [name=units]": 'changeUnits', + "click [data-role=destroy-media]": "destroy", + }, + + initialize: function(opt){ + this.parent = opt.parent + this.__super__.initialize.call(this) + + this.$name = this.$("[name=name]") + this.$description = this.$("[name=description]") + + // image fields + this.$width = this.$("[name=width]") + this.$height = this.$("[name=height]") + this.$units = this.$("[name=units]") + + // video fields + this.$playButton = this.$("[data-role=play-media]") + this.$autoplay = this.$("[name=autoplay]") + this.$loop = this.$("[name=loop]") + this.$mute = this.$("[name=mute]") + this.$keyframe = this.$("[name=keyframe]") + }, + + toggle: function(state) { + if (state) { + this.parent.settings.toggle() + } + this.$el.toggleClass("active", state); + }, + + togglePaused: function(state){ + var state = this.sculpture.toggle(state) + this.$playButton.toggleClass("paused", ! state) + }, + + pick: function(sculpture) { + if (this.sculpture && sculpture !== this.sculpture) { + this.unbind() + } + + this.bind(sculpture) + this.$el.addClass("active") + +// app.controller.toolbar.resetMode() + app.controller.toolbar.resetControls() + // Sculpture.resize.show(sculpture) + Sculpture.hovering = true + + var media = sculpture.media + + // console.log(media) + + this.$name.val(media.title) // || filenameFromUrl(media.url) ) + this.$description.val(media.description) + this.setDimensions() + this.$units.val( "ft" ) + + switch (media.type) { + case "image": + this.$(".video").hide() + this.$(".audio").hide() + this.$(".image").show() + break + + case "youtube": + case "vimeo": + case "video": + this.$(".image").hide() + this.$(".audio").hide() + this.$(".video").show() + + this.$playButton.toggleClass("paused", ! this.sculpture.paused()) + this.$autoplay.prop('checked', !! media.autoplay) + this.$loop.prop('checked', !! media.loop) + this.$mute.prop('checked', !! media.mute) + this.$keyframe.val( Number(media.keyframe || 0) ) + break + + case "soundcloud": + this.$(".image").hide() + this.$(".video").hide() + this.$(".audio").show() + this.$playButton.toggleClass("paused", ! this.sculpture.paused()) + this.$autoplay.prop('checked', !! media.autoplay) + this.$loop.prop('checked', !! media.loop) + break + } + }, + + hide: function(sculpture){ + if (this.sculpture) { + this.unbind() + } + this.toggle(false) + }, + + seek: function(){ + var n = parseFloat( this.$keyframe.val() ) + this.sculpture.seek(n) + this.tainted = true + + this.sculpture.media.keyframe = n + }, + setAutoplay: function(){ + var checked = this.$autoplay.prop('checked') + this.sculpture.media.autoplay = checked + this.tainted = true + if (checked && this.sculpture.paused()) { + this.togglePaused() + } + }, + setLoop: function(){ + var checked = this.$loop.prop('checked') + this.sculpture.setLoop(checked) + this.tainted = true + }, + setMute: function(){ + var checked = this.$mute.prop('checked') + this.sculpture.media.mute = checked + this.sculpture.mute(checked) + this.tainted = true + }, + + setDimensions: function(){ + if (! this.sculpture) return + this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" ) + this.$height.unitVal( Number(this.sculpture.naturalDimensions.b * this.sculpture.scale) || "" ) + this.tainted = true + }, + changeWidth: function(e){ + e.stopPropagation() + this.sculpture.set_scale( this.$width.unitVal() / this.sculpture.naturalDimensions.a ) + this.setDimensions() + }, + changeHeight: function(e){ + e.stopPropagation() + this.sculpture.set_scale( this.$height.unitVal() / this.sculpture.naturalDimensions.b ) + this.setDimensions() + }, + changeUnits: function(){ + app.units = this.$units.val() + this.$('.units').resetUnitVal() + }, + + taint: function(e){ + e.stopPropagation() + this.tainted = true + }, + + bind: function(sculpture){ + this.sculpture = sculpture + this.sculpture.mx.bound = true + this.sculpture.mx.el.classList.add("picked") + }, + + unbind: function(){ + if (this.sculpture) { + this.sculpture.focused = false + if (this.tainted && this.sculpture.media) { + this.sculpture.media.title = this.$name.val() + this.sculpture.media.description = this.$description.val() + Minotaur.watch( app.router.editorView.settings ) + } + if (this.sculpture.mx) { + this.sculpture.mx.bound = false + this.sculpture.mx.el.classList.remove("picked") + } + } + this.tainted = false + this.sculpture = null + }, + + destroy: function(){ + var sculpture = this.sculpture + this.hide() + + sculpture.remove() + + this.tainted = false + this.sculpture = null + }, + +}) diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index ca6cc94..1eda8bd 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -74,6 +74,7 @@ + @@ -124,6 +125,7 @@ + -- cgit v1.2.3-70-g09d2 From 24543d0839ad51b2afa7195b16d29bc52b3f1a1b Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 13:15:19 -0400 Subject: remove sculpture --- .../javascripts/mx/extensions/mx.movements.js | 5 +++- .../rectangles/engine/sculpture/types/_object.js | 12 +++++++++ .../javascripts/ui/editor/SculptureEditor.js | 31 +++++++++++++++++++++- public/assets/stylesheets/app.css | 3 +++ views/controls/editor/sculpture.ejs | 10 +++---- 5 files changed, 54 insertions(+), 7 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/mx/extensions/mx.movements.js b/public/assets/javascripts/mx/extensions/mx.movements.js index bc71fc4..931caac 100644 --- a/public/assets/javascripts/mx/extensions/mx.movements.js +++ b/public/assets/javascripts/mx/extensions/mx.movements.js @@ -162,7 +162,10 @@ MX.Movements = function (cam) { case 8: // backspace e.preventDefault() - if (app.controller.mediaEditor.scenery) { + if (app.controller.sculptureEditor.sculpture) { + app.controller.sculptureEditor.sculpture.remove() + } + else if (app.controller.mediaEditor.scenery) { app.controller.mediaEditor.scenery.remove() } else if (app.controller.textEditor.scenery) { diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index 6c93b41..48fd96a 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -43,6 +43,18 @@ Sculpture.types.base = Fiber.extend(function(base){ this.move.unbind() }, + setOutline: function(val){ + this.outline = val + // show/hide outline + }, + setOutlineColor: function(val){ + this.outlineColor = val + // set outline color + }, + setBillboard: function(val){ + this.billboard = val + }, + remove: function(){ if (this.removed) return this.removed = true diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index cce000e..ab0ccd2 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -10,12 +10,15 @@ var SculptureEditor = FormView.extend({ "mousedown": "stopPropagation", "change [name=keyframe]": "seek", "change [name=autoplay]": "setAutoplay", + "change [name=billboard]": "setBillboard", + "change [name=outline]": "setOutline", + "change [name=outlineColor]": "setOutlineColor", "change [name=loop]": "setLoop", "change [name=mute]": "setMute", "change [name=width]": 'changeWidth', "change [name=height]": 'changeHeight', "change [name=units]": 'changeUnits', - "click [data-role=destroy-media]": "destroy", + "click [data-role=destroy-sculpture]": "destroy", }, initialize: function(opt){ @@ -25,6 +28,10 @@ var SculptureEditor = FormView.extend({ this.$name = this.$("[name=name]") this.$description = this.$("[name=description]") + this.$billboard = this.$("[name=billboard]") + this.$outline = this.$("[name=outline]") + this.$outlineColor = this.$("[name=outlineColor]") + // image fields this.$width = this.$("[name=width]") this.$height = this.$("[name=height]") @@ -71,6 +78,11 @@ var SculptureEditor = FormView.extend({ this.$description.val(media.description) this.setDimensions() this.$units.val( "ft" ) + + this.$outline.prop( 'checked', !! media.outline ) + this.$outlineColor.val( media.outlineColor ) + this.$billboard.prop( 'checked', !! media.billboard ) + switch (media.type) { case "image": @@ -138,6 +150,23 @@ var SculptureEditor = FormView.extend({ this.tainted = true }, + + setBillboard: function(){ + var checked = this.$billboard.prop('checked') + this.sculpture.setBillboard(checked) + this.tainted = true + }, + setOutline: function(){ + var checked = this.$outline.prop('checked') + this.sculpture.setOutline(checked) + this.tainted = true + }, + setOutlineColor: function(){ + var color = this.$outlineColor.val() + this.sculpture.setOutlineColor(color) + this.tainted = true + }, + setDimensions: function(){ if (! this.sculpture) return this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" ) diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index b23b50b..6e97500 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -2455,6 +2455,9 @@ input[type="range"]::-webkit-slider-thumb { #mediaEditor .setting.number [type=text] { width: 140px; } +#sculptureEditor .setting.number input[type=text] { + width: 130px; +} .playButton,.muteButton { border-radius: 50%; diff --git a/views/controls/editor/sculpture.ejs b/views/controls/editor/sculpture.ejs index 21e5039..4b8535a 100644 --- a/views/controls/editor/sculpture.ejs +++ b/views/controls/editor/sculpture.ejs @@ -13,14 +13,14 @@
- - - + + +
- - + +
-- cgit v1.2.3-70-g09d2 From 546fba7ee9dac48d2fb0015709247b1b2efca8bc Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 14:31:24 -0400 Subject: store billboard setting --- public/assets/javascripts/rectangles/engine/scenery/resize.js | 2 +- .../javascripts/rectangles/engine/sculpture/types/_object.js | 6 ++++++ public/assets/javascripts/ui/editor/EditorView.js | 1 + public/assets/javascripts/ui/editor/SculptureEditor.js | 7 +++---- 4 files changed, 11 insertions(+), 5 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index a5e255a..006ff2a 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -49,7 +49,7 @@ Scenery.resize = new function(){ // rotate the dots as appropriate base.rotate_dots = function(){ - console.trace() + // console.trace() rotationY = obj.wall.rotationY dots.forEach(function(dot){ dot.rotationY = rotationY diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index 489a6a1..b903c5b 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -54,9 +54,13 @@ Sculpture.types.base = Fiber.extend(function(base){ setBillboard: function(val){ this.billboard = val if (this.billboard) { + this.mx.el.classList.add("backface-visible") + this.mx.el.classList.remove("backface-hidden") this.mx.rotationY = cam.rotationY } else { + this.mx.el.classList.add("backface-hidden") + this.mx.el.classList.remove("backface-visible") this.mx.rotationY = PI/2 } }, @@ -106,6 +110,8 @@ Sculpture.types.base = Fiber.extend(function(base){ scale: this.scale, media: this.media, billboard: this.billboard, + outline: this.outline, + outlineColor: this.outlineColor, backface: this.backface, } return data diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index e5e2ca0..a7b4f20 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -80,6 +80,7 @@ var EditorView = View.extend({ }, hideExtras: function(){ + this.sculptureEditor.hide() this.mediaEditor.hide() this.textEditor.hide() this.share.hide() diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index ab0ccd2..ff1e6b9 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -79,10 +79,9 @@ var SculptureEditor = FormView.extend({ this.setDimensions() this.$units.val( "ft" ) - this.$outline.prop( 'checked', !! media.outline ) - this.$outlineColor.val( media.outlineColor ) - this.$billboard.prop( 'checked', !! media.billboard ) - + this.$outline.prop( 'checked', !! sculpture.outline ) + this.$outlineColor.val( sculpture.outlineColor || "#000000" ) + this.$billboard.prop( 'checked', !! sculpture.billboard ) switch (media.type) { case "image": -- cgit v1.2.3-70-g09d2 From 0b8b54e26aa7a40065a0be6f7708b7021e4fec13 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 20 Apr 2015 15:03:35 -0400 Subject: resize scenery --- Gruntfile.js | 1 + .../rectangles/engine/scenery/resize.js | 1 + .../rectangles/engine/sculpture/_sculpture.js | 4 + .../rectangles/engine/sculpture/move.js | 6 +- .../rectangles/engine/sculpture/resize.js | 207 +++++++++++++++++++++ .../rectangles/engine/sculpture/types/_object.js | 2 +- .../assets/javascripts/rectangles/models/floor.js | 2 +- public/assets/javascripts/ui/editor/EditorView.js | 1 + .../javascripts/ui/editor/SculptureEditor.js | 3 +- views/partials/scripts.ejs | 1 + 10 files changed, 221 insertions(+), 7 deletions(-) create mode 100644 public/assets/javascripts/rectangles/engine/sculpture/resize.js (limited to 'public/assets/javascripts/ui/editor') diff --git a/Gruntfile.js b/Gruntfile.js index 026ec6f..789ce6f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -79,6 +79,7 @@ module.exports = function(grunt) { "public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js", "public/assets/javascripts/rectangles/engine/sculpture/move.js", + "public/assets/javascripts/rectangles/engine/sculpture/resize.js", "public/assets/javascripts/rectangles/engine/sculpture/types/_object.js", "public/assets/javascripts/rectangles/engine/sculpture/types/image.js", diff --git a/public/assets/javascripts/rectangles/engine/scenery/resize.js b/public/assets/javascripts/rectangles/engine/scenery/resize.js index 006ff2a..8dac140 100644 --- a/public/assets/javascripts/rectangles/engine/scenery/resize.js +++ b/public/assets/javascripts/rectangles/engine/scenery/resize.js @@ -8,6 +8,7 @@ Scenery.resize = new function(){ var dragging = false var naturalDimension, naturalDimensionCopy, dimension, position, scale var oldState + var rotationY var dots = [], dot, selected_dot diff --git a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js index 1543def..888b925 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/_sculpture.js @@ -9,6 +9,7 @@ var Sculpture = new function(){ base.init = function(){ app.on("move", base.updateBillboards) + base.resize.init() } base.updateBillboards = function(){ @@ -17,6 +18,9 @@ var Sculpture = new function(){ sculpture.mx.rotationY = cam.rotationY } }) + if (Sculpture.resize.obj && Sculpture.resize.obj.billboard) { + Sculpture.resize.move_dots() + } } base.add = function(opt){ diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js index 28d707e..f968bcf 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/move.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js @@ -66,9 +66,9 @@ Sculpture.move = function(base){ base.mx.x = x + delta.a * cos(cam.rotationY) - delta.b * sin(cam.rotationY) base.mx.z = z + delta.a * sin(cam.rotationY) + delta.b * cos(cam.rotationY) -// if (editor.permissions.resize) { -// Sculpture.resize.move_dots() -// } + if (editor.permissions.resize) { + Sculpture.resize.move_dots() + } } function up (e, cursor){ diff --git a/public/assets/javascripts/rectangles/engine/sculpture/resize.js b/public/assets/javascripts/rectangles/engine/sculpture/resize.js new file mode 100644 index 0000000..53b8b2d --- /dev/null +++ b/public/assets/javascripts/rectangles/engine/sculpture/resize.js @@ -0,0 +1,207 @@ +Sculpture.resize = new function(){ + + var base = this + + var obj + var x, y, z, bounds + var dragging = false + var naturalDimension, naturalDimensionCopy, dimension, position, scale + var oldState + var rotationY + + 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 * 2 + dot.scale = 0.5 + 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) + }) + } + + // move all the dots to the object's current position + base.move_dots = function(){ + rotationY = obj.mx.rotationY + + var x = obj.mx.x + sin(rotationY) * dot_distance_from_picture + var y = obj.mx.y + var z = obj.mx.z - cos(rotationY) * dot_distance_from_picture + + dots.forEach(function(dot){ + base.move_dot(dot, { x: x, y: y, z: z, rotationY: rotationY }) + }) + } + + // move a dot .. to the initial position of the image + base.move_dot = function(dot, pos){ + if (dot.side & TOP) { + pos.y += obj.dimensions.b / 2 + } + if (dot.side & BOTTOM) { + pos.y -= obj.dimensions.b / 2 + } + if (dot.side & LEFT) { + pos.x -= cos(rotationY) * (obj.dimensions.a) / 2 + pos.z -= sin(rotationY) * (obj.dimensions.a) / 2 + } + if (dot.side & RIGHT) { + pos.x += cos(rotationY) * (obj.dimensions.a) / 2 + pos.z += sin(rotationY) * (obj.dimensions.a) / 2 + } + dot.move(pos) + } + + // pick a new object to focus on and show the dots + base.show = function(new_object) { + // if (obj === new_object) return + if (! new_object) return + base.obj = obj = new_object + base.add_dots() + base.move_dots() + } + + // dismiss the dots on blur + var dotsHideTimeout; + base.defer_hide = function(){ + clearTimeout(dotsHideTimeout) + + dotsHideTimeout = setTimeout(function(){ + if (Scenery.hovering || Scenery.resize.hovering || Scenery.mouse.down) return + Scenery.resize.hide() + }, dot_hide_delay) + } + + base.hide = function () { + if (! obj) return + base.obj = obj = null + dots.forEach(function(dot){ + scene.remove(dot) + }) + } + + base.bind = function(){ + dots.forEach(function(dot){ + Sculpture.mouse.bind_el(dot.el) + }) + Sculpture.mouse.on("down", down) + Sculpture.mouse.on("drag", drag) + Sculpture.mouse.on("up", up) + } + + base.unbind = function(){ + dots.forEach(function(dot){ + Sculpture.mouse.unbind_el(dot.el) + }) + Sculpture.mouse.off("down", down) + Sculpture.mouse.off("drag", drag) + Sculpture.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 + + naturalDimension = obj.naturalDimensions + 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") + } + + function drag (e, cursor){ + if (! dragging) return + + 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 width = cursor.x.magnitude() + var height = cursor.y.magnitude() + var mag = cursor.magnitude() + + if (abs(width) > abs(height)) { + mag = x_sign * mag * sign(width) + } + else { + mag = y_sign * mag * sign(height) + } + + 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 + } + + base.move_dots() + + app.controller.sculptureEditor.setDimensions() + } + + function up (e, cursor){ + if (! dragging) return + dragging = false + if (! editor.permissions.resize) { return } + + obj.scale = obj.mx.ops.scale = obj.mx.scale + obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale) + + UndoStack.push({ + type: 'update-sculpture', + undo: oldState, + redo: obj.serialize(), + }) + + // TODO: watch individual scenery object here + Minotaur.watch( app.router.editorView.settings ) + + document.body.classList.remove("dragging") + selected_dot = null + } +} \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index b903c5b..390c42e 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -80,7 +80,7 @@ Sculpture.types.base = Fiber.extend(function(base){ Sculpture.remove(this.id) - // Sculpture.resize.hide() + Sculpture.resize.hide() if (app.controller.sculptureEditor) { app.controller.sculptureEditor.tainted = false app.controller.sculptureEditor.hide() diff --git a/public/assets/javascripts/rectangles/models/floor.js b/public/assets/javascripts/rectangles/models/floor.js index 530de2b..799bdc7 100644 --- a/public/assets/javascripts/rectangles/models/floor.js +++ b/public/assets/javascripts/rectangles/models/floor.js @@ -90,7 +90,7 @@ } app.controller.toolbar.resetPermissions() - // Sculpture.resize.show(sculpture) + Sculpture.resize.show(sculpture) Sculpture.hovering = true // app.controller.pick(sculpture) diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index a7b4f20..a2d84a6 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -84,6 +84,7 @@ var EditorView = View.extend({ this.mediaEditor.hide() this.textEditor.hide() this.share.hide() + Sculpture.resize.hide() Scenery.resize.hide() Scenery.hovering = false } diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index ff1e6b9..35abc00 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -67,7 +67,7 @@ var SculptureEditor = FormView.extend({ // app.controller.toolbar.resetMode() app.controller.toolbar.resetControls() - // Sculpture.resize.show(sculpture) + Sculpture.resize.show(sculpture) Sculpture.hovering = true var media = sculpture.media @@ -149,7 +149,6 @@ var SculptureEditor = FormView.extend({ this.tainted = true }, - setBillboard: function(){ var checked = this.$billboard.prop('checked') this.sculpture.setBillboard(checked) diff --git a/views/partials/scripts.ejs b/views/partials/scripts.ejs index 1eda8bd..6dfe912 100644 --- a/views/partials/scripts.ejs +++ b/views/partials/scripts.ejs @@ -75,6 +75,7 @@ + -- cgit v1.2.3-70-g09d2 From 90b0e89b4dabf67035ae4bccdb02c52da4e31ab1 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Apr 2015 19:49:27 -0400 Subject: infoboxes on sculpture --- public/assets/javascripts/ui/editor/SculptureEditor.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index 35abc00..52663e1 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -73,9 +73,8 @@ var SculptureEditor = FormView.extend({ var media = sculpture.media // console.log(media) - - this.$name.val(media.title) // || filenameFromUrl(media.url) ) - this.$description.val(media.description) + this.$name.val(media.title || "") // || filenameFromUrl(media.url) ) + this.$description.val(media.description || "") this.setDimensions() this.$units.val( "ft" ) -- cgit v1.2.3-70-g09d2 From 53695472cfb20b730d04b2d6a6a16c6d281e9180 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 27 Apr 2015 20:47:41 -0400 Subject: outline box --- .../rectangles/engine/sculpture/move.js | 1 + .../rectangles/engine/sculpture/resize.js | 3 +- .../rectangles/engine/sculpture/types/_object.js | 52 +++++++++++++++++++--- .../assets/javascripts/rectangles/models/vec3.js | 18 +++++++- .../javascripts/rectangles/util/measurement.js | 4 ++ .../javascripts/ui/editor/SculptureEditor.js | 11 +++++ public/assets/stylesheets/app.css | 7 +++ views/controls/editor/sculpture.ejs | 2 +- 8 files changed, 90 insertions(+), 8 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/sculpture/move.js b/public/assets/javascripts/rectangles/engine/sculpture/move.js index e571c3b..0cbeccd 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/move.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/move.js @@ -83,6 +83,7 @@ Sculpture.move = function(base){ if (editor.permissions.resize) { Sculpture.resize.move_dots() + base.updateOutline() } } diff --git a/public/assets/javascripts/rectangles/engine/sculpture/resize.js b/public/assets/javascripts/rectangles/engine/sculpture/resize.js index 53b8b2d..5f21d66 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/resize.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/resize.js @@ -180,7 +180,8 @@ Sculpture.resize = new function(){ } base.move_dots() - + obj.updateOutline() + app.controller.sculptureEditor.setDimensions() } diff --git a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js index 5dd0aae..2f24ae5 100644 --- a/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js +++ b/public/assets/javascripts/rectangles/engine/sculpture/types/_object.js @@ -6,7 +6,8 @@ Sculpture.types.base = Fiber.extend(function(base){ this.id = opt.id || Sculpture.uid("sculpture") // this.move = new Sculpture.move (this) this.media = opt.media - this.naturalDimensions = new vec2(this.media.width, this.media.height) + this.naturalDimensions = new vec3(this.media.width, this.media.height, this.media.width) + this.dimensions = new vec3(this.media.width, this.media.height, this.media.width) this.move = new Sculpture.move (this) this.billboard = true @@ -14,7 +15,7 @@ Sculpture.types.base = Fiber.extend(function(base){ this.set_scale( opt.scale || this.media.scale || 1.0 ) this.position = new vec2(0,0) - + this.isSculpture = true }, @@ -25,6 +26,11 @@ Sculpture.types.base = Fiber.extend(function(base){ } this.dimensions = this.naturalDimensions.clone().mul(this.scale) }, + set_depth: function(depth){ + console.log(this.dimensions.c, this.naturalDimensions.c, depth) + this.dimensions.c = depth + this.naturalDimensions.c = depth / this.scale + }, place: function(opt){ if (opt.data) { @@ -45,11 +51,16 @@ Sculpture.types.base = Fiber.extend(function(base){ setOutline: function(val){ this.outline = val - // show/hide outline + if (val && ! this.outlineEl) { + this.buildOutline() + } + this.outlineEl.el.style.display = val ? "block" : "none" }, setOutlineColor: function(val){ this.outlineColor = val - // set outline color + if (this.outlineEl) { + this.outlineColor = this.outlineEl.el.style.borderColor = val + } }, setBillboard: function(val){ this.billboard = val @@ -65,6 +76,32 @@ Sculpture.types.base = Fiber.extend(function(base){ } Sculpture.resize.move_dots() }, + + buildOutline: function(){ + this.outlineEl = new MX.Object3D(".mx-outline") + this.outlineEl.width = this.naturalDimensions.a + this.outlineEl.height = this.naturalDimensions.c + this.outlineEl.scale = this.mx.scale + this.outlineEl.rotationX = -PI/2 + this.outlineEl.x = this.mx.x + this.outlineEl.y = sculpture_distance_from_floor + this.outlineEl.z = this.mx.z + this.outlineEl.el.style.borderColor = this.outlineColor || "#000000" + scene.add(this.outlineEl) + }, + updateOutline: function(){ + if (! this.outline) { return } + if (! this.outlineEl) { + this.buildOutline() + } + this.outlineEl.x = this.mx.x + this.outlineEl.y = sculpture_distance_from_floor + this.outlineEl.z = this.mx.z + this.outlineEl.width = this.naturalDimensions.a + this.outlineEl.height = this.naturalDimensions.c + + this.outlineEl.scale = this.mx.scale + }, remove: function(){ if (this.removed) return @@ -112,7 +149,7 @@ Sculpture.types.base = Fiber.extend(function(base){ media: this.media, billboard: this.billboard, outline: this.outline, - outlineColor: this.outlineColor, + outlineColor: this.outlineColor || "#000000", backface: this.backface, } return data @@ -123,9 +160,14 @@ Sculpture.types.base = Fiber.extend(function(base){ this.mx.ops.width = data.dimensions.a this.mx.ops.height = data.dimensions.b this.billboard = data.billboard + this.outline = data.outline + this.outlineColor = data.outlineColor || "#000000" this.backface = data.backface if (! this.backface) this.mx.el.classList.remove("backface-visible") this.dimensions.deserialize(data.dimensions) + if (this.outline) { + this.buildOutline() + } }, } diff --git a/public/assets/javascripts/rectangles/models/vec3.js b/public/assets/javascripts/rectangles/models/vec3.js index 97329ed..b3825a9 100644 --- a/public/assets/javascripts/rectangles/models/vec3.js +++ b/public/assets/javascripts/rectangles/models/vec3.js @@ -39,5 +39,21 @@ vec3.prototype.serialize = function(){ vec3.prototype.deserialize = function(data){ this.a = data[0] this.b = data[1] - this.c = data[2] + this.c = data[2] || data[0] + return this +} +vec3.prototype.clone = function(){ + return new vec3(this.a, this.b, this.c) +} +vec3.prototype.assign = function(v){ + this.a = v.a + this.b = v.b + this.c = v.c + return this +} +vec3.prototype.mul = function(n) { + this.a *= n + this.b *= n + this.c *= n + return this } \ No newline at end of file diff --git a/public/assets/javascripts/rectangles/util/measurement.js b/public/assets/javascripts/rectangles/util/measurement.js index d6a0b35..6346eac 100644 --- a/public/assets/javascripts/rectangles/util/measurement.js +++ b/public/assets/javascripts/rectangles/util/measurement.js @@ -28,6 +28,10 @@ function measurementToString( n ) { case 'ft': ft = floor(n / 36) inch = abs(round((n % 36) / 3)) + if (inch == 12) { + inch = 0 + ft += 1 + } s = ft + "'" if (inch > 0) { s += " " + inch + '"' diff --git a/public/assets/javascripts/ui/editor/SculptureEditor.js b/public/assets/javascripts/ui/editor/SculptureEditor.js index 52663e1..953260c 100644 --- a/public/assets/javascripts/ui/editor/SculptureEditor.js +++ b/public/assets/javascripts/ui/editor/SculptureEditor.js @@ -17,6 +17,7 @@ var SculptureEditor = FormView.extend({ "change [name=mute]": "setMute", "change [name=width]": 'changeWidth', "change [name=height]": 'changeHeight', + "change [name=depth]": 'changeDepth', "change [name=units]": 'changeUnits', "click [data-role=destroy-sculpture]": "destroy", }, @@ -35,6 +36,7 @@ var SculptureEditor = FormView.extend({ // image fields this.$width = this.$("[name=width]") this.$height = this.$("[name=height]") + this.$depth = this.$("[name=depth]") this.$units = this.$("[name=units]") // video fields @@ -168,17 +170,26 @@ var SculptureEditor = FormView.extend({ if (! this.sculpture) return this.$width.unitVal( Number(this.sculpture.naturalDimensions.a * this.sculpture.scale) || "" ) this.$height.unitVal( Number(this.sculpture.naturalDimensions.b * this.sculpture.scale) || "" ) + this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" ) this.tainted = true }, changeWidth: function(e){ e.stopPropagation() this.sculpture.set_scale( this.$width.unitVal() / this.sculpture.naturalDimensions.a ) this.setDimensions() + this.sculpture.updateOutline() }, changeHeight: function(e){ e.stopPropagation() this.sculpture.set_scale( this.$height.unitVal() / this.sculpture.naturalDimensions.b ) this.setDimensions() + this.sculpture.updateOutline() + }, + changeDepth: function(e){ + e.stopPropagation() + this.sculpture.set_depth( this.$depth.unitVal() ) + this.$depth.unitVal( Number(this.sculpture.naturalDimensions.c * this.sculpture.scale) || "" ) + this.sculpture.updateOutline() }, changeUnits: function(){ app.units = this.$units.val() diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 6e97500..6adb2a0 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1205,6 +1205,13 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } -webkit-box-sizing: content-box; box-sizing: content-box; } +.mx-outline { + border-width: 2px; + border-style: dashed; + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; + box-sizing: content-box; +} .destroyActive .mx-scene, .destroyActive .mx-object3d.image { cursor:url(/assets/img/delete-cursor.png), auto; } diff --git a/views/controls/editor/sculpture.ejs b/views/controls/editor/sculpture.ejs index 4b8535a..dfe917f 100644 --- a/views/controls/editor/sculpture.ejs +++ b/views/controls/editor/sculpture.ejs @@ -33,7 +33,7 @@
- +
remove object -- cgit v1.2.3-70-g09d2 From 630c08b712a2ace833217428f1ef20bddc0b975d Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 25 Aug 2015 18:32:14 -0400 Subject: blueprint integration into project editor --- .../javascripts/rectangles/engine/rooms/_rooms.js | 32 +++++++++ public/assets/javascripts/ui/_router.js | 75 +++++++++++++--------- .../javascripts/ui/blueprint/BlueprintSettings.js | 3 + .../javascripts/ui/blueprint/BlueprintView.js | 2 +- .../assets/javascripts/ui/builder/BuilderInfo.js | 4 +- .../assets/javascripts/ui/editor/EditorSettings.js | 7 +- public/assets/javascripts/ui/editor/EditorView.js | 5 ++ server/lib/api/blueprint.js | 3 + server/lib/api/projects.js | 14 +++- server/lib/schemas/Blueprint.js | 1 + server/lib/schemas/Project.js | 2 + server/lib/util.js | 4 ++ 12 files changed, 117 insertions(+), 35 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js index 46c1d7f..d4281ad 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js +++ b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js @@ -37,6 +37,7 @@ base.list = {} base.regions = [] + base.shapesMode = false base.uid = new UidGenerator(base.list) @@ -95,6 +96,7 @@ } base.rebuild = function(walls_data){ + if (base.shapesMode) return walls_data = walls_data || Walls.serialize() Rooms.clipper.update() Rooms.builder.rebuild() @@ -124,6 +126,36 @@ }) Rooms.rebuild(walls_data) } + + base.deserializeFromShapes = function(shapes_data, walls_data) { + base.shapesMode = true + window.viewHeight = data.viewHeight || app.defaults.viewHeight + window.wallHeight = data.wallHeight || app.defaults.wallHeight + $(".units").val( data.units ) + + shapes.deserialize( data.shapes ) + shapes.build() + + regions.forEach(function(region){ + var room = new Room({ + rect: region, + regions: [region], + height: wallHeight, + }) + room.sides = region.sides + region.id = Rooms.uid("room_") + Rooms.list[ region.id ] = room + Rooms.builder.build(region) + room.mx_floor = Rooms.builder.make_floor(room, region) + room.mx_ceiling = Rooms.builder.make_ceiling(room, region) + }) + + Rooms.grouper.build() + + Walls.paint() + Walls.deserialize(walls_data) + app.tube("rooms-built") + } base.report = function(){ var data = [] diff --git a/public/assets/javascripts/ui/_router.js b/public/assets/javascripts/ui/_router.js index e5e46e5..61b1d1b 100644 --- a/public/assets/javascripts/ui/_router.js +++ b/public/assets/javascripts/ui/_router.js @@ -18,35 +18,36 @@ var SiteRouter = Router.extend({ }, routes: { - "/": 'home', - "/home": 'home', - "/login": 'signin', - "/signin": 'signin', - "/signup": 'signup', - - "/auth/usernameTaken": 'usernameTaken', - "/auth/password": 'passwordReset', - "/auth/forgotPassword": 'passwordForgot', - - "/profile": 'profile', - "/profile/edit": 'editProfile', - "/profile/billing": 'editSubscription', - "/profile/:name": 'profile', - "/about/:name/edit": 'editDocument', - "/about/new": 'newDocument', - - "/layout": 'layoutPicker', - "/layout/:name": 'layoutEditor', - - "/blueprint": 'blueprintEditor', - "/blueprint/:name": 'blueprintEditor', - - "/project": 'projectPicker', - "/project/new": 'newProject', - "/project/new/:layout": 'projectNewWithLayout', - "/project/:name": 'projectViewer', - "/project/:name/edit": 'projectEditor', - "/project/:name/view": 'projectViewer', + "/": 'home', + "/home": 'home', + "/login": 'signin', + "/signin": 'signin', + "/signup": 'signup', + + "/auth/usernameTaken": 'usernameTaken', + "/auth/password": 'passwordReset', + "/auth/forgotPassword": 'passwordForgot', + + "/profile": 'profile', + "/profile/edit": 'editProfile', + "/profile/billing": 'editSubscription', + "/profile/:name": 'profile', + "/about/:name/edit": 'editDocument', + "/about/new": 'newDocument', + + "/layout": 'layoutPicker', + "/layout/:name": 'layoutEditor', + + "/blueprint": 'blueprintEditor', + "/blueprint/:name": 'blueprintEditor', + + "/project": 'projectPicker', + "/project/new": 'newProject', + "/project/blueprint/:blueprint": 'projectNewWithBlueprint', + "/project/new/:layout": 'projectNewWithLayout', + "/project/:name": 'projectViewer', + "/project/:name/edit": 'projectEditor', + "/project/:name/view": 'projectViewer', "/test/blueprint": 'blueprintEditor', }, @@ -123,6 +124,22 @@ var SiteRouter = Router.extend({ window.history.pushState(null, document.title, "/project/new") this.newProjectModal.load() }, + + projectNewWithBlueprint: function(e, blueprint){ + e && e.preventDefault() + + Rooms.shapesMode = true + + app.mode.editor = true + app.launch() + if (app.unsupported) return + + blueprint = slugify(blueprint) + + window.history.pushState(null, document.title, "/project/blueprint/" + blueprint) + this.editorView = app.controller = new EditorView() + this.editorView.loadBlueprint(blueprint) + }, projectNewWithLayout: function(e, layout){ e && e.preventDefault() diff --git a/public/assets/javascripts/ui/blueprint/BlueprintSettings.js b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js index 9c8808a..0870a11 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintSettings.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js @@ -95,6 +95,9 @@ var BlueprintSettings = FormView.extend(ToggleableView.prototype).extend({ fd.append( "name", this.$name.val() ) fd.append( "shapes", JSON.stringify( shapes.serialize() ) ) fd.append( "startPosition", JSON.stringify( app.position(scene.camera) ) ) + fd.append( "wallHeight", this.parent.info.$height.unitVal() ) + fd.append( "units", this.parent.info.$units.val() ) + return fd }, diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index e1d360f..3095cfe 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -48,8 +48,8 @@ var BlueprintView = View.extend({ }, ready: function(data){ - this.settings.load(data) this.info.load(data) + this.settings.load(data) this.editor.loadFloorplan(data) }, diff --git a/public/assets/javascripts/ui/builder/BuilderInfo.js b/public/assets/javascripts/ui/builder/BuilderInfo.js index 9a7dbf9..aa58d6e 100644 --- a/public/assets/javascripts/ui/builder/BuilderInfo.js +++ b/public/assets/javascripts/ui/builder/BuilderInfo.js @@ -40,8 +40,8 @@ var BuilderInfo = View.extend({ load: function(data){ this.$viewHeight.unitVal( window.viewHeight = data.viewHeight || app.defaults.viewHeight ) - this.$units.val( "ft" ) - this.$unitName.html( "ft" ) + this.$units.val( data.units || "ft" ) + this.$unitName.html( data.units || "ft" ) if (Rooms.regions.length == 0) { this.changeHeightGlobal(true) diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index 460863e..000852e 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -41,7 +41,12 @@ var EditorSettings = FormView.extend({ this.action = data.isNew ? this.createAction : this.updateAction this.parent.data = data - data.rooms && Rooms.deserialize(data.rooms, data.walls) + if (data.rooms) { + Rooms.deserialize(data.rooms, data.walls) + } + else if (data.shapes) { + Rooms.deserializeFromShapes(data.shapes, data.walls) + } if (data.startPosition) { scene.camera.move(data.startPosition) this.startPosition = data.startPosition diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index a2d84a6..879c963 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -2,6 +2,7 @@ var EditorView = View.extend({ el: "#editorView", + blueprintAction: "/api/blueprint/", projectAction: "/api/project/", layoutAction: "/api/layout/", @@ -41,6 +42,10 @@ var EditorView = View.extend({ $.get(this.layoutAction + layout, this.readyLayout.bind(this)) }, + loadBlueprint: function(blueprint){ + $.get(this.blueprintAction + blueprint, this.readyLayout.bind(this)) + }, + ready: function(data){ $("#map").hide() diff --git a/server/lib/api/blueprint.js b/server/lib/api/blueprint.js index e581d8f..222b466 100644 --- a/server/lib/api/blueprint.js +++ b/server/lib/api/blueprint.js @@ -92,6 +92,9 @@ var blueprint = { doc.name = util.sanitize(data.name) doc.slug = util.slugify(data.name) + doc.units = util.sanitize(data.units) + doc.viewHeight = util.sanitizeNumber(data.viewHeight) + doc.wallHeight = util.sanitizeNumber(data.wallHeight) doc.shapes = JSON.parse(data.shapes) doc.startPosition = JSON.parse(data.startPosition) diff --git a/server/lib/api/projects.js b/server/lib/api/projects.js index 3810168..50d3b49 100644 --- a/server/lib/api/projects.js +++ b/server/lib/api/projects.js @@ -37,7 +37,12 @@ var projects = { data.slug = util.slugify(data.name) + "-" + (+new Date) data.description = util.sanitize(data.description) data.viewHeight = Number(data.viewHeight || 0) - data.rooms = JSON.parse(data.rooms) + if (data.shapes) { + data.shapes = JSON.parse(data.shapes) + } + else { + data.rooms = JSON.parse(data.rooms) + } data.walls = JSON.parse(data.walls) data.media = JSON.parse(data.media) data.sculpture = JSON.parse(data.sculpture) @@ -102,7 +107,12 @@ var projects = { _.extend(doc, data) - doc.rooms = JSON.parse(data.rooms) + if (data.shapes) { + doc.shapes = JSON.parse(data.shapes) + } + else { + doc.rooms = JSON.parse(data.rooms) + } doc.walls = JSON.parse(data.walls) doc.colors = JSON.parse(data.colors) doc.media = JSON.parse(data.media) diff --git a/server/lib/schemas/Blueprint.js b/server/lib/schemas/Blueprint.js index 76d0a09..3c3b0cc 100644 --- a/server/lib/schemas/Blueprint.js +++ b/server/lib/schemas/Blueprint.js @@ -51,6 +51,7 @@ var BlueprintSchema = new mongoose.Schema({ widthDimension: { type: Number }, heightDimension: { type: Number }, + wallHeight: { type: Number }, units: { type: String }, line: { type: String }, diff --git a/server/lib/schemas/Project.js b/server/lib/schemas/Project.js index 855d95a..687555d 100644 --- a/server/lib/schemas/Project.js +++ b/server/lib/schemas/Project.js @@ -28,6 +28,7 @@ var ProjectSchema = new mongoose.Schema({ type: String, }, rooms: [mongoose.Schema.Types.Mixed], + shapes: [mongoose.Schema.Types.Mixed], walls: [mongoose.Schema.Types.Mixed], media: [mongoose.Schema.Types.Mixed], sculpture: [mongoose.Schema.Types.Mixed], @@ -35,6 +36,7 @@ var ProjectSchema = new mongoose.Schema({ startPosition: mongoose.Schema.Types.Mixed, lastPosition: mongoose.Schema.Types.Mixed, viewHeight: { type: Number }, + units: { type: String, default: "ft" }, user_id: { type: mongoose.Schema.ObjectId, index: true }, created_at: { type: Date }, updated_at: { type: Date }, diff --git a/server/lib/util.js b/server/lib/util.js index e3fd1ed..86fbdcc 100644 --- a/server/lib/util.js +++ b/server/lib/util.js @@ -5,6 +5,7 @@ var whitespace = new RegExp('\\s', 'g') var whitespaceHead = /^\s+/ var whitespaceTail = /\s+$/ var nonAlphanumerics = new RegExp('[^-_a-zA-Z0-9]', 'g') +var nonNumerics = new RegExp('[^0-9]', 'g') var consecutiveDashes = new RegExp("-+", 'g') var entities = new RegExp("[<>&]", 'g') @@ -19,6 +20,9 @@ util.slugify = function (s){ util.sanitize = function (s){ return (s || "").replace(entities, "") } +util.sanitizeNumber = function (s){ + return (s || "").replace(nonNumerics, "") +} util.escape = function (s){ return (s || "").replace(/&/g, "&").replace(//g, ">") } -- cgit v1.2.3-70-g09d2 From 73b8036e977a21d4b1e327245d02826eade3c843 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 26 Aug 2015 12:24:12 -0400 Subject: loading rooms into editor --- .../assets/javascripts/rectangles/engine/rooms/_rooms.js | 13 ++++++++++--- public/assets/javascripts/rectangles/models/room.js | 4 ++++ public/assets/javascripts/ui/editor/EditorSettings.js | 15 ++++++++++----- public/assets/javascripts/ui/editor/EditorView.js | 2 +- server/index.js | 2 ++ server/lib/api/blueprint.js | 15 +++++++++++++++ 6 files changed, 42 insertions(+), 9 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js index d4281ad..5c9945c 100644 --- a/public/assets/javascripts/rectangles/engine/rooms/_rooms.js +++ b/public/assets/javascripts/rectangles/engine/rooms/_rooms.js @@ -127,14 +127,16 @@ Rooms.rebuild(walls_data) } - base.deserializeFromShapes = function(shapes_data, walls_data) { + base.deserializeFromShapes = function(data, walls_data) { + walls_data = walls_data || Walls.serialize() base.shapesMode = true window.viewHeight = data.viewHeight || app.defaults.viewHeight window.wallHeight = data.wallHeight || app.defaults.wallHeight $(".units").val( data.units ) shapes.deserialize( data.shapes ) - shapes.build() + // shapes.build() + var regions = RegionList.build() regions.forEach(function(region){ var room = new Room({ @@ -142,12 +144,17 @@ regions: [region], height: wallHeight, }) + room.sides = region.sides region.id = Rooms.uid("room_") Rooms.list[ region.id ] = room - Rooms.builder.build(region) + var mx_walls = Rooms.builder.build_walls(region) room.mx_floor = Rooms.builder.make_floor(room, region) room.mx_ceiling = Rooms.builder.make_ceiling(room, region) + + mx_walls.forEach(function(mx){ scene.add(mx) }) + scene.add(room.mx_floor) + scene.add(room.mx_ceiling) }) Rooms.grouper.build() diff --git a/public/assets/javascripts/rectangles/models/room.js b/public/assets/javascripts/rectangles/models/room.js index 26bf055..0ef76e4 100644 --- a/public/assets/javascripts/rectangles/models/room.js +++ b/public/assets/javascripts/rectangles/models/room.js @@ -35,6 +35,10 @@ this.height = opt.height || 200 this.focused = false + + this.mx_walls = [] + this.mx_floor = [] + this.mx_ceiling = [] } Room.prototype.copy = function(){ diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index 000852e..83bc8b7 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -41,11 +41,11 @@ var EditorSettings = FormView.extend({ this.action = data.isNew ? this.createAction : this.updateAction this.parent.data = data - if (data.rooms) { - Rooms.deserialize(data.rooms, data.walls) + if (data.shapes) { + Rooms.deserializeFromShapes(data, data.walls) } - else if (data.shapes) { - Rooms.deserializeFromShapes(data.shapes, data.walls) + else if (data.rooms) { + Rooms.deserialize(data.rooms, data.walls) } if (data.startPosition) { scene.camera.move(data.startPosition) @@ -194,7 +194,12 @@ var EditorSettings = FormView.extend({ fd.append( "description", this.$description.val() ) fd.append( "privacy", this.$privacy.filter(":checked").val() == "private" ) fd.append( "viewHeight", window.viewHeight ) - fd.append( "rooms", JSON.stringify( Rooms.serialize() ) ) + if (Rooms.shapesMode) { + fd.append( "shapes", JSON.stringify( shapes.serialize() ) ) + } + else { + fd.append( "rooms", JSON.stringify( Rooms.serialize() ) ) + } fd.append( "walls", JSON.stringify( Walls.serialize() ) ) fd.append( "colors", JSON.stringify( Walls.colors ) ) fd.append( "media", JSON.stringify( Scenery.serialize() ) ) diff --git a/public/assets/javascripts/ui/editor/EditorView.js b/public/assets/javascripts/ui/editor/EditorView.js index 879c963..c05b373 100644 --- a/public/assets/javascripts/ui/editor/EditorView.js +++ b/public/assets/javascripts/ui/editor/EditorView.js @@ -2,7 +2,7 @@ var EditorView = View.extend({ el: "#editorView", - blueprintAction: "/api/blueprint/", + blueprintAction: "/api/blueprint/user/", projectAction: "/api/project/", layoutAction: "/api/layout/", diff --git a/server/index.js b/server/index.js index 7143da2..224aa86 100644 --- a/server/index.js +++ b/server/index.js @@ -138,6 +138,7 @@ site.route = function () { app.get('/project', middleware.ensureAuthenticated, views.modal) app.get('/project/new', middleware.ensureAuthenticated, views.modal) app.get('/project/new/:layout', middleware.ensureAuthenticated, views.editor_new) + app.get('/project/blueprint/:layout', middleware.ensureAuthenticated, views.editor_new) app.get('/project/:slug', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader) app.get('/project/:slug/view', middleware.ensureProject, middleware.ensureIsCollaborator, views.reader) app.get('/project/:slug/edit', middleware.ensureProject, middleware.ensureIsCollaborator, views.editor) @@ -163,6 +164,7 @@ site.route = function () { app.post('/api/blueprint/new', middleware.ensureAuthenticated, api.blueprint.create) app.post('/api/blueprint/upload', middleware.ensureAuthenticated, api.blueprint.upload) + app.get('/api/blueprint/user/:slug', middleware.ensureAuthenticated, api.blueprint.show) app.get('/api/blueprint/user', middleware.ensureAuthenticated, api.blueprint.user) app.post('/api/blueprint/scale', middleware.ensureAuthenticated, api.blueprint.scale) app.post('/api/blueprint/edit', middleware.ensureAuthenticated, api.blueprint.update) diff --git a/server/lib/api/blueprint.js b/server/lib/api/blueprint.js index 222b466..e780b92 100644 --- a/server/lib/api/blueprint.js +++ b/server/lib/api/blueprint.js @@ -25,6 +25,21 @@ var blueprint = { }) }, + show: function(req, res){ + Blueprint.findOne({ slug: req.params.slug }, function(err, doc){ + if (doc) { + res.json(doc) + return + } + else { + Project.count({}, function(err, count){ + var name = "Project #" + (count || 0) + res.json({ _id: "new", name: name, isNew: true }) + }) + } + }) + }, + create: function(req, res){ var data = util.cleanQuery(req.body) data.user_id = req.user._id -- cgit v1.2.3-70-g09d2 From ee110d4725943bbc2b783323ec5087324531ca33 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 27 Aug 2015 18:17:14 -0400 Subject: get rooms api working with shapes --- .../javascripts/rectangles/engine/map/_map.js | 3 + .../javascripts/rectangles/engine/map/draw.js | 19 +-- .../javascripts/rectangles/engine/shapes/ortho.js | 9 ++ .../rectangles/engine/shapes/polyline.js | 9 ++ .../rectangles/engine/shapes/regionlist.js | 11 ++ .../rectangles/engine/shapes/shapelist.js | 13 +- .../assets/javascripts/ui/editor/EditorSettings.js | 2 +- public/assets/javascripts/ui/reader/ReaderView.js | 7 +- server/lib/api/rooms.js | 139 +++++++++++++++------ 9 files changed, 161 insertions(+), 51 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/map/_map.js b/public/assets/javascripts/rectangles/engine/map/_map.js index e27346d..6492db6 100644 --- a/public/assets/javascripts/rectangles/engine/map/_map.js +++ b/public/assets/javascripts/rectangles/engine/map/_map.js @@ -50,6 +50,7 @@ var Map = function(opt){ switch (opt.type) { case "ortho": base.draw = new Map.Draw (base, { ortho: true }) + base.draw.grid_size = MAP_GRID_SIZE base.ui = new Map.UI.Ortho (base) base.sides = base.sides_for_center $(window).resize(base.resize) @@ -57,6 +58,7 @@ var Map = function(opt){ case "editor": base.draw = new Map.Draw (base) + base.draw.grid_size = MAP_GRID_SIZE base.ui = new Map.UI.Editor (base) base.sides = base.sides_for_center $(window).resize(base.resize) @@ -64,6 +66,7 @@ var Map = function(opt){ case "minimap": base.draw = new Map.Draw (base, { center: scene.camera, minimap: true }) + base.draw.grid_size = MAP_GRID_SIZE * 10 base.ui = new Map.UI.Minimap (base) base.sides = base.sides_for_camera break diff --git a/public/assets/javascripts/rectangles/engine/map/draw.js b/public/assets/javascripts/rectangles/engine/map/draw.js index fd05f86..4f4759f 100644 --- a/public/assets/javascripts/rectangles/engine/map/draw.js +++ b/public/assets/javascripts/rectangles/engine/map/draw.js @@ -179,8 +179,8 @@ Map.Draw = function(map, opt){ ctx.lineWidth = 1/map.zoom var sides = map.sides() - var quant = sides.clone().quantize(MAP_GRID_SIZE) - for (var x = quant.x.a - MAP_GRID_SIZE; x <= quant.x.b; x += MAP_GRID_SIZE) { + var quant = sides.clone().quantize(draw.grid_size) + for (var x = quant.x.a - draw.grid_size; x <= quant.x.b; x += draw.grid_size) { if (Math.round(x) % 360 == 0) { ctx.strokeStyle = "rgba(0,0,0,0.3)" ctx.lineWidth = 1/map.zoom @@ -191,17 +191,18 @@ Map.Draw = function(map, opt){ } line(x, sides.y.a, x, sides.y.b) } - for (var y = quant.y.a - MAP_GRID_SIZE; y <= quant.y.b; y += MAP_GRID_SIZE) { - if (Math.round(y) % 360 == 0) { + + for (var y = quant.y.a - draw.grid_size; y <= quant.y.b; y += draw.grid_size) { + if (Math.round(y) % 360 == 0) { ctx.strokeStyle = "rgba(0,0,0,0.3)" ctx.lineWidth = 1/map.zoom - } - else { + } + else { ctx.strokeStyle = "rgba(0,0,0,0.05)" ctx.lineWidth = 1/map.zoom - } - line(sides.x.a, y, sides.x.b, y) - } + } + line(sides.x.a, y, sides.x.b, y) + } } // diff --git a/public/assets/javascripts/rectangles/engine/shapes/ortho.js b/public/assets/javascripts/rectangles/engine/shapes/ortho.js index c1acae5..163f646 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/ortho.js +++ b/public/assets/javascripts/rectangles/engine/shapes/ortho.js @@ -1,5 +1,9 @@ // An OrthoPolyline is a Polyline where all angles are 90 degrees. +if (! ('window' in this) ) { + var Polyline = require("./polyline.js") +} + var OrthoPolyline = Polyline.extend(function(base){ var exports = {} exports.type = function(){ @@ -55,3 +59,8 @@ var OrthoPolyline = Polyline.extend(function(base){ } return exports }) + + +if (! ('window' in this) ) { + module.exports = OrthoPolyline +} diff --git a/public/assets/javascripts/rectangles/engine/shapes/polyline.js b/public/assets/javascripts/rectangles/engine/shapes/polyline.js index 579d0ea..b2cd92f 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/polyline.js +++ b/public/assets/javascripts/rectangles/engine/shapes/polyline.js @@ -2,6 +2,11 @@ // Additionally, it manages a set of MX objects which correspond to the walls in 3D. // In this way, it attempts to bridge the 2D (canvas, imperative) and 3D (css, declarative) views. +if (! ('window' in this) ) { + var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js") + var vec2 = require("../../models/vec2") +} + var Polyline = Fiber.extend(function(base){ var exports = {} exports.init = function(){ @@ -201,3 +206,7 @@ var Polyline = Fiber.extend(function(base){ } return exports }) + +if (! ('window' in this) ) { + module.exports = Polyline +} diff --git a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js index 0dd4a1e..8c9e732 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js @@ -5,6 +5,13 @@ // 1) all angles are orthogonal // 2) all polylines are closed +if (! ('window' in this) ) { + var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js") + var vec2 = require("../../models/vec2") + var Rect = require("../../models/rect") + var sort = require("../../util/sort") +} + var RegionList = (function(){ var RegionList = {} @@ -223,6 +230,10 @@ var RegionList = (function(){ } return new Rect( segment[0].a, segment[0].b, segment[1].a, segment[1].b ) } + + if (! ('window' in this) ) { + module.exports = RegionList + } return RegionList diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js index 2d33af2..21beb76 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js @@ -1,5 +1,11 @@ // The ShapeList manages the list of polylines which form a V2 layout. +if (! ('window' in this) ) { + var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js") + var Polyline = require("./polyline.js") + var OrthoPolyline = require("./ortho.js") +} + var ShapeList = Fiber.extend(function(base){ var exports = {} exports.init = function(){ @@ -110,4 +116,9 @@ var ShapeList = Fiber.extend(function(base){ }) } return exports -}) \ No newline at end of file +}) + +if (! ('window' in this) ) { + shapes = new ShapeList + module.exports = shapes +} diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index 83bc8b7..d8cfca6 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -41,7 +41,7 @@ var EditorSettings = FormView.extend({ this.action = data.isNew ? this.createAction : this.updateAction this.parent.data = data - if (data.shapes) { + if (data.shapes.length) { Rooms.deserializeFromShapes(data, data.walls) } else if (data.rooms) { diff --git a/public/assets/javascripts/ui/reader/ReaderView.js b/public/assets/javascripts/ui/reader/ReaderView.js index 1ba97cf..43e81d8 100644 --- a/public/assets/javascripts/ui/reader/ReaderView.js +++ b/public/assets/javascripts/ui/reader/ReaderView.js @@ -76,7 +76,12 @@ var ReaderView = View.extend({ }, build: function(data){ - data.rooms && Rooms.deserialize(data.rooms) + if (data.shapes.length) { + Rooms.deserializeFromShapes(data) + } + else { + Rooms.deserialize(data.rooms) + } data.walls && Walls.deserialize(data.walls) data.media && Scenery.deserialize(data.media) data.sculpture && Sculpture.deserialize(data.sculpture) diff --git a/server/lib/api/rooms.js b/server/lib/api/rooms.js index c044309..2a1d2fe 100644 --- a/server/lib/api/rooms.js +++ b/server/lib/api/rooms.js @@ -6,6 +6,8 @@ var Clipper = require("../../../public/assets/javascripts/rectangles/engine/room var Builder = require("../../../public/assets/javascripts/rectangles/engine/rooms/builder.js") var Grouper = require("../../../public/assets/javascripts/rectangles/engine/rooms/grouper.js") var Walls = require("../../../public/assets/javascripts/rectangles/engine/rooms/_walls.js") +var shapes = require("../../../public/assets/javascripts/rectangles/engine/shapes/shapelist.js") +var RegionList = require("../../../public/assets/javascripts/rectangles/engine/shapes/regionlist.js") /* jshint node: true */ @@ -21,47 +23,106 @@ var rooms = module.exports = { if (! doc) { res.json({ status: 404 }); return } doc = doc.toObject() - doc.rooms.forEach(function(data){ - var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1]) - var room = new Room({ - id: data.id, - rect: rect, - height: data.height - }) - Rooms.add(room) - }) - Rooms.clipper.solve_rects() - Rooms.builder.build() - - var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = [] - var collections = Rooms.grouper.collect() - Rooms.grouper.cull(collections) - Rooms.grouper.group(walls, collections, FRONT) - Rooms.grouper.group(walls, collections, BACK) - Rooms.grouper.group(walls, collections, LEFT) - Rooms.grouper.group(walls, collections, RIGHT) - walls.forEach(function(wall){ - wall.mx.forEach(function(mx){ - var data = mx.report() - data.id = wall.id - mx_walls.push(data) - }) - }) - - doc.mx_walls = mx_walls - doc.mx_floor = mx_floor - doc.mx_ceiling = mx_ceiling - - Rooms.forEach(function(room){ - room.mx_floor.forEach(function(mx){ - mx_floor.push( mx.report() ) - }) - room.mx_ceiling.forEach(function(mx){ - mx_ceiling.push( mx.report() ) - }) - }) + if (doc.shapes.length) { + parseMxShapes(doc) + } + else { + parseMxRooms(doc) + } res.json(doc) }) } } + +function parseMxShapes (doc) { + var viewHeight = doc.viewHeight + var wallHeight = doc.wallHeight + + shapes.deserialize( doc.shapes ) + + var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = [] + var regions = RegionList.build() + + regions.forEach(function(region){ + var room = new Room({ + rect: region, + regions: [region], + height: wallHeight, + }) + + room.sides = region.sides + region.id = Rooms.uid("room_") + Rooms.list[ region.id ] = room + Rooms.builder.build_walls(region) + mx_floor.push( Rooms.builder.make_floor(room, region) ) + mx_ceiling.push( Rooms.builder.make_ceiling(room, region) ) + }) + + var collections = Rooms.grouper.collect() + Rooms.grouper.cull(collections) + Rooms.grouper.group(walls, collections, FRONT) + Rooms.grouper.group(walls, collections, BACK) + Rooms.grouper.group(walls, collections, LEFT) + Rooms.grouper.group(walls, collections, RIGHT) + walls.forEach(function(wall){ + wall.mx.forEach(function(mx){ + var data = mx.report() + data.id = wall.id + mx_walls.push(data) + }) + }) + + doc.mx_walls = mx_walls + doc.mx_floor = mx_floor + doc.mx_ceiling = mx_ceiling + + Rooms.forEach(function(room){ + mx_floor.push( room.mx_floor ) + room.mx_ceiling.forEach(function(mx){ + mx_ceiling.push( mx.report() ) + }) + }) +} + +function parseMxRooms (doc) { + doc.rooms.forEach(function(data){ + var rect = new Rect(data.rect.x[0], data.rect.y[0], data.rect.x[1], data.rect.y[1]) + var room = new Room({ + id: data.id, + rect: rect, + height: data.height + }) + Rooms.add(room) + }) + Rooms.clipper.solve_rects() + Rooms.builder.build() + + var walls = [], mx_walls = [], mx_floor = [], mx_ceiling = [] + var collections = Rooms.grouper.collect() + Rooms.grouper.cull(collections) + Rooms.grouper.group(walls, collections, FRONT) + Rooms.grouper.group(walls, collections, BACK) + Rooms.grouper.group(walls, collections, LEFT) + Rooms.grouper.group(walls, collections, RIGHT) + walls.forEach(function(wall){ + wall.mx.forEach(function(mx){ + var data = mx.report() + data.id = wall.id + mx_walls.push(data) + }) + }) + + doc.mx_walls = mx_walls + doc.mx_floor = mx_floor + doc.mx_ceiling = mx_ceiling + + Rooms.forEach(function(room){ + room.mx_floor.forEach(function(mx){ + mx_floor.push( mx.report() ) + }) + room.mx_ceiling.forEach(function(mx){ + mx_ceiling.push( mx.report() ) + }) + }) +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 7f443264d1c30b48cc3923ee6e700facdf0f7214 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Fri, 10 Jun 2016 16:32:37 -0400 Subject: fix resize issues --- .../javascripts/rectangles/engine/map/_map.js | 29 +++++++++++++--------- public/assets/javascripts/rectangles/util/mouse.js | 15 ++++++++++- .../assets/javascripts/ui/editor/EditorSettings.js | 2 +- public/assets/stylesheets/app.css | 2 ++ views/home.ejs | 1 + 5 files changed, 35 insertions(+), 14 deletions(-) (limited to 'public/assets/javascripts/ui/editor') diff --git a/public/assets/javascripts/rectangles/engine/map/_map.js b/public/assets/javascripts/rectangles/engine/map/_map.js index 6492db6..ba3ec92 100644 --- a/public/assets/javascripts/rectangles/engine/map/_map.js +++ b/public/assets/javascripts/rectangles/engine/map/_map.js @@ -41,12 +41,28 @@ var Map = function(opt){ } base.set_zoom(opt.zoom) + base.resize = function(w, h){ + if (w && h) { + canvas.width = base.dimensions.a = w + canvas.height = base.dimensions.b = h + } + else { + // resize here - esp if 2d-hires + canvas.width = base.dimensions.a = base.el.parentNode.offsetWidth + canvas.height = base.dimensions.b = base.el.parentNode.offsetHeight + } + } + + base.toggle = function(state){ + return $(base.el).toggle(state).is(':visible') + } + var canvas = base.canvas = document.createElement("canvas") canvas.width = base.dimensions.a canvas.height = base.dimensions.b base.el.appendChild(canvas) - + switch (opt.type) { case "ortho": base.draw = new Map.Draw (base, { ortho: true }) @@ -71,17 +87,6 @@ var Map = function(opt){ base.sides = base.sides_for_camera break } - - base.resize = function(w, h){ - canvas.width = base.dimensions.a = w || window.innerWidth - canvas.height = base.dimensions.b = h || window.innerHeight - // resize here - esp if 2d-hires - } - - base.toggle = function(state){ - return $(base.el).toggle(state).is(':visible') - } - } Map.prototype.update = function(){ diff --git a/public/assets/javascripts/rectangles/util/mouse.js b/public/assets/javascripts/rectangles/util/mouse.js index 2b98cee..6d9862c 100644 --- a/public/assets/javascripts/rectangles/util/mouse.js +++ b/public/assets/javascripts/rectangles/util/mouse.js @@ -54,10 +54,20 @@ function mouse (opt) { opt.up && base.tube.on("up", opt.up) opt.rightclick && base.tube.on("rightclick", opt.rightclick) - var offset = (opt.use_offset && opt.el) ? opt.el.getBoundingClientRect() : null + var offset; base.init = function (){ base.bind() + base.set_offset() + } + + base.set_offset = function(){ + if (opt.use_offset && opt.el) { + offset = opt.el.getBoundingClientRect() + } + else { + offset = null + } } base.on = function(){ @@ -73,6 +83,9 @@ function mouse (opt) { opt.el.addEventListener("mousedown", base.mousedown) opt.el.addEventListener("contextmenu", base.contextmenu) } + if (opt.use_offset) { + window.addEventListener("resize", base.set_offset) + } window.addEventListener("mousemove", base.mousemove) window.addEventListener("mouseup", base.mouseup) } diff --git a/public/assets/javascripts/ui/editor/EditorSettings.js b/public/assets/javascripts/ui/editor/EditorSettings.js index d8cfca6..5aa88e9 100644 --- a/public/assets/javascripts/ui/editor/EditorSettings.js +++ b/public/assets/javascripts/ui/editor/EditorSettings.js @@ -41,7 +41,7 @@ var EditorSettings = FormView.extend({ this.action = data.isNew ? this.createAction : this.updateAction this.parent.data = data - if (data.shapes.length) { + if (data.shapes && data.shapes.length) { Rooms.deserializeFromShapes(data, data.walls) } else if (data.rooms) { diff --git a/public/assets/stylesheets/app.css b/public/assets/stylesheets/app.css index 1154fde..fdf7c12 100755 --- a/public/assets/stylesheets/app.css +++ b/public/assets/stylesheets/app.css @@ -1331,6 +1331,8 @@ form .paidPlan label { float: none; font-size: 16px; margin: 0 10px; } #hud { position: fixed; top:0;left:0; + width: 100%; + height: 100%; z-index: 2; } #palette { diff --git a/views/home.ejs b/views/home.ejs index af43f0b..36dad83 100755 --- a/views/home.ejs +++ b/views/home.ejs @@ -60,6 +60,7 @@

Sign Up

Room Showcase

-- cgit v1.2.3-70-g09d2