Scenery.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 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) }) } // rotate the dots as appropriate base.rotate_dots = function(){ rotationY = obj.wall.rotationY dots.forEach(function(dot){ dot.rotationY = rotationY }) } // move all the dots to the object's current position base.move_dots = function(){ 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 }) }) } // 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 obj = new_object base.add_dots() base.rotate_dots() base.move_dots() } // dismiss the dots on blur var dotsHideTimeout; base.defer_hide = function(){ clearTimeout(dotsHideTimeout) dotsHideTimeout = setTimeout(function(){ if (Scenery.hovering || Scenery.resize.hovering || Scenery.mouse.down) return Scenery.resize.hide() }, dot_hide_delay) } base.hide = function () { if (! obj) return obj = null dots.forEach(function(dot){ scene.remove(dot) }) } base.bind = function(){ dots.forEach(function(dot){ Scenery.mouse.bind_el(dot.el) }) Scenery.mouse.on("down", down) Scenery.mouse.on("drag", drag) Scenery.mouse.on("up", up) } base.unbind = function(){ dots.forEach(function(dot){ Scenery.mouse.unbind_el(dot.el) }) Scenery.mouse.off("down", down) Scenery.mouse.off("drag", drag) Scenery.mouse.off("up", up) } function down (e, cursor){ var selection = dots.filter(function(dot){return e.target == dot.el}) if (! selection.length) return selected_dot = selection[0] dragging = true 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.router.editorView.mediaEditor.setDimensions() } function up (e, cursor){ if (! dragging) return dragging = false if (! editor.permissions.resize) { return } if (obj.type == "text") { var newHeight = $(obj.mx.inner).height() if (selected_dot.side & BOTTOM) { obj.mx.y = position.b + (naturalDimensionCopy.b - newHeight) / 2 * obj.scale } else { obj.mx.y = dots[0].y - newHeight/2*obj.scale } obj.mx.height = obj.media.height = naturalDimension.b = newHeight dimension.a = naturalDimension.a * obj.scale dimension.b = naturalDimension.b * obj.scale base.move_dots() } else { obj.scale = obj.mx.ops.scale = obj.mx.scale obj.dimensions.assign(obj.naturalDimensions).mul(obj.scale) } UndoStack.push({ type: 'update-scenery', 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 } }