From a72d5a517938c52993b49c57ff13419772d8eac5 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 8 Jun 2017 22:02:27 +0200 Subject: [PATCH] Start with drag command --- src/commands/index.js | 18 +- src/commands/view/Drag.js | 32 ++++ src/dom_components/view/ToolbarButtonView.js | 7 +- src/editor/model/Editor.js | 2 +- src/utils/Dragger.js | 181 ++++++++++++++++--- src/utils/index.js | 8 +- 6 files changed, 208 insertions(+), 40 deletions(-) create mode 100644 src/commands/view/Drag.js diff --git a/src/commands/index.js b/src/commands/index.js index 38f3e309a..dc4996dda 100644 --- a/src/commands/index.js +++ b/src/commands/index.js @@ -103,6 +103,7 @@ module.exports = () => { defaultCommands.fullscreen = require('./view/Fullscreen'); defaultCommands.preview = require('./view/Preview'); defaultCommands.resize = require('./view/Resize'); + defaultCommands.drag = require('./view/Drag'); defaultCommands['tlb-delete'] = { run(ed) { @@ -137,7 +138,7 @@ module.exports = () => { }; defaultCommands['tlb-move'] = { - run(ed) { + run(ed, sender, opts) { var sel = ed.getSelected(); if(!sel || !sel.get('draggable')) { @@ -146,18 +147,27 @@ module.exports = () => { } var toolbarEl = ed.Canvas.getToolbarEl(); - var cmdMove = ed.Commands.get('move-comp'); + toolbarEl.style.display = 'none'; + + if (ed.getModel().get('designerMode')) { + // TODO move grabbing func in editor/canvas from the Sorter + editor.runCommand('drag', { + el: sel.view.el, + options: { + event: opts && opts.event, + } + }); + } + var cmdMove = ed.Commands.get('move-comp'); cmdMove.onEndMoveFromModel = () => { ed.editor.runDefault(); ed.editor.set('selectedComponent', sel); ed.trigger('component:update', sel); }; - ed.editor.stopDefault(); cmdMove.initSorterFromModel(sel); sel.set('status', 'selected'); - toolbarEl.style.display = 'none'; }, }; diff --git a/src/commands/view/Drag.js b/src/commands/view/Drag.js new file mode 100644 index 000000000..0ce4ba823 --- /dev/null +++ b/src/commands/view/Drag.js @@ -0,0 +1,32 @@ +module.exports = { + + run(editor, sender, opts) { + var el = (opts && opts.el) || ''; + var canvas = editor.Canvas; + var dragger = this.dragger; + var options = opts.options || {}; + + // Create the resizer for the canvas if not yet created + if(!dragger) { + var canvasView = canvas.getCanvasView(); + options.prefix = editor.getConfig().stylePrefix; + options.posFetcher = canvasView.getElementPos.bind(canvasView); + options.mousePosFetcher = canvas.getMouseRelativePos; + dragger = editor.Utils.Dragger.init(options); + this.dragger = dragger; + } + + dragger.setOptions(options); + dragger.focus(el); + + if (options.event) { + dragger.start(options.event); + } + }, + + stop() { + if(this.canvasResizer) + this.canvasResizer.blur(); + }, + +}; diff --git a/src/dom_components/view/ToolbarButtonView.js b/src/dom_components/view/ToolbarButtonView.js index e0ea6d24b..252ce4dd9 100644 --- a/src/dom_components/view/ToolbarButtonView.js +++ b/src/dom_components/view/ToolbarButtonView.js @@ -13,15 +13,16 @@ module.exports = Backbone.View.extend({ this.editor = opts.config.editor; }, - handleClick() { + handleClick(event) { + var opts = {event}; var command = this.model.get('command'); if (typeof command === 'function') { - command(this.editor); + command(this.editor, null, opts); } if (typeof command === 'string') { - this.editor.runCommand(command); + this.editor.runCommand(command, opts); } }, diff --git a/src/editor/model/Editor.js b/src/editor/model/Editor.js index 625dce2f4..342e530ac 100644 --- a/src/editor/model/Editor.js +++ b/src/editor/model/Editor.js @@ -1,5 +1,5 @@ var deps = [ -require('Utils'), +require('utils'), require('storage_manager'), require('device_manager'), require('parser'), diff --git a/src/utils/Dragger.js b/src/utils/Dragger.js index 0fa74c9e1..e28f250ed 100644 --- a/src/utils/Dragger.js +++ b/src/utils/Dragger.js @@ -1,3 +1,14 @@ +var getBoundingRect = (el, win) => { + var w = win || window; + var rect = el.getBoundingClientRect(); + return { + left: rect.left + w.pageXOffset, + top: rect.top + w.pageYOffset, + width: rect.width, + height: rect.height + }; +}; + module.exports = { // TODO move to opts @@ -5,13 +16,124 @@ module.exports = { //key(keys, command); }, + /** + * Return element position + * @param {HTMLElement} el + * @return {Object} + */ + getElementRect(el) { + var posFetcher = this.opts.posFetcher || ''; + return posFetcher ? posFetcher(el) : getBoundingRect(el); + }, + /** * Init the resizer * @param {Object} opts */ init(opts) { + this.setOptions(opts); + this.handleMouseDown = this.handleMouseDown.bind(this); + this.drag = this.drag.bind(this); + this.move = this.move.bind(this); + this.stop = this.stop.bind(this); + this.setKey('up, right, down, left', this.handleKey); + return this; + }, + + /** + * Update options + * @param {Object} options + */ + setOptions(opts) { this.opts = opts || {}; - setKey('up, right, down, left', this.handleKey); + }, + + /** + * Focus dragger on the element + * @param {HTMLElement} el + */ + focus(el) { + // Avoid focusing on already focused element + if (el && el === this.el) { + return; + } + this.getDocumentEl(el); + this.blur(); + this.el = el; + this.handlers = this.opts.dragHandlers || [el]; + + this.el.style.position = 'absolute'; + this.el.style.margin = 0; + + + var elRect = this.getElementRect(el); + console.log('elRect', elRect); + this.startTop = elRect.top; + this.startLeft = elRect.left; + // setModelTop, setModelLeft + + // TODO init snapper + this.getDocumentEl().on('mousedown', this.handleMouseDown); + }, + + /** + * Blur from the focused element + */ + blur() { + console.log('BLUR'); + this.getDocumentEl().off('mousedown', this.handleMouseDown); + this.el = null; + }, + + /** + * Start dragging + * @param {Event} e + */ + start(e) { + this.startPos = this.getMousePos(e); + var doc = this.getDocumentEl(); + console.log('startPos', this.startPos); + doc.on('mousemove', this.drag); + doc.on('mouseup', this.stop); + this.drag(e); + }, + + /** + * Stop dragging + */ + stop() { + console.log('Stop'); + var doc = this.getDocumentEl(); + doc.off('mousemove', this.drag); + doc.off('mouseup', this.stop); + this.lockedAxis = null; + }, + + /** + * Handle mousedown to check if it's possible to drag + * @param {Event} e + */ + handleMouseDown(e) { + var el = e.target; + console.log('handleMouseDown'); + if (this.isHandler(el)) { + this.start(e); + } + }, + + /** + * Detects if the clicked element is a valid handler + * @param {HTMLElement} el + * @return {Boolean} + */ + isHandler(el) { + var handlers = this.handlers; + + for (var n in handlers) { + if (handlers[n] === el) return true; + } + + return false; }, /** @@ -36,6 +158,22 @@ module.exports = { } }, + /** + * Returns documents + */ + getDocumentEl(el) { + var el = el || this.el; + if (!this.$doc) { + var docs = [document]; + if (el) { + docs.push(el.ownerDocument); + } + console.log(docs); + this.$doc = $(docs); + } + return this.$doc; + }, + /** * Get mouse coordinates * @param {Event} event @@ -49,29 +187,12 @@ module.exports = { }; }, - /** - * Start to drag - * @param {HTMLElement} el Element to drag - * @param {Event} e - */ - startToDrag(el, e) { - e.stopPropagation(); - this.el = el; - this.startPos = this.getMousePos(e); - var doc = this.getDocumentEl(); - doc.on('mousemove', this.drag); - doc.on('mouseup', this.stopToDrag); - - // TODO init snapper - - this.drag(event); - }, - /** * Drag event * @param {Event} event */ drag(e) { + console.log('dragging'); var lockedAxis = this.lockedAxis; var currentPos = this.getMousePos(e); var delta = { @@ -107,9 +228,15 @@ module.exports = { this.lockedAxis = lockedAxis; this.move(delta.x, delta.y); + + // In case the mouse button was released outside of the window + if (e.which === 0) { + this.stop(e); + } }, move: function(x, y) { + console.log(`Drag X: ${x} Y: ${y}`); this.moveX(x); this.moveY(y); }, @@ -117,20 +244,18 @@ module.exports = { moveX(x) { var el = this.el; var opts = this.opts; - el.style.left += x; + //el.style.left += x; + // Top & left are component related + console.log('X ', this.startLeft, x, this.startLeft + x); + el.style.left = this.startLeft + x + 'px'; }, moveY(y) { var el = this.el; var opts = this.opts; - el.style.top += y; - }, - - stopToDrag(event) { - var doc = this.getDocumentEl(); - doc.off('mousemove', this.drag); - doc.off('mouseup', this.stopToDrag); - this.lockedAxis = null; + //el.style.top += y; + console.log('Y ', this.startTop, y, this.startTop + y); + el.style.top = this.startTop + y + 'px'; }, }; diff --git a/src/utils/index.js b/src/utils/index.js index 6e1c98e15..e4fcd5aa7 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -1,8 +1,8 @@ module.exports = () => { - var Sorter = require('./Sorter'); - - var Resizer = require('./Resizer'); + const Sorter = require('./Sorter'); + const Resizer = require('./Resizer'); + const Dragger = require('./Dragger'); return { /** @@ -20,7 +20,7 @@ module.exports = () => { }, Sorter, - Resizer, + Dragger, }; };