From 3c36de54b57422f34c367934fdf62873b881fa20 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Mon, 17 Aug 2015 16:27:40 -0400 Subject: integrate ortho3 stuff into blueprint views --- .../javascripts/ui/blueprint/BlueprintUploader.js | 126 +++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 public/assets/javascripts/ui/blueprint/BlueprintUploader.js (limited to 'public/assets/javascripts/ui/blueprint/BlueprintUploader.js') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js new file mode 100644 index 0000000..aeb7d9c --- /dev/null +++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js @@ -0,0 +1,126 @@ + +var BlueprintUploader = UploadView.extend({ + el: ".blueprintUploader", + + mediaTag: "blueprint", + createAction: "/api/media/new", + uploadAction: "/api/media/upload", + listAction: "/api/media/user", + destroyAction: "/api/media/destroy", + + events: { + "mousedown": 'stopPropagation', + "change .url": "enterUrl", + "keydown .url": "enterSetUrl", + + "click .blueprint": "pick", + "click .remove": "destroy", + }, + + initialize: function(opt){ + this.parent = opt.parent + this.__super__.initialize.call(this) + + this.$url = this.$(".url") + this.$blueprints = this.$(".blueprints") + }, + + loaded: false, + load: function(){ + $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this)) + }, + + populate: function(data){ + this.loaded = true + if (data && data.length) { + this.$blueprints.show() + data.forEach(this.append.bind(this)) + this.hide() + this.parent.scaler.pick(data[0]) + } + else { + this.show() + } + }, + + pick: function(e){ + var $el = $(e.currentTarget) + var media = $el.data("media") + this.hide() + this.parent.scaler.pick(media) + }, + + destroy: function(e){ + e.stopPropagation() + var $el = $(e.currentTarget) + var _id = $el.closest(".blueprint").data("id") + $el.remove() + $.ajax({ + type: "delete", + url: this.destroyAction, + data: { _id: _id, _csrf: $("[name=_csrf]").val() } + }).complete(function(){ + }) + }, + + show: function(){ + this.toggle(true) + }, + hide: function(){ + this.toggle(false) + }, + toggle: function (state) { + this.$el.toggleClass("active", state) + }, + + addUrl: function (url){ + Parser.loadImage(url, function(media){ + if (! media) return + media._csrf = $("[name=_csrf]").val() + media.tag = this.mediaTag + + var request = $.ajax({ + type: "post", + url: this.createAction, + data: media, + }) + request.done(this.add.bind(this)) + + }.bind(this)) + }, + enterUrl: function(){ + var url = this.$url.sanitize() + this.addUrl(url) + this.$url.val("") + }, + enterSetUrl: function (e) { + e.stopPropagation() + if (e.keyCode == 13) { + setTimeout(this.enterUrl.bind(this), 100) + } + }, + + add: function(media){ + this.$blueprints.show() + this.append(media) + this.hide() + this.parent.scaler.pick(media) + }, + + append: function(media){ + var $el = $("") + var img = new Image () + img.src = media.url + var remove = document.createElement("span") + remove.className = "remove" + remove.innerHTML = "x" + + $el.data("id", media._id) + $el.data("media", media) + $el.append(img) + $el.append(remove) + $el.addClass("blueprint") + this.$blueprints.append($el) + }, + +}) -- cgit v1.2.3-70-g09d2 From 1807ea009f23ac446cb103005045942b733ffc61 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 18 Aug 2015 15:56:15 -0400 Subject: edit scale --- .../javascripts/ui/blueprint/BlueprintEditor.js | 2 +- .../javascripts/ui/blueprint/BlueprintScaler.js | 32 +++++-- .../javascripts/ui/blueprint/BlueprintToolbar.js | 8 ++ .../javascripts/ui/blueprint/BlueprintUploader.js | 12 +-- .../javascripts/ui/blueprint/BlueprintView.js | 2 +- server/index.js | 7 +- server/lib/api/blueprint.js | 105 +++++++++++++++++++++ server/lib/api/index.js | 1 + server/lib/api/media.js | 16 ---- server/lib/schemas/Blueprint.js | 53 +++++++++++ views/controls/blueprint/toolbar.ejs | 6 ++ 11 files changed, 210 insertions(+), 34 deletions(-) create mode 100644 server/lib/api/blueprint.js create mode 100644 server/lib/schemas/Blueprint.js (limited to 'public/assets/javascripts/ui/blueprint/BlueprintUploader.js') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js index 545de7b..cc469b6 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js @@ -64,7 +64,7 @@ var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ }, loadFloorplan: function(media){ - console.log(media) + // console.log(media) this.floorplan.load({ media: media, keepImage: true, diff --git a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js index ff26c8e..0f2fdcd 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintScaler.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintScaler.js @@ -2,7 +2,7 @@ var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ el: ".blueprintScaler", - action: "/api/media/scale", + action: "/api/blueprint/scale", events: { "change [name=blueprint-dimensions]": "changeDimensions", @@ -26,8 +26,8 @@ var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ width: window.innerWidth, height: window.innerHeight, zoom: -2, - zoom_min: -6.2, - zoom_max: 1, + zoom_min: -7.0, + zoom_max: 2, }) this.lineTool = new LineTool this.map.ui.add_tool("line", this.lineTool) @@ -42,17 +42,27 @@ var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ this.parent.uploader.show() }, - pick: function(media){ + pick: function(media, shouldEdit){ this.media = media - - if (!! media.units) { + + this.floorplan.load({ media: media, scale: 1, keepImage: true }) + + if (!! media.units && ! shouldEdit) { this.parent.useFloorplan(media) this.hide() this.stopAnimating() return } - this.floorplan.load({ media: media, keepImage: true }) + if (media.units && media.line && media.scale) { + var points = media.line.split(",") + this.lineTool.line[0] = new vec2( +points[0], +points[1] ) + this.lineTool.line[1] = new vec2( +points[2], +points[3] ) + + app.units = media.units + this.$units.val( media.units ) + this.$dimensions.unitVal( media.scale * this.lineLength() ) + } this.startAnimating() }, @@ -65,8 +75,9 @@ var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ this.floorplan.draw(this.map.draw.ctx, true) + this.map.draw.ctx.save() this.map.draw.ctx.strokeStyle = "#f00" - this.map.draw.ctx.lineWidth = 2/map.zoom + this.map.draw.ctx.lineWidth = 1/map.zoom switch (this.lineTool.line.length) { case 1: this.map.draw.line( @@ -85,6 +96,7 @@ var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ ) break } + this.map.draw.ctx.restore() this.map.draw.coords() @@ -125,15 +137,17 @@ var BlueprintScaler = ModalFormView.extend(AnimatedView.prototype).extend({ showErrors: function(){}, serialize: function(){ - var fd = new FormData() + var fd = new FormData(), line = this.lineTool.line fd.append( "_id", this.media._id) fd.append( "units", this.$units.val() ) fd.append( "scale", this.$dimensions.unitVal() / this.lineLength() ) + fd.append( "line", [line[0].a,line[0].b,line[1].a,line[1].b].join(",") ) fd.append( "_csrf", $("[name=_csrf]").val()) return fd }, success: function(){ + this.media.scale = this.$dimensions.unitVal() / this.lineLength() this.stopAnimating() this.parent.useFloorplan(this.media) this.hide() diff --git a/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js index 69288f6..a21a0ef 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js @@ -3,6 +3,7 @@ var BlueprintToolbar = View.extend({ el: "#blueprintToolbar", events: { + "click [data-role=upload-floorplan]": 'showUploader', "click [data-role=toggle-orbit-mode]": 'toggleOrbitMode', "click [data-role=arrow-mode]": 'arrowMode', "click [data-role=polyline-mode]": 'polylineMode', @@ -14,6 +15,7 @@ var BlueprintToolbar = View.extend({ this.parent = opt.parent this.$modes = this.$('.mode') + this.$toggleOrbitMode = this.$('[data-role=toggle-orbit-mode]') this.$arrowMode = this.$('[data-role=arrow-mode]') this.$polylineMode = this.$('[data-role=polyline-mode]') this.$orthoPolylineMode = this.$('[data-role=ortho-polyline-mode]') @@ -22,9 +24,15 @@ var BlueprintToolbar = View.extend({ this.orthoPolylineMode() }, + showUploader: function(){ + this.parent.scaler.show() + this.parent.uploader.show() + }, + orbiting: true, toggleOrbitMode: function(){ this.orbiting = ! this.orbiting + this.$toggleOrbitMode.toggleClass("inuse", ! this.orbiting) if (this.orbiting) { controls.toggle(true) movements.lock() diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js index aeb7d9c..676976f 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js @@ -3,10 +3,10 @@ var BlueprintUploader = UploadView.extend({ el: ".blueprintUploader", mediaTag: "blueprint", - createAction: "/api/media/new", - uploadAction: "/api/media/upload", - listAction: "/api/media/user", - destroyAction: "/api/media/destroy", + createAction: "/api/blueprint/new", + uploadAction: "/api/blueprint/upload", + listAction: "/api/blueprint/user", + destroyAction: "/api/blueprint/destroy", events: { "mousedown": 'stopPropagation', @@ -47,7 +47,7 @@ var BlueprintUploader = UploadView.extend({ var $el = $(e.currentTarget) var media = $el.data("media") this.hide() - this.parent.scaler.pick(media) + this.parent.scaler.pick(media, true) }, destroy: function(e){ @@ -104,7 +104,7 @@ var BlueprintUploader = UploadView.extend({ this.$blueprints.show() this.append(media) this.hide() - this.parent.scaler.pick(media) + this.parent.scaler.pick(media, true) }, append: function(media){ diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index cf627d9..4cb9138 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -2,7 +2,7 @@ var BlueprintView = View.extend({ el: "#blueprintView", - action: "/api/layout/", + action: "/api/blueprint/", events: { }, diff --git a/server/index.js b/server/index.js index 078db8e..421a6a7 100644 --- a/server/index.js +++ b/server/index.js @@ -159,9 +159,14 @@ site.route = function () { app.get('/api/media/user', middleware.ensureAuthenticated, api.media.user) app.post('/api/media/new', middleware.ensureAuthenticated, api.media.create) app.post('/api/media/upload', middleware.ensureAuthenticated, api.media.upload) - app.post('/api/media/scale', middleware.ensureAuthenticated, api.media.scale) app.delete('/api/media/destroy', middleware.ensureAuthenticated, api.media.destroy) + 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', middleware.ensureAuthenticated, api.blueprint.user) + app.post('/api/blueprint/scale', middleware.ensureAuthenticated, api.blueprint.scale) + app.delete('/api/blueprint/destroy', middleware.ensureAuthenticated, api.blueprint.destroy) + app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) app.put('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensureSubscription, api.subscription.update) app.put('/api/subscription/sync', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.sync) diff --git a/server/lib/api/blueprint.js b/server/lib/api/blueprint.js new file mode 100644 index 0000000..a932383 --- /dev/null +++ b/server/lib/api/blueprint.js @@ -0,0 +1,105 @@ +/* jshint node: true */ + +var _ = require('lodash'), + crypto = require('crypto'), + util = require('../util'), + upload = require('../upload'), + config = require('../../../config.json'), + Blueprint = require('../schemas/Blueprint'); + +var blueprint = { + + user: function(req, res){ + var offset = Number(req.query.offset) || 0 + var limit = Math.min( Number(req.query.limit), 50 ) || 20 + var query = { user_id: req.user._id } + if (req.query.tag) { + query.tag = req.query.tag + } + Blueprint.find(query) + .sort({'created_at': -1}) + .skip(offset) + .limit(limit) + .exec(function(err, media){ + res.json(media || []) + }) + }, + + create: function(req, res){ + var data = util.cleanQuery(req.body) + data.user_id = req.user._id + data.created_at = new Date () + + if (data.tag) { + data.tag = util.sanitize(data.tag) + } + + new Blueprint(data).save(function(err, rec){ + if (err || ! rec) { return res.json({ error: err }) } + return res.json(rec) + }) + }, + + upload: function(req, res){ + var data = util.cleanQuery(req.body) + data.user_id = req.user._id + data.created_at = new Date () + data.type = "image" + + upload.put("media", req.files.image, { + username: req.user.username, + unacceptable: function(err){ + res.json({ error: { errors: { media: { message: "Problem saving image: " + err } } } }) + }, + success: function(url){ + data.url = url + done() + } + }) + + function done () { + new Blueprint(data).save(function(err, rec) { + if (err || ! rec) { return res.json({ error: err }) } + res.json(rec) + }) + } + }, + + scale: function(req, res){ + var _id = req.body._id + var data = util.cleanQuery(req.body) + if (! _id) { return res.json({ error: 404 }) } + Blueprint.findOne({ _id: _id }, function(err, doc){ + if (! doc) { return res.json({ error: 404 }) } + if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) } + doc.scale = data.scale + doc.units = data.units + doc.line = data.line + console.log(doc) + doc.save(function(err, rec){ + if (err || ! rec) { return res.json({ error: err }) } + res.json(rec) + }) + }) + }, + + destroy: function(req, res){ + var _id = util.sanitize(req.body._id) + if (! _id || ! _id.length) { + res.json({ error: 404 }) + return + } + Blueprint.findOne({ _id: _id }, function(err, doc){ + if (! doc) { return res.json({ error: 404 }) } + if (String(doc.user_id) !== String(req.user._id)) { + return res.json({ error: "access denied" }) + } + Blueprint.remove({ _id: _id }, function(err){ + res.json({ status: "OK" }) + }) + }) + } + +} + +module.exports = blueprint diff --git a/server/lib/api/index.js b/server/lib/api/index.js index 9478d9b..8254232 100644 --- a/server/lib/api/index.js +++ b/server/lib/api/index.js @@ -1,6 +1,7 @@ /* jshint node: true */ var api = { + blueprint: require('./blueprint'), docs: require('./docs'), layouts: require('./layouts'), media: require('./media'), diff --git a/server/lib/api/media.js b/server/lib/api/media.js index 68e012c..85cbdd6 100644 --- a/server/lib/api/media.js +++ b/server/lib/api/media.js @@ -65,22 +65,6 @@ var media = { } }, - scale: function(req, res){ - var _id = req.body._id - var data = util.cleanQuery(req.body) - if (! _id) { return res.json({ error: 404 }) } - Media.findOne({ _id: _id }, function(err, doc){ - if (! doc) { return res.json({ error: 404 }) } - if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) } - doc.scale = data.scale - doc.units = data.units - doc.save(function(err, rec){ - if (err || ! rec) { return res.json({ error: err }) } - res.json(rec) - }) - }) - }, - destroy: function(req, res){ var _id = util.sanitize(req.body._id) if (! _id || ! _id.length) { diff --git a/server/lib/schemas/Blueprint.js b/server/lib/schemas/Blueprint.js new file mode 100644 index 0000000..40e67d8 --- /dev/null +++ b/server/lib/schemas/Blueprint.js @@ -0,0 +1,53 @@ +/* jshint node: true */ + +var mongoose = require('mongoose'), + _ = require('lodash'), + util = require('../util'); + +var BlueprintSchema = new mongoose.Schema({ + type: { + type: String, + required: true + }, + url: { + type: String, + required: true, + }, + token: { + type: String, + default: "" + }, + thumbnail: { + type: String, + default: "" + }, + width: { + type: Number, + default: 0 + }, + height: { + type: Number, + default: 0 + }, + title: { + type: String, + default: "" + }, + description: { + type: String, + default: "" + }, + tag: { type: String, default: "" }, + scale: { type: Number, default: 1.0 }, + + widthDimension: { type: Number }, + heightDimension: { type: Number }, + units: { type: String }, + line: { type: String }, + + user_id: { type: mongoose.Schema.ObjectId, index: true }, + created_at: { type: Date }, +}); + +module.exports = exports = mongoose.model('blueprint', BlueprintSchema) +exports.schema = BlueprintSchema; diff --git a/views/controls/blueprint/toolbar.ejs b/views/controls/blueprint/toolbar.ejs index 13e99ec..82cbcba 100644 --- a/views/controls/blueprint/toolbar.ejs +++ b/views/controls/blueprint/toolbar.ejs @@ -1,4 +1,10 @@ -X -

Your Media diff --git a/views/partials/header.ejs b/views/partials/header.ejs index 2acf2bc..bb8fc6e 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -78,4 +78,6 @@ [[ } ]] -

\ No newline at end of file + + +X \ No newline at end of file -- cgit v1.2.3-70-g09d2 From d9ecfddd7ba63d3cf94b29053476d1d11118d38e Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Tue, 18 Aug 2015 21:25:28 -0400 Subject: saving blueprints --- .../javascripts/rectangles/engine/shapes/polyline.js | 12 ++++++------ .../rectangles/engine/shapes/shapelist.js | 7 ++++--- .../javascripts/ui/blueprint/BlueprintSettings.js | 7 +++++-- .../javascripts/ui/blueprint/BlueprintToolbar.js | 5 +++++ .../javascripts/ui/blueprint/BlueprintUploader.js | 16 ++++++++++++++-- .../assets/javascripts/ui/blueprint/BlueprintView.js | 14 +++++--------- server/index.js | 1 + server/lib/api/blueprint.js | 20 ++++++++++++++++++++ server/lib/schemas/Blueprint.js | 11 ++++++++++- 9 files changed, 70 insertions(+), 23 deletions(-) (limited to 'public/assets/javascripts/ui/blueprint/BlueprintUploader.js') diff --git a/public/assets/javascripts/rectangles/engine/shapes/polyline.js b/public/assets/javascripts/rectangles/engine/shapes/polyline.js index e853592..3c4e9c3 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/polyline.js +++ b/public/assets/javascripts/rectangles/engine/shapes/polyline.js @@ -1,12 +1,9 @@ var Polyline = Fiber.extend(function(base){ var exports = {} - exports.init = function(points){ - this.points = points + exports.init = function(){ + this.points = [] this.mx_points = [] this.closed = false - if (points) { - this.build() - } } exports.add = function(p){ this.points.push( p ) @@ -138,7 +135,10 @@ var Polyline = Fiber.extend(function(base){ this.mx.rebuild() } exports.serialize = function(){ - return this.points + return this.points.map(function(point){ return [point.a, point.b] }) + } + exports.deserialize = function(points){ + this.points = points.map(function(point){ return new vec2(point[0], point[1]) }) } exports.reset = function(){ this.mx_points.forEach(function(mx){ scene.remove(mx) }) diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js index d8a03b2..1b8acfd 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js @@ -73,9 +73,10 @@ var ShapeList = Fiber.extend(function(base){ }) } exports.deserialize = function(data){ - data.forEach(function(points){ - var line = new Polyline(points) - this.add(line) + data && data.forEach(function(points){ + var line = new Polyline() + line.deserialize(points) + line.build() }.bind(this)) } return exports diff --git a/public/assets/javascripts/ui/blueprint/BlueprintSettings.js b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js index f9c9e78..acd8dcc 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintSettings.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintSettings.js @@ -26,6 +26,10 @@ var BlueprintSettings = FormView.extend({ load: function(data){ this.$id.val(data._id) this.$name.val(data.name) + if (data.shapes) { + shapes.destroy() + shapes.deserialize( data.shapes ) + } this.data = data }, @@ -88,7 +92,6 @@ var BlueprintSettings = FormView.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( "thumbnail", this.data.url ) return fd }, @@ -105,7 +108,7 @@ var BlueprintSettings = FormView.extend({ Minotaur.unwatch(this) Minotaur.hide() - window.history.pushState(null, document.title, "/layout/" + data.slug) + window.history.pushState(null, document.title, "/blueprint/" + data.slug) }, }) diff --git a/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js index 5f313fd..e22535e 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintToolbar.js @@ -9,6 +9,7 @@ var BlueprintToolbar = View.extend({ "click [data-role=polyline-mode]": 'polylineMode', "click [data-role=ortho-polyline-mode]": 'orthoPolylineMode', "click [data-role=eraser-mode]": 'eraserMode', + "click [data-role=toggle-layout-settings]": 'toggleSettings', }, initialize: function(opt){ @@ -49,6 +50,10 @@ var BlueprintToolbar = View.extend({ } }, + toggleSettings: function(){ + this.parent.settings.toggle() + }, + setActiveMode: function( $el ) { this.$modes.removeClass('active') $el.addClass('active') diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js index 6d13817..c7138e9 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js @@ -26,7 +26,9 @@ var BlueprintUploader = UploadView.extend({ }, loaded: false, - load: function(){ + nameToShow: null, + load: function(name){ + this.nameToShow = name || "" $.get(this.listAction, { tag: this.mediaTag }, this.populate.bind(this)) }, @@ -36,7 +38,17 @@ var BlueprintUploader = UploadView.extend({ this.$blueprints.show() data.forEach(this.append.bind(this)) this.hide() - this.parent.scaler.pick(data[0]) + if (this.nameToShow) { + data.some(function(el){ + if (el.slug == this.nameToShow) { + this.parent.scaler.pick(el) + return true + } + }.bind(this)) + } + else { + this.parent.scaler.pick(data[0]) + } } else { this.parent.scaler.hideClose() diff --git a/public/assets/javascripts/ui/blueprint/BlueprintView.js b/public/assets/javascripts/ui/blueprint/BlueprintView.js index 8330154..e1d360f 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintView.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintView.js @@ -2,7 +2,7 @@ var BlueprintView = View.extend({ el: "#blueprintView", - action: "/api/blueprint/", + action: "/api/blueprint/show/", events: { }, @@ -20,14 +20,10 @@ var BlueprintView = View.extend({ }, load: function(name){ - if (! name || name == "new") { - this.uploader.load() - return - } - - name = sanitize(name) - - $.get(this.action + name, this.ready.bind(this)) + name = sanitize(name) || "new" + this.uploader.load(name) +// name = sanitize(name) +// $.get(this.action + name, this.ready.bind(this)) }, orbiting: true, diff --git a/server/index.js b/server/index.js index 421a6a7..7143da2 100644 --- a/server/index.js +++ b/server/index.js @@ -165,6 +165,7 @@ site.route = function () { app.post('/api/blueprint/upload', middleware.ensureAuthenticated, api.blueprint.upload) 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) app.delete('/api/blueprint/destroy', middleware.ensureAuthenticated, api.blueprint.destroy) app.get('/api/subscription', middleware.ensureAuthenticated, api.subscription.middleware.ensurePlans, api.subscription.middleware.ensureSubscription, api.subscription.show) diff --git a/server/lib/api/blueprint.js b/server/lib/api/blueprint.js index 7319055..e581d8f 100644 --- a/server/lib/api/blueprint.js +++ b/server/lib/api/blueprint.js @@ -81,6 +81,26 @@ var blueprint = { }) }) }, + + update: function(req, res){ + var _id = req.body._id + var data = util.cleanQuery(req.body) + if (! _id) { return res.json({ error: 404 }) } + Blueprint.findOne({ _id: _id }, function(err, doc){ + if (! doc) { return res.json({ error: 404 }) } + if (String(doc.user_id) !== String(req.user._id)) { return res.json({ error: 404 }) } + + doc.name = util.sanitize(data.name) + doc.slug = util.slugify(data.name) + doc.shapes = JSON.parse(data.shapes) + doc.startPosition = JSON.parse(data.startPosition) + + doc.save(function(err, rec){ + if (err || ! rec) { return res.json({ error: err }) } + res.json(rec) + }) + }) + }, destroy: function(req, res){ var _id = util.sanitize(req.body._id) diff --git a/server/lib/schemas/Blueprint.js b/server/lib/schemas/Blueprint.js index 78a388f..666f0cf 100644 --- a/server/lib/schemas/Blueprint.js +++ b/server/lib/schemas/Blueprint.js @@ -33,6 +33,15 @@ var BlueprintSchema = new mongoose.Schema({ type: String, default: "" }, + slug: { + type: String, + required: true, + validate: [function (val){ + val = util.sanitize(val || this.displayName || "") + if (! val.length) return false + return true + },"{PATH} name is required"] + }, description: { type: String, default: "" @@ -45,7 +54,7 @@ var BlueprintSchema = new mongoose.Schema({ units: { type: String }, line: { type: String }, - rooms: [mongoose.Schema.Types.Mixed], + shapes: [mongoose.Schema.Types.Mixed], startPosition: mongoose.Schema.Types.Mixed, user_id: { type: mongoose.Schema.ObjectId, index: true }, -- cgit v1.2.3-70-g09d2 From 618ccc76b96fa5d070484ce2d0ec8d509153da69 Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Thu, 20 Aug 2015 19:14:32 -0400 Subject: starting to convert polylines into regions --- .../rectangles/engine/shapes/regionlist.js | 83 ++++++++++++++++++---- .../javascripts/ui/blueprint/BlueprintEditor.js | 11 ++- .../javascripts/ui/blueprint/BlueprintUploader.js | 2 +- 3 files changed, 80 insertions(+), 16 deletions(-) (limited to 'public/assets/javascripts/ui/blueprint/BlueprintUploader.js') diff --git a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js index 1f2810f..94b902a 100644 --- a/public/assets/javascripts/rectangles/engine/shapes/regionlist.js +++ b/public/assets/javascripts/rectangles/engine/shapes/regionlist.js @@ -2,36 +2,91 @@ var RegionList = (function(){ var RegionList = {} var regions = RegionList.regions - - RegionList.init = function(){ + + RegionList.build = function(){ + var segments = RegionList.getSortedSegments() + + // loop over them from left to right +// console.log(segments.map(function(s){ return s.toString() }).join("\n")) + + var rooms = [] + var open_segments = [] + + var segment, open_segment, vertical, other_side + + for (var i = 0; i < segments.length; i++) { + segment = segments[i] + if (! isVertical(segment)) { + continue + } + for (var j = 0; j < open_segments.length; j++) { + open_segment = open_segments[j] + if (overlaps(segment, open_segment)) { + // if we have overlap, it means we have made a full room + other_side = clone_segment(open_segment) + other_side[0].a = segment[0].a + other_side[1].a = segment[1].a + rooms.push([open_segment, other_side]) + open_segments.splice(j, 1) + j-- + } + } + open_segments.push(segment) + } + +// console.log(rooms.map(function(s){ return s[0][0].toString() + " " + s[0][1].toString() + " " + s[1][0].toString() + " " + s[1][1].toString() }).join("\n")) + + return rooms } - RegionList.build = function(){ + RegionList.getSortedSegments = function(){ + // get a list of all segments from these polylines var segments = shapes.getAllSegments() + + // re-orientate them so they're either facing up or right segments.forEach(function(segment){ - if (segment[0][0] == segment[1][0]) { - if (segment[0][1] > segment[1][1]) { + // vertical + if (segment[0].a == segment[1].a) { + if (segment[0].b > segment[1].b) { segment.push(segment.shift()) } } - else if (segment[0][1] == segment[1][1]) { - if (segment[0][0] > segment[1][0]) { + // horizontal + else if (segment[0].b == segment[1].b) { + if (segment[0].a > segment[1].a) { segment.push(segment.shift()) } } }) + + // sort them from top to bottom, left to right segments = segments.sort(function(a,b){ - return a[0][0] < b[0][0] + if (a[0].a < b[0].a) { + return -1 + } + else if (a[0].a == b[0].a) { + if (a[0].b < b[0].b) { + return -1 + } + else if (a[0].b == b[0].b) { + return 0 + } + else { + return 1 + } + } + else { + return 1 + } }) - console.log(segments) - - // get a list of all segments from these polylines - // re-orientate them so they're either facing up or right - // loop over them from left to right - // + return segments } + function isVertical (segment) { return segment[0].a == segment[1].a } + function isHorizontal (segment) { return segment[0].b == segment[1].b } + function overlaps (a,b) { return (a[0].b > b[0].b || a[1].b < b[1].b) } + function clone_segment(a){ return [a[0].clone(), a[1].clone()] } return RegionList })() \ No newline at end of file diff --git a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js index 73f21c0..8fe66ca 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintEditor.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintEditor.js @@ -93,7 +93,7 @@ var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ map.draw.ctx.save() map.draw.translate() - this.floorplan.draw(map.draw.ctx, true) + // this.floorplan.draw(map.draw.ctx, true) map.draw.coords() @@ -113,6 +113,15 @@ var BlueprintEditor = View.extend(AnimatedView.prototype).extend({ map.draw.mouse(map.ui.mouse.cursor) map.draw.camera(scene.camera) + var rooms = RegionList.build() + rooms.forEach(function(room,i){ + map.draw.ctx.fillStyle = colors[i % colors.length] + map.draw.ctx.fillRect( room[0][0].a, room[0][1].b, + room[1][0].a - room[0][0].a, + room[0][0].b - room[0][1].b + ) + }) + map.draw.ctx.restore() }, diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js index c7138e9..fbb71d5 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js @@ -38,7 +38,7 @@ var BlueprintUploader = UploadView.extend({ this.$blueprints.show() data.forEach(this.append.bind(this)) this.hide() - if (this.nameToShow) { + if (this.nameToShow && this.nameToShow !== "new") { data.some(function(el){ if (el.slug == this.nameToShow) { this.parent.scaler.pick(el) -- cgit v1.2.3-70-g09d2 From c781911322c84eb0c2aa4a00860016437d7b7cba Mon Sep 17 00:00:00 2001 From: Jules Laplace Date: Wed, 26 Aug 2015 18:30:33 -0400 Subject: surface blueprints on new project modal --- .../rectangles/engine/map/tools/arrow.js | 2 + .../rectangles/engine/map/tools/eraser.js | 2 + .../rectangles/engine/map/tools/line.js | 2 +- .../rectangles/engine/map/tools/ortho.js | 5 +- .../rectangles/engine/map/tools/polyline.js | 2 + .../rectangles/engine/map/tools/position.js | 2 + .../rectangles/engine/map/tools/start.js | 2 +- .../javascripts/ui/blueprint/BlueprintUploader.js | 9 +- public/assets/javascripts/ui/site/LayoutsModal.js | 190 +++++++++++++++++++-- public/assets/stylesheets/app.css | 4 +- server/lib/api/layouts.js | 18 +- views/projects/layouts-modal.ejs | 3 + 12 files changed, 211 insertions(+), 30 deletions(-) (limited to 'public/assets/javascripts/ui/blueprint/BlueprintUploader.js') diff --git a/public/assets/javascripts/rectangles/engine/map/tools/arrow.js b/public/assets/javascripts/rectangles/engine/map/tools/arrow.js index 2a73954..00478d4 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/arrow.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/arrow.js @@ -1,3 +1,5 @@ +// Tool used to move corners of polylines + var ArrowTool = MapTool.extend(function(base){ var exports = {} diff --git a/public/assets/javascripts/rectangles/engine/map/tools/eraser.js b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js index 648cd11..8fc3687 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/eraser.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js @@ -1,3 +1,5 @@ +// Tool used to delete lines + var EraserTool = MapTool.extend(function(base){ var exports = {} exports.down = function(e, cursor){ diff --git a/public/assets/javascripts/rectangles/engine/map/tools/line.js b/public/assets/javascripts/rectangles/engine/map/tools/line.js index a8e2473..8175d66 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/line.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/line.js @@ -1,4 +1,4 @@ -// This tool is used to define a very simple line between two points. +// Tool is used to define a very simple line between two points. // It is used by the BlueprintScaler to specify a sample distance to scale. var LineTool = MapTool.extend(function(base){ diff --git a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js index 918ac0d..6ced728 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/ortho.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/ortho.js @@ -1,6 +1,7 @@ +// Tool to make a polyline where all walls are orthogonal + var OrthoPolylineTool = MapTool.extend(function (base) { - // this will work like normal polyline except all walls will be orthogonal - + var prev_point, horizontal = false, first_edge_is_horizontal = false var exports = {} diff --git a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js index 6716180..445ae26 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/polyline.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/polyline.js @@ -1,3 +1,5 @@ +// Tool used to draw polylines with arbitrary angles + var PolylineTool = MapTool.extend(function (base) { var exports = {} exports.down = function(e, cursor){ diff --git a/public/assets/javascripts/rectangles/engine/map/tools/position.js b/public/assets/javascripts/rectangles/engine/map/tools/position.js index a994f5a..f8365bc 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/position.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/position.js @@ -1,3 +1,5 @@ +// Tool used to set position on the map and let you change the view by dragging. + var PositionTool = MapTool.extend(function(base){ var exports = { recenterCursor: false, diff --git a/public/assets/javascripts/rectangles/engine/map/tools/start.js b/public/assets/javascripts/rectangles/engine/map/tools/start.js index cca387c..203a85f 100644 --- a/public/assets/javascripts/rectangles/engine/map/tools/start.js +++ b/public/assets/javascripts/rectangles/engine/map/tools/start.js @@ -1,4 +1,4 @@ -// This tool is used to set the start position on the map. +// Tool is used to set the start position on the map. var StartPositionTool = MapTool.extend(function(base){ var exports = {} diff --git a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js index fbb71d5..fe1073a 100644 --- a/public/assets/javascripts/ui/blueprint/BlueprintUploader.js +++ b/public/assets/javascripts/ui/blueprint/BlueprintUploader.js @@ -37,8 +37,12 @@ var BlueprintUploader = UploadView.extend({ if (data && data.length) { this.$blueprints.show() data.forEach(this.append.bind(this)) - this.hide() - if (this.nameToShow && this.nameToShow !== "new") { + if (this.nameToShow === "new") { + // don't pick anything.. + this.show() + } + else if (! this.nameToShow) { + this.hide() data.some(function(el){ if (el.slug == this.nameToShow) { this.parent.scaler.pick(el) @@ -47,6 +51,7 @@ var BlueprintUploader = UploadView.extend({ }.bind(this)) } else { + this.hide() this.parent.scaler.pick(data[0]) } } diff --git a/public/assets/javascripts/ui/site/LayoutsModal.js b/public/assets/javascripts/ui/site/LayoutsModal.js index 87251af..a9c6ef0 100644 --- a/public/assets/javascripts/ui/site/LayoutsModal.js +++ b/public/assets/javascripts/ui/site/LayoutsModal.js @@ -6,6 +6,10 @@ var LayoutsIndex = View.extend({ this.$templatesList = this.$(".templates-list") this.$noTemplates = this.$(".no-templates") this.$form = this.$("form") + + this.$userTemplatesList = this.$(".userTemplatesList") + this.$blueprintsList = this.$(".blueprintsList") + this.$newBlueprintButton = this.$("[data-role='create-new-blueprint']") }, load: function(type){ @@ -15,11 +19,6 @@ var LayoutsIndex = View.extend({ }, populate: function(data){ -/* - if (data.user.plan_level < 1 && data.projectCount == 1) { - // show lockout message - } -*/ if (! data.layouts.length) { this.$templates.hide() this.$form.hide() @@ -89,20 +88,89 @@ var LayoutsModal = ModalView.extend(LayoutsIndex.prototype).extend({ action: "/api/layout", events: { - "click .templates span": 'toggleActive', + "click .templates span": 'pick', + "click .userTemplates span": 'pick', + "click .blueprints span": 'pickBlueprint', "submit form": 'newLayout', }, - toggleActive: function(e){ + pick: function(e){ e.preventDefault() - this.$(".templates .active").removeClass("active") var $layout = $(e.currentTarget) - $layout.addClass("active") + window.location.pathname = "/layout/" + $layout.data("slug") + }, + + pick: function(e){ + e.preventDefault() + var $blueprint = $(e.currentTarget) + $blueprint.addClass("active") - // actually do window.location.pathname = "/layout/" + $layout.data("slug") }, - + + populate: function(data){ +/* + if (data.user.plan_level < 1 && data.projectCount == 1) { + // show lockout message + } +*/ + if (! data.layouts.length) { + this.$templates.hide() + this.$form.hide() + this.$noTemplates.show() + } + this.$templatesList.empty() + data.layouts.forEach(function(room){ + var $span = $("") + $span.data("slug", room.slug) + + var $label = $("