mirror of https://github.com/artf/grapesjs.git
committed by
GitHub
80 changed files with 2883 additions and 2062 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 7.8 KiB |
@ -0,0 +1,77 @@ |
|||
import { bindAll } from 'underscore'; |
|||
import { on, off, getKeyChar } from 'utils/mixins'; |
|||
import Dragger from 'utils/Dragger'; |
|||
|
|||
module.exports = { |
|||
run(ed) { |
|||
bindAll(this, 'onKeyUp', 'enableDragger', 'disableDragger'); |
|||
this.editor = ed; |
|||
this.canvasModel = this.canvas.getCanvasView().model; |
|||
this.toggleMove(1); |
|||
}, |
|||
stop(ed) { |
|||
this.toggleMove(); |
|||
this.disableDragger(); |
|||
}, |
|||
|
|||
onKeyUp(ev) { |
|||
if (getKeyChar(ev) === ' ') { |
|||
this.editor.stopCommand(this.id); |
|||
} |
|||
}, |
|||
|
|||
enableDragger(ev) { |
|||
this.toggleDragger(1, ev); |
|||
}, |
|||
|
|||
disableDragger(ev) { |
|||
this.toggleDragger(0, ev); |
|||
}, |
|||
|
|||
toggleDragger(enable, ev) { |
|||
const { canvasModel, em } = this; |
|||
let { dragger } = this; |
|||
const methodCls = enable ? 'add' : 'remove'; |
|||
this.getCanvas().classList[methodCls](`${this.ppfx}is__grabbing`); |
|||
|
|||
if (!dragger) { |
|||
dragger = new Dragger({ |
|||
getPosition() { |
|||
return { |
|||
x: canvasModel.get('x'), |
|||
y: canvasModel.get('y') |
|||
}; |
|||
}, |
|||
setPosition({ x, y }) { |
|||
canvasModel.set({ x, y }); |
|||
}, |
|||
onStart(ev, dragger) { |
|||
em.trigger('canvas:move:start', dragger); |
|||
}, |
|||
onDrag(ev, dragger) { |
|||
em.trigger('canvas:move', dragger); |
|||
}, |
|||
onEnd(ev, dragger) { |
|||
em.trigger('canvas:move:end', dragger); |
|||
} |
|||
}); |
|||
this.dragger = dragger; |
|||
} |
|||
|
|||
enable ? dragger.start(ev) : dragger.stop(); |
|||
}, |
|||
|
|||
toggleMove(enable) { |
|||
const { ppfx } = this; |
|||
const methodCls = enable ? 'add' : 'remove'; |
|||
const methodEv = enable ? 'on' : 'off'; |
|||
const methodsEv = { on, off }; |
|||
const canvas = this.getCanvas(); |
|||
const classes = [`${ppfx}is__grab`]; |
|||
!enable && classes.push(`${ppfx}is__grabbing`); |
|||
classes.forEach(cls => canvas.classList[methodCls](cls)); |
|||
methodsEv[methodEv](document, 'keyup', this.onKeyUp); |
|||
methodsEv[methodEv](canvas, 'mousedown', this.enableDragger); |
|||
methodsEv[methodEv](document, 'mouseup', this.disableDragger); |
|||
} |
|||
}; |
|||
@ -0,0 +1,135 @@ |
|||
import { keys, bindAll } from 'underscore'; |
|||
import Dragger from 'utils/Dragger'; |
|||
|
|||
module.exports = { |
|||
run(editor, sender, opts = {}) { |
|||
bindAll(this, 'setPosition', 'onStart', 'onEnd', 'getPosition'); |
|||
const { target, event, mode } = opts; |
|||
const { Canvas } = editor; |
|||
const el = target.getEl(); |
|||
const scale = Canvas.getZoomMultiplier(); |
|||
const config = { |
|||
scale, |
|||
doc: el.ownerDocument, |
|||
onStart: this.onStart, |
|||
onEnd: this.onEnd, |
|||
getPosition: this.getPosition, |
|||
setPosition: this.setPosition |
|||
}; |
|||
this.opts = opts; |
|||
this.editor = editor; |
|||
this.target = target; |
|||
this.isTran = mode == 'translate'; |
|||
let dragger = this.dragger; |
|||
|
|||
if (!dragger) { |
|||
dragger = new Dragger(config); |
|||
this.dragger = dragger; |
|||
} else { |
|||
dragger.setOptions(config); |
|||
} |
|||
|
|||
event && dragger.start(event); |
|||
this.toggleDrag(1); |
|||
|
|||
return dragger; |
|||
}, |
|||
|
|||
stop() { |
|||
this.toggleDrag(); |
|||
}, |
|||
|
|||
getTranslate(transform, axis = 'x') { |
|||
let result = 0; |
|||
(transform || '').split(' ').forEach(item => { |
|||
const itemStr = item.trim(); |
|||
const fn = `translate${axis.toUpperCase()}(`; |
|||
if (itemStr.indexOf(fn) === 0) |
|||
result = parseFloat(itemStr.replace(fn, '')); |
|||
}); |
|||
return result; |
|||
}, |
|||
|
|||
setTranslate(transform, axis, value) { |
|||
const fn = `translate${axis.toUpperCase()}(`; |
|||
const val = `${fn}${value})`; |
|||
let result = (transform || '') |
|||
.split(' ') |
|||
.map(item => { |
|||
const itemStr = item.trim(); |
|||
if (itemStr.indexOf(fn) === 0) item = val; |
|||
return item; |
|||
}) |
|||
.join(' '); |
|||
if (result.indexOf(fn) < 0) result += ` ${val}`; |
|||
|
|||
return result; |
|||
}, |
|||
|
|||
getPosition() { |
|||
const { target, isTran } = this; |
|||
const { left, top, transform } = target.getStyle(); |
|||
let x = 0; |
|||
let y = 0; |
|||
|
|||
if (isTran) { |
|||
x = this.getTranslate(transform); |
|||
y = this.getTranslate(transform, 'y'); |
|||
} else { |
|||
(x = parseFloat(left)), (y = parseFloat(top)); |
|||
} |
|||
|
|||
return { x, y }; |
|||
}, |
|||
|
|||
setPosition({ x, y, end, position, width, height }) { |
|||
const { target, isTran } = this; |
|||
const unit = 'px'; |
|||
const en = !end ? 1 : ''; // this will trigger the final change
|
|||
const left = `${x}${unit}`; |
|||
const top = `${y}${unit}`; |
|||
|
|||
if (isTran) { |
|||
let transform = target.getStyle()['transform'] || ''; |
|||
transform = this.setTranslate(transform, 'x', left); |
|||
transform = this.setTranslate(transform, 'y', top); |
|||
return target.addStyle({ transform, en }, { avoidStore: !end }); |
|||
} |
|||
|
|||
const adds = { position, width, height }; |
|||
const style = { left, top, en }; |
|||
keys(adds).forEach(add => { |
|||
const prop = adds[add]; |
|||
if (prop) style[add] = prop; |
|||
}); |
|||
target.addStyle(style, { avoidStore: !end }); |
|||
}, |
|||
|
|||
onStart() { |
|||
const { target, editor, isTran } = this; |
|||
const style = target.getStyle(); |
|||
const position = 'absolute'; |
|||
if (isTran) return; |
|||
|
|||
if (style.position !== position) { |
|||
const { left, top, width, height } = editor.Canvas.offset(target.getEl()); |
|||
this.setPosition({ x: left, y: top, position, width, height }); |
|||
} |
|||
}, |
|||
|
|||
onEnd() { |
|||
const { editor, opts, id } = this; |
|||
const { onEnd } = opts; |
|||
onEnd && onEnd(); |
|||
editor.stopCommand(id); |
|||
}, |
|||
|
|||
toggleDrag(on) { |
|||
const { ppfx, editor } = this; |
|||
const methodCls = on ? 'add' : 'remove'; |
|||
const canvas = this.getCanvas(); |
|||
const classes = [`${ppfx}is__grabbing`]; |
|||
classes.forEach(cls => canvas.classList[methodCls](cls)); |
|||
editor.Canvas[on ? 'startAutoscroll' : 'stopAutoscroll'](); |
|||
} |
|||
}; |
|||
@ -1,31 +0,0 @@ |
|||
module.exports = { |
|||
run(editor, sender, opts) { |
|||
var el = (opts && opts.el) || ''; |
|||
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) { |
|||
dragger = editor.Utils.Dragger.init(options); |
|||
this.dragger = dragger; |
|||
} |
|||
|
|||
dragger.setOptions(options); |
|||
dragger.focus(el); |
|||
|
|||
if (options.event) { |
|||
dragger.start(options.event); |
|||
} |
|||
|
|||
return dragger; |
|||
}, |
|||
|
|||
stop() { |
|||
if (this.canvasResizer) this.canvasResizer.blur(); |
|||
} |
|||
}; |
|||
@ -1,34 +0,0 @@ |
|||
import _ from 'underscore'; |
|||
import Backbone from 'backbone'; |
|||
var InsertCustom = require('./InsertCustom'); |
|||
|
|||
module.exports = _.extend({}, InsertCustom, { |
|||
/** |
|||
* Trigger before insert |
|||
* @param {Object} object |
|||
* @private |
|||
* |
|||
* */ |
|||
beforeInsert(object) { |
|||
object.type = 'image'; |
|||
object.style = {}; |
|||
object.attributes = {}; |
|||
object.attributes.onmousedown = 'return false'; |
|||
if ( |
|||
this.config.firstCentered && |
|||
this.getCanvasWrapper() == this.sorter.target |
|||
) { |
|||
object.style.margin = '0 auto'; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Trigger after insert |
|||
* @param {Object} model Model created after insert |
|||
* @private |
|||
* */ |
|||
afterInsert(model) { |
|||
model.trigger('dblclick'); |
|||
if (this.sender) this.sender.set('active', false); |
|||
} |
|||
}); |
|||
@ -1,76 +0,0 @@ |
|||
import _ from 'underscore'; |
|||
import Backbone from 'backbone'; |
|||
var CreateComponent = require('./CreateComponent'); |
|||
|
|||
module.exports = _.extend({}, CreateComponent, { |
|||
init(...args) { |
|||
CreateComponent.init.apply(this, args); |
|||
_.bindAll(this, 'insertComponent'); |
|||
this.allowDraw = 0; |
|||
}, |
|||
|
|||
/** |
|||
* Run method |
|||
* @private |
|||
* */ |
|||
run(em, sender, options) { |
|||
this.em = em; |
|||
this.sender = sender; |
|||
this.opt = options || {}; |
|||
this.$wr = this.$wrapper; |
|||
this.enable(); |
|||
}, |
|||
|
|||
enable(...args) { |
|||
CreateComponent.enable.apply(this, args); |
|||
this.$wr.on('click', this.insertComponent); |
|||
}, |
|||
|
|||
/** |
|||
* Start insert event |
|||
* @private |
|||
* */ |
|||
insertComponent() { |
|||
this.$wr.off('click', this.insertComponent); |
|||
this.stopSelectPosition(); |
|||
var object = this.buildContent(); |
|||
this.beforeInsert(object); |
|||
var index = this.sorter.lastPos.index; |
|||
// By default, collections do not trigger add event, so silent is used
|
|||
var model = this.create(this.sorter.target, object, index, null, { |
|||
silent: false |
|||
}); |
|||
|
|||
if (this.opt.terminateAfterInsert && this.sender) |
|||
this.sender.set('active', false); |
|||
else this.enable(); |
|||
|
|||
if (!model) return; |
|||
|
|||
this.afterInsert(model, this); |
|||
}, |
|||
|
|||
/** |
|||
* Trigger before insert |
|||
* @param {Object} obj |
|||
* @private |
|||
* */ |
|||
beforeInsert(obj) {}, |
|||
|
|||
/** |
|||
* Trigger after insert |
|||
* @param {Object} model Model created after insert |
|||
* @private |
|||
* */ |
|||
afterInsert(model) {}, |
|||
|
|||
/** |
|||
* Create different object, based on content, to insert inside canvas |
|||
* |
|||
* @return {Object} |
|||
* @private |
|||
* */ |
|||
buildContent() { |
|||
return this.opt.content || {}; |
|||
} |
|||
}); |
|||
@ -1,27 +0,0 @@ |
|||
import _ from 'underscore'; |
|||
import Backbone from 'backbone'; |
|||
var CreateComponent = require('./CreateComponent'); |
|||
|
|||
module.exports = _.extend({}, CreateComponent, { |
|||
/** |
|||
* This event is triggered at the beginning of a draw operation |
|||
* @param {Object} component Object component before creation |
|||
* @private |
|||
* */ |
|||
beforeDraw(component) { |
|||
component.type = 'text'; |
|||
if (!component.style) component.style = {}; |
|||
component.style.padding = '10px'; |
|||
}, |
|||
|
|||
/** |
|||
* This event is triggered at the end of a draw operation |
|||
* @param {Object} model Component model created |
|||
* @private |
|||
* */ |
|||
afterDraw(model) { |
|||
if (!model || !model.set) return; |
|||
model.trigger('focus'); |
|||
if (this.sender) this.sender.set('active', false); |
|||
} |
|||
}); |
|||
@ -0,0 +1,18 @@ |
|||
$gjs-is-prefix: '.#{$app-prefix}is__'; |
|||
|
|||
@function gjs-is($name) { |
|||
@return '#{$gjs-is-prefix}#{$name}'; |
|||
} |
|||
|
|||
#{$gjs-is-prefix} { |
|||
&grab, |
|||
&grab * { |
|||
cursor: grab !important; |
|||
} |
|||
|
|||
&grabbing, |
|||
&grabbing * { |
|||
@include user-select(none); |
|||
cursor: grabbing !important; |
|||
} |
|||
} |
|||
@ -1,327 +1,228 @@ |
|||
import Backbone from 'backbone'; |
|||
const $ = Backbone.$; |
|||
|
|||
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
|
|||
setKey(keys, command) { |
|||
//key(keys, command);
|
|||
}, |
|||
import { bindAll, isFunction, result } from 'underscore'; |
|||
import { on, off } from 'utils/mixins'; |
|||
|
|||
export default class Dragger { |
|||
/** |
|||
* Return element position |
|||
* @param {HTMLElement} el |
|||
* @return {Object} |
|||
*/ |
|||
getElementRect(el) { |
|||
var posFetcher = this.opts.posFetcher || ''; |
|||
return posFetcher |
|||
? posFetcher(el, { |
|||
avoidFrameOffset: 1 |
|||
}) |
|||
: getBoundingRect(el); |
|||
}, |
|||
|
|||
/** |
|||
* Init the resizer |
|||
* Init the dragger |
|||
* @param {Object} opts |
|||
*/ |
|||
init(opts) { |
|||
constructor(opts = {}) { |
|||
this.opts = { |
|||
/** |
|||
* Callback on start |
|||
* onStart(ev, dragger) { |
|||
* console.log('pointer start', dragger.startPointer, 'position start', dragger.startPosition); |
|||
* }, |
|||
*/ |
|||
onStart: null, |
|||
/** |
|||
* Callback on drag |
|||
* onDrag(ev, dragger) { |
|||
* console.log('pointer', dragger.currentPointer, 'position', dragger.position, 'delta', dragger.delta); |
|||
* }, |
|||
*/ |
|||
onDrag: null, |
|||
/** |
|||
* Callback on drag |
|||
* onEnd(ev, dragger) { |
|||
* console.log('pointer', dragger.currentPointer, 'position', dragger.position, 'delta', dragger.delta); |
|||
* }, |
|||
*/ |
|||
onEnd: null, |
|||
/** |
|||
* Indicate a callback where to pass an object with new coordinates |
|||
*/ |
|||
setPosition: null, |
|||
/** |
|||
* Indicate a callback where to get initial coordinates. |
|||
* getPosition: () => { |
|||
* ... |
|||
* return { x: 10, y: 100 } |
|||
* } |
|||
*/ |
|||
getPosition: null, |
|||
|
|||
// Document on which listen to pointer events
|
|||
doc: 0, |
|||
|
|||
// Scale result points, can also be a function
|
|||
scale: 1 |
|||
}; |
|||
bindAll(this, 'drag', 'stop'); |
|||
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); |
|||
this.delta = { x: 0, y: 0 }; |
|||
return this; |
|||
}, |
|||
} |
|||
|
|||
/** |
|||
* Update options |
|||
* @param {Object} options |
|||
*/ |
|||
setOptions(opts) { |
|||
this.opts = opts || {}; |
|||
}, |
|||
|
|||
/** |
|||
* 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]; |
|||
|
|||
var elRect = this.getElementRect(el); //<-- TODO have wrong top:left
|
|||
this.elRect = elRect; |
|||
this.startTop = elRect.top; |
|||
this.startLeft = elRect.left; |
|||
|
|||
// TODO init snapper
|
|||
|
|||
this.getDocumentEl().on('mousedown', this.handleMouseDown); |
|||
}, |
|||
setOptions(opts = {}) { |
|||
this.opts = { |
|||
...this.opts, |
|||
...opts |
|||
}; |
|||
} |
|||
|
|||
/** |
|||
* Blur from the focused element |
|||
*/ |
|||
blur() { |
|||
this.getDocumentEl().off('mousedown', this.handleMouseDown); |
|||
this.el = null; |
|||
}, |
|||
toggleDrag(enable) { |
|||
const docs = this.getDocumentEl(); |
|||
const method = enable ? 'on' : 'off'; |
|||
const methods = { on, off }; |
|||
methods[method](docs, 'mousemove', this.drag); |
|||
methods[method](docs, 'mouseup', this.stop); |
|||
} |
|||
|
|||
/** |
|||
* Start dragging |
|||
* @param {Event} e |
|||
*/ |
|||
start(e) { |
|||
this.startPos = this.getMousePos(e); |
|||
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(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 |
|||
} |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Handle mousedown to check if it's possible to drag |
|||
* @param {Event} e |
|||
*/ |
|||
handleMouseDown(e) { |
|||
var el = e.target; |
|||
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; |
|||
}, |
|||
|
|||
/** |
|||
* Handle key press |
|||
* @param {Event} e |
|||
* @param {Object} handler |
|||
*/ |
|||
handleKey(e, handler) { |
|||
switch (handler.shortcut) { |
|||
case 'up': |
|||
this.move(0, -1); |
|||
break; |
|||
case 'right': |
|||
this.move(1, 0); |
|||
break; |
|||
case 'down': |
|||
this.move(0, 1); |
|||
break; |
|||
case 'left': |
|||
this.move(-1, 0); |
|||
break; |
|||
} |
|||
}, |
|||
|
|||
/** |
|||
* Returns documents |
|||
*/ |
|||
getDocumentEl(el) { |
|||
var el = el || this.el; |
|||
if (!this.$doc) { |
|||
var docs = [document]; |
|||
if (el) { |
|||
docs.push(el.ownerDocument); |
|||
} |
|||
this.$doc = $(docs); |
|||
} |
|||
return this.$doc; |
|||
}, |
|||
|
|||
/** |
|||
* Get mouse coordinates |
|||
* @param {Event} event |
|||
* @return {Object} |
|||
*/ |
|||
getMousePos(e) { |
|||
var mouseFetch = this.opts.mousePosFetcher; |
|||
return mouseFetch |
|||
? mouseFetch(e) |
|||
: { |
|||
x: e.clientX, |
|||
y: e.clientY |
|||
}; |
|||
}, |
|||
start(ev) { |
|||
const { onStart } = this.opts; |
|||
this.toggleDrag(1); |
|||
this.startPointer = this.getPointerPos(ev); |
|||
isFunction(onStart) && onStart(ev, this); |
|||
this.startPosition = this.getStartPosition(); |
|||
this.drag(ev); |
|||
} |
|||
|
|||
/** |
|||
* Drag event |
|||
* @param {Event} event |
|||
*/ |
|||
drag(e) { |
|||
var lockedAxis = this.lockedAxis; |
|||
var currentPos = this.getMousePos(e); |
|||
var delta = { |
|||
x: currentPos.x - this.startPos.x, |
|||
y: currentPos.y - this.startPos.y |
|||
drag(ev) { |
|||
const { opts } = this; |
|||
const { onDrag } = opts; |
|||
const { startPointer } = this; |
|||
const currentPos = this.getPointerPos(ev); |
|||
const delta = { |
|||
x: currentPos.x - startPointer.x, |
|||
y: currentPos.y - startPointer.y |
|||
}; |
|||
// Lock one axis
|
|||
if (e.shiftKey) { |
|||
if (!lockedAxis) { |
|||
var relX = delta.x; |
|||
var relY = delta.y; |
|||
var absX = Math.abs(relX); |
|||
var absY = Math.abs(relY); |
|||
let { lockedAxis } = this; |
|||
|
|||
// Vertical or Horizontal lock
|
|||
if (relY >= absX || relY <= -absX) { |
|||
lockedAxis = 'x'; |
|||
} else if (relX > absY || relX < -absY) { |
|||
lockedAxis = 'y'; |
|||
} |
|||
} |
|||
// Lock one axis
|
|||
if (ev.shiftKey) { |
|||
lockedAxis = !lockedAxis && this.detectAxisLock(delta.x, delta.y); |
|||
} else { |
|||
lockedAxis = null; |
|||
} |
|||
|
|||
if (lockedAxis === 'x') { |
|||
delta.x = this.startPos.x; |
|||
} |
|||
|
|||
if (lockedAxis === 'y') { |
|||
delta.y = this.startPos.y; |
|||
delta.x = startPointer.x; |
|||
} else if (lockedAxis === 'y') { |
|||
delta.y = startPointer.y; |
|||
} |
|||
|
|||
['x', 'y'].forEach(co => (delta[co] = delta[co] * result(opts, 'scale'))); |
|||
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 |
|||
}); |
|||
} |
|||
this.currentPointer = currentPos; |
|||
isFunction(onDrag) && onDrag(ev, this); |
|||
|
|||
// In case the mouse button was released outside of the window
|
|||
if (e.which === 0) { |
|||
this.stop(e); |
|||
} |
|||
}, |
|||
ev.which === 0 && this.stop(ev); |
|||
} |
|||
|
|||
/** |
|||
* Stop dragging |
|||
*/ |
|||
stop(ev) { |
|||
const { delta } = this; |
|||
this.toggleDrag(); |
|||
this.lockedAxis = null; |
|||
this.move(delta.x, delta.y, 1); |
|||
const { onEnd } = this.opts; |
|||
isFunction(onEnd) && onEnd(ev, this); |
|||
} |
|||
|
|||
/** |
|||
* Move the element |
|||
* @param {integer} x |
|||
* @param {integer} y |
|||
*/ |
|||
move: function(x, y) { |
|||
this.moveX(x); |
|||
this.moveY(y); |
|||
}, |
|||
move(x, y, end) { |
|||
const { el, opts } = this; |
|||
const pos = this.startPosition; |
|||
if (!pos) return; |
|||
const { setPosition } = opts; |
|||
const xPos = pos.x + x; |
|||
const yPos = pos.y + y; |
|||
this.position = { |
|||
x: xPos, |
|||
y: yPos, |
|||
end |
|||
}; |
|||
|
|||
isFunction(setPosition) && setPosition(this.position); |
|||
|
|||
if (el) { |
|||
el.style.left = `${xPos}px`; |
|||
el.style.top = `${yPos}px`; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Move in x direction |
|||
* @param {integer} x |
|||
* Returns documents |
|||
*/ |
|||
moveX(x) { |
|||
var el = this.el; |
|||
var opts = this.opts; |
|||
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'; |
|||
getDocumentEl(el) { |
|||
const { doc } = this.opts; |
|||
el = el || this.el; |
|||
|
|||
if (!this.docs) { |
|||
const docs = [document]; |
|||
el && docs.push(el.ownerDocument); |
|||
doc && docs.push(doc); |
|||
this.docs = docs; |
|||
} |
|||
}, |
|||
|
|||
return this.docs; |
|||
} |
|||
|
|||
/** |
|||
* Move in y direction |
|||
* @param {integer} y |
|||
* Get mouse coordinates |
|||
* @param {Event} event |
|||
* @return {Object} |
|||
*/ |
|||
moveY(y) { |
|||
var el = this.el; |
|||
var opts = this.opts; |
|||
var yPos = this.startTop + y; |
|||
const setY = this.opts.setY; |
|||
getPointerPos(ev) { |
|||
const getPos = this.opts.getPointerPosition; |
|||
return getPos |
|||
? getPos(ev) |
|||
: { |
|||
x: ev.clientX, |
|||
y: ev.clientY |
|||
}; |
|||
} |
|||
|
|||
if (typeof setY === 'function') { |
|||
setY(yPos, { |
|||
el, |
|||
start: this.startTop, |
|||
delta: y |
|||
}); |
|||
} else { |
|||
el.style.top = yPos + 'px'; |
|||
getStartPosition() { |
|||
const { el, opts } = this; |
|||
const getPos = opts.getPosition; |
|||
let result = { x: 0, y: 0 }; |
|||
|
|||
if (isFunction(getPos)) { |
|||
result = getPos(); |
|||
} else if (el) { |
|||
result = { |
|||
x: parseFloat(el.style.left), |
|||
y: parseFloat(el.style.top) |
|||
}; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
detectAxisLock(x, y) { |
|||
const relX = x; |
|||
const relY = y; |
|||
const absX = Math.abs(relX); |
|||
const absY = Math.abs(relY); |
|||
|
|||
// Vertical or Horizontal lock
|
|||
if (relY >= absX || relY <= -absX) { |
|||
return 'x'; |
|||
} else if (relX > absY || relX < -absY) { |
|||
return 'y'; |
|||
} |
|||
} |
|||
}; |
|||
} |
|||
|
|||
Loading…
Reference in new issue