dragmove.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // https://github.com/knadh/dragmove.js
  2. // Kailash Nadh (c) 2020.
  3. // MIT License.
  4. let _loaded = false
  5. const _callbacks = []
  6. const _isTouch = window.ontouchstart !== undefined
  7. export const dragmove = function(target, handler, onStart, onEnd) {
  8. // Register a global event to capture mouse moves (once).
  9. if (!_loaded) {
  10. document.addEventListener(_isTouch ? 'touchmove' : 'mousemove', function(e) {
  11. let c = e
  12. if (e.touches) {
  13. c = e.touches[0]
  14. }
  15. // On mouse move, dispatch the coords to all registered callbacks.
  16. for (var i = 0; i < _callbacks.length; i++) {
  17. _callbacks[i](c.clientX, c.clientY)
  18. }
  19. })
  20. }
  21. _loaded = true
  22. let isMoving = false
  23. let hasStarted = false
  24. let startX = 0
  25. let startY = 0
  26. let lastX = 0
  27. let lastY = 0
  28. // On the first click and hold, record the offset of the pointer in relation
  29. // to the point of click inside the element.
  30. handler.addEventListener(_isTouch ? 'touchstart' : 'mousedown', function(e) {
  31. e.stopPropagation()
  32. e.preventDefault()
  33. if (target.dataset.dragEnabled === 'false') {
  34. return
  35. }
  36. let c = e
  37. if (e.touches) {
  38. c = e.touches[0]
  39. }
  40. isMoving = true
  41. startX = target.offsetLeft - c.clientX
  42. startY = target.offsetTop - c.clientY
  43. })
  44. // On leaving click, stop moving.
  45. document.addEventListener(_isTouch ? 'touchend' : 'mouseup', function(e) {
  46. if (onEnd && hasStarted) {
  47. onEnd(target, parseInt(target.style.left), parseInt(target.style.top))
  48. }
  49. isMoving = false
  50. hasStarted = false
  51. })
  52. // Register mouse-move callback to move the element.
  53. _callbacks.push(function move(x, y) {
  54. if (!isMoving) {
  55. return
  56. }
  57. if (!hasStarted) {
  58. hasStarted = true
  59. if (onStart) {
  60. onStart(target, lastX, lastY)
  61. }
  62. }
  63. lastX = x + startX
  64. lastY = y + startY
  65. // If boundary checking is on, don't let the element cross the viewport.
  66. if (target.dataset.dragBoundary === 'true') {
  67. lastX = Math.min(window.innerWidth - target.offsetWidth, Math.max(0, lastX))
  68. lastY = Math.min(window.innerHeight - target.offsetHeight, Math.max(0, lastY))
  69. }
  70. target.style.left = lastX + 'px'
  71. target.style.top = lastY + 'px'
  72. })
  73. }
  74. export { dragmove as default }