Scenery.resize = new function(){ var base = this var obj var x, y, z, bounds var dragging = false var naturalDimension, 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 dot.side = side $(dot.el).on({ mouseenter: function(){ base.hovering = true }, mouseleave: function(){ base.hovering = false }, }) dots.push(dot) } base.add_dots = function(){ dots.forEach(function(dot){ scene.add(dot) }) } // rotate the dots as appropriate base.rotate_dots = function(){ rotationY = wall_rotation[obj.wall.side] dots.forEach(function(dot){ dot.rotationY = rotationY }) } // move all the dots to the object's current position base.move_dots = function(){ x = obj.mx.x + sin(rotationY) * dot_distance_from_picture y = obj.mx.y z = obj.mx.z - cos(rotationY) * dot_distance_from_picture dots.forEach(function(dot){ base.move_dot(dot) }) } // move a dot .. to the initial position of the image base.move_dot = function(dot){ dot.x = x dot.y = y dot.z = z if (dot.side & TOP) { dot.y += obj.mx.height * obj.mx.scale / 2 } if (dot.side & BOTTOM) { dot.y -= obj.mx.height * obj.mx.scale / 2 } if (dot.side & LEFT) { dot.x -= cos(rotationY) * (obj.mx.width * obj.mx.scale) / 2 dot.z -= sin(rotationY) * (obj.mx.width * obj.mx.scale) / 2 } if (dot.side & RIGHT) { dot.x += cos(rotationY) * (obj.mx.width * obj.mx.scale) / 2 dot.z += sin(rotationY) * (obj.mx.width * obj.mx.scale) / 2 } } // pick a new object to focus on and show the dots base.show = function(new_object) { // if (obj === new_object) return obj = new_object base.add_dots() base.rotate_dots() base.move_dots() } // dismiss the dots on blur var dotsHideTimeout; base.defer_hide = function(){ clearTimeout(dotsHideTimeout) dotsHideTimeout = setTimeout(function(){ if (Scenery.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) $(dot.el).bind({ mouseenter: function(e){ Scenery.resize.hovering = true }, mouseleave: function(e){ // Scenery.resize.hovering = false // base.defer_hide() } }) }) Scenery.mouse.on("down", down) Scenery.mouse.on("drag", drag) Scenery.mouse.on("up", up) } this.unbind = function(){ dots.forEach(function(dot){ Scenery.mouse.unbind_el(dot.el) }) Scenery.mouse.off("down", down) Scenery.mouse.off("drag", drag) Scenery.mouse.off("up", up) } function down (e, cursor){ var selection = dots.filter(function(dot){return e.target == dot.el}) if (! selection.length) return selected_dot = selection[0] dragging = true naturalDimension = obj.naturalDimensions dimension = obj.dimensions position = new vec3(obj.mx.x, obj.mx.y, obj.mx.z) scale = obj.mx.scale oldState = obj.serialize() 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() var old_width = dimension.a * scale if (abs(width) > abs(height)) { mag = x_sign * mag * sign(width) } else { mag = y_sign * mag * sign(height) } obj.set_scale( ( dimension.a + mag ) / naturalDimension.a ) // dimension.a // scale * (old_width + mag) / old_width // console.log(scale, obj.mx.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 selected_dot = null 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-scenery', undo: oldState, redo: obj.serialize(), }) // TODO: watch individual scenery object here Minotaur.watch( app.router.editorView.settings ) document.body.classList.remove("dragging") } }