/**
* @namespace qui.utils.gestures
*/
import * as Window from '$qui/window.js'
/**
* Drag Move Callback Function.
* @callback qui.utils.gestures.DragMoveCallback
* @param {Number} elemX the new element x coordinate, relative to page
* @param {Number} elemY the new element y coordinate, relative to page
* @param {Number} deltaX the x coordinate variation, relative to initial drag point
* @param {Number} deltaY the y coordinate variation, relative to initial drag point
* @param {Number} pageX the x coordinate, relative to page
* @param {Number} pageY the y coordinate, relative to page
*/
/**
* Drag Begin Callback Function.
* @callback qui.utils.gestures.DragBeginCallback
* @param {Number} elemX the initial element x coordinate, relative to page
* @param {Number} elemY the initial element y coordinate, relative to page
* @param {Number} pageX the x coordinate, relative to page
* @param {Number} pageY the y coordinate, relative to page
* @returns {Boolean} `false` to prevent dragging
*/
/**
* Drag End Callback Function.
* @callback qui.utils.gestures.DragEndCallback
* @param {Number} elemX the final element x coordinate, relative to page
* @param {Number} elemY the final element y coordinate, relative to page
* @param {Number} deltaX the final x coordinate variation, relative to initial drag point
* @param {Number} deltaY the final y coordinate variation, relative to initial drag point
* @param {Number} pageX the x coordinate inside, relative to page
* @param {Number} pageY the y coordinate inside, relative to page
*/
/**
* Setup an HTML element for dragging.
* @alias qui.utils.gestures.enableDragging
* @param {jQuery} element the dragged element
* @param {qui.utils.gestures.DragMoveCallback} onMove
* @param {qui.utils.gestures.DragBeginCallback} onBegin
* @param {qui.utils.gestures.DragEndCallback} onEnd
* @param {?String} [direction] indicates dragging direction: `"x"`, `"y"` or `null` for both; defaults to `null`
*/
export function enableDragging(element, onMove, onBegin, onEnd, direction) {
let beginPageX = 0, beginPageY = 0
let beginElemX = 0, beginElemY = 0
function pointerDown(e) {
let elemOffset = element.offset()
beginElemX = elemOffset.left
beginElemY = elemOffset.top
let scalingFactor = Window.getScalingFactor()
e.pageX /= scalingFactor
e.pageY /= scalingFactor
beginPageX = e.pageX
beginPageY = e.pageY
if (onBegin) {
if (onBegin(beginElemX, beginElemY, e.pageX, e.pageY) === false) {
return
}
}
Window.$body.on('pointermove', pointerMove)
.on('pointerup pointercancel pointerleave', pointerUp)
}
function pointerUp(e) {
Window.$body.off('pointermove', pointerMove)
.off('pointerup pointercancel pointerleave', pointerUp)
let scalingFactor = Window.getScalingFactor()
e.pageX /= scalingFactor
e.pageY /= scalingFactor
if (direction === 'x') { /* Constrain moving to horizontal axis */
e.pageY = beginPageY
}
if (direction === 'y') { /* Constrain moving to vertical axis */
e.pageX = beginPageX
}
let deltaX = e.pageX - beginPageX
let deltaY = e.pageY - beginPageY
let elemX = beginElemX + deltaX
let elemY = beginElemY + deltaY
beginPageX = beginPageY = 0
beginElemX = beginElemY = 0
if (onEnd) {
onEnd(elemX, elemY, deltaX, deltaY, e.pageX, e.pageY)
}
}
function pointerMove(e) {
let scalingFactor = Window.getScalingFactor()
e.pageX /= scalingFactor
e.pageY /= scalingFactor
if (direction === 'x') { /* Constrain moving to horizontal axis */
e.pageY = beginPageY
}
if (direction === 'y') { /* Constrain moving to vertical axis */
e.pageX = beginPageX
}
let deltaX = e.pageX - beginPageX
let deltaY = e.pageY - beginPageY
let elemX = beginElemX + deltaX
let elemY = beginElemY + deltaY
if (onMove) {
onMove(elemX, elemY, deltaX, deltaY, e.pageX, e.pageY)
}
e.preventDefault()
}
element.data('qui.utils.gestures.dragging', {
pointerDown: pointerDown,
pointerUp: pointerUp,
pointerMove: pointerMove
})
let touchAction = 'none'
if (direction === 'x') {
touchAction = 'pan-y'
}
else if (direction === 'y') {
touchAction = 'pan-x'
}
element.css('touch-action', touchAction)
element.attr('touch-action', touchAction) /* Required for pep.js (on iOS) */
element.on('pointerdown', pointerDown)
}
/**
* Disable previously configured dragging support on an HTML element.
* @alias qui.utils.gestures.disableDragging
* @param {jQuery} element the dragged element
*/
export function disableDragging(element) {
let draggingData = element.data('qui.utils.gestures.dragging')
if (!draggingData) {
return
}
Window.$body.off('pointermove', draggingData.pointerMove)
.off('pointerup pointercancel pointerleave', draggingData.pointerUp)
element.css('touch-action', '')
element.attr('touch-action', '') /* Required for pep.js (on iOS) */
element.off('pointerdown', draggingData.pointerDown)
}