From 899bd0810adc0e486f6c3c6621703a386e76261a Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Sat, 10 Jun 2017 14:21:09 +0200 Subject: [PATCH] Improve dragger --- src/canvas/index.js | 4 +- src/canvas/view/CanvasView.js | 11 +++- src/commands/index.js | 44 ++++++++++--- src/commands/view/Drag.js | 10 +-- src/utils/Dragger.js | 120 ++++++++++++++++++++++++++-------- 5 files changed, 141 insertions(+), 48 deletions(-) diff --git a/src/canvas/index.js b/src/canvas/index.js index 540165efe..cef7a9bb0 100644 --- a/src/canvas/index.js +++ b/src/canvas/index.js @@ -204,8 +204,8 @@ module.exports = () => { * @param {HTMLElement} el * @return {Object} */ - getElementPos(el) { - return CanvasView.getElementPos(el); + getElementPos(el, opts) { + return CanvasView.getElementPos(el, opts); }, /** diff --git a/src/canvas/view/CanvasView.js b/src/canvas/view/CanvasView.js index f88bbd1e6..032b96e6a 100644 --- a/src/canvas/view/CanvasView.js +++ b/src/canvas/view/CanvasView.js @@ -154,12 +154,17 @@ module.exports = Backbone.View.extend({ * @return {Object} * @private */ - getElementPos(el) { + getElementPos(el, opts) { + var opt = opts || {}; var frmOff = this.getFrameOffset(); var cvsOff = this.getCanvasOffset(); var eo = this.offset(el); - var top = eo.top + frmOff.top - cvsOff.top; - var left = eo.left + frmOff.left - cvsOff.left; + + var frmTop = opt.avoidFrameOffset ? 0 : frmOff.top; + var frmLeft = opt.avoidFrameOffset ? 0 : frmOff.left; + + var top = eo.top + frmTop - cvsOff.top; + var left = eo.left + frmLeft - cvsOff.left; return { top, left, diff --git a/src/commands/index.js b/src/commands/index.js index dc4996dda..406706d8f 100644 --- a/src/commands/index.js +++ b/src/commands/index.js @@ -140,33 +140,57 @@ module.exports = () => { defaultCommands['tlb-move'] = { run(ed, sender, opts) { var sel = ed.getSelected(); + var dragger; if(!sel || !sel.get('draggable')) { console.warn('The element is not draggable'); return; } + const onStart = (e, opts) => { + console.log('start mouse pos ', opts.start); + console.log('el rect ', opts.elRect); + var el = opts.el; + el.style.position = 'absolute'; + el.style.margin = 0; + }; + + const onEnd = (e, opts) => { + em.runDefault(); + em.set('selectedComponent', sel); + ed.trigger('component:update', sel); + dragger && dragger.blur(); + console.log('onEnd ', opts); + }; + + const onDrag = (e, opts) => { + console.log('Delta ', opts.delta); + console.log('Current ', opts.current); + }; + var toolbarEl = ed.Canvas.getToolbarEl(); toolbarEl.style.display = 'none'; + var em = ed.getModel(); + em.stopDefault(); - if (ed.getModel().get('designerMode')) { + if (em.get('designerMode')) { // TODO move grabbing func in editor/canvas from the Sorter - editor.runCommand('drag', { + dragger = editor.runCommand('drag', { el: sel.view.el, options: { event: opts && opts.event, + onStart, + onDrag, + onEnd } }); + } else { + var cmdMove = ed.Commands.get('move-comp'); + cmdMove.onEndMoveFromModel = onEnd; + cmdMove.initSorterFromModel(sel); } - 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'); }, }; diff --git a/src/commands/view/Drag.js b/src/commands/view/Drag.js index 0ce4ba823..567d56754 100644 --- a/src/commands/view/Drag.js +++ b/src/commands/view/Drag.js @@ -5,13 +5,13 @@ module.exports = { var canvas = editor.Canvas; var dragger = this.dragger; var options = opts.options || {}; + var canvasView = canvas.getCanvasView(); + options.prefix = editor.getConfig().stylePrefix; + options.mousePosFetcher = canvas.getMouseRelativePos; + options.posFetcher = canvasView.getElementPos.bind(canvasView); // 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; } @@ -22,6 +22,8 @@ module.exports = { if (options.event) { dragger.start(options.event); } + + return dragger; }, stop() { diff --git a/src/utils/Dragger.js b/src/utils/Dragger.js index e28f250ed..7e5b7f63f 100644 --- a/src/utils/Dragger.js +++ b/src/utils/Dragger.js @@ -23,7 +23,9 @@ module.exports = { */ getElementRect(el) { var posFetcher = this.opts.posFetcher || ''; - return posFetcher ? posFetcher(el) : getBoundingRect(el); + return posFetcher ? posFetcher(el, { + avoidFrameOffset: 1, + }) : getBoundingRect(el); }, /** @@ -57,22 +59,20 @@ module.exports = { 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); + var elRect = this.getElementRect(el); //<-- TODO have wrong top:left + this.elRect = elRect; this.startTop = elRect.top; this.startLeft = elRect.left; - // setModelTop, setModelLeft // TODO init snapper + this.getDocumentEl().on('mousedown', this.handleMouseDown); }, @@ -80,7 +80,6 @@ module.exports = { * Blur from the focused element */ blur() { - console.log('BLUR'); this.getDocumentEl().off('mousedown', this.handleMouseDown); this.el = null; }, @@ -91,22 +90,45 @@ module.exports = { */ 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); + var docs = this.getDocumentEl(); + docs.on('mousemove', this.drag); + docs.on('mouseup', this.stop); + + // Start callback + var onStart = this.opts.onStart; + if(typeof onStart === 'function') { + onStart(e, { + docs, + el: this.el, + start: this.startPos, + elRect: this.elRect, + }); + } + this.drag(e); }, /** * Stop dragging */ - stop() { - console.log('Stop'); - var doc = this.getDocumentEl(); - doc.off('mousemove', this.drag); - doc.off('mouseup', this.stop); + stop(e) { + var docs = this.getDocumentEl(); + docs.off('mousemove', this.drag); + docs.off('mouseup', this.stop); this.lockedAxis = null; + + // Stop callback + var onEnd = this.opts.onEnd; + if(typeof onEnd === 'function') { + onEnd(e, { + docs, + delta: this.delta, + end: { + x: this.startLeft + this.delta.x, + y: this.startTop + this.delta.y, + } + }); + } }, /** @@ -115,7 +137,6 @@ module.exports = { */ handleMouseDown(e) { var el = e.target; - console.log('handleMouseDown'); if (this.isHandler(el)) { this.start(e); } @@ -168,7 +189,6 @@ module.exports = { if (el) { docs.push(el.ownerDocument); } - console.log(docs); this.$doc = $(docs); } return this.$doc; @@ -192,14 +212,13 @@ module.exports = { * @param {Event} event */ drag(e) { - console.log('dragging'); var lockedAxis = this.lockedAxis; var currentPos = this.getMousePos(e); var delta = { x: currentPos.x - this.startPos.x, y: currentPos.y - this.startPos.y }; - // lock one axis + // Lock one axis if (e.shiftKey) { if (!lockedAxis) { var relX = delta.x; @@ -227,35 +246,78 @@ module.exports = { } this.lockedAxis = lockedAxis; + this.delta = delta; this.move(delta.x, delta.y); + // Drag callback + const onDrag = this.opts.onDrag; + if(typeof onDrag === 'function') { + onDrag(e, { + delta, + current: { + x: this.startLeft + delta.x, + y: this.startTop + delta.y + }, + lockedAxis + }); + } + // In case the mouse button was released outside of the window if (e.which === 0) { this.stop(e); } }, + /** + * Move the element + * @param {integer} x + * @param {integer} y + */ move: function(x, y) { - console.log(`Drag X: ${x} Y: ${y}`); this.moveX(x); this.moveY(y); }, + /** + * Move in x direction + * @param {integer} x + */ moveX(x) { var el = this.el; var opts = this.opts; - //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'; + var xPos = this.startLeft + x; + const setX = this.opts.setX; + + if (typeof setX === 'function') { + setX(xPos, { + el, + start: this.startLeft, + delta: x, + }); + } else { + el.style.left = xPos + 'px'; + } }, + /** + * Move in y direction + * @param {integer} y + */ moveY(y) { var el = this.el; var opts = this.opts; - //el.style.top += y; - console.log('Y ', this.startTop, y, this.startTop + y); - el.style.top = this.startTop + y + 'px'; + var yPos = this.startTop + y; + const setY = this.opts.setY; + + if (typeof setY === 'function') { + setY(yPos, { + el, + start: this.startTop, + delta: y, + }); + } else { + el.style.top = yPos + 'px'; + } }, };