use-draggable.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { onBeforeUnmount, onMounted, watchEffect } from 'vue-demi'
  2. export const useDraggable = (targetRef, dragRef,draggable) => {
  3. let transform = {
  4. offsetX: 0,
  5. offsetY: 0,
  6. }
  7. const onMousedown = (e) => {
  8. const downX = e.clientX
  9. const downY = e.clientY
  10. const { offsetX, offsetY } = transform
  11. const targetRect = targetRef.value.getBoundingClientRect()
  12. const targetLeft = targetRect.left
  13. const targetTop = targetRect.top
  14. const targetWidth = targetRect.width
  15. const targetHeight = targetRect.height
  16. const clientWidth = document.documentElement.clientWidth
  17. const clientHeight = document.documentElement.clientHeight
  18. const minLeft = -targetLeft + offsetX
  19. const minTop = -targetTop + offsetY
  20. const maxLeft = clientWidth - targetLeft - targetWidth + offsetX
  21. const maxTop = clientHeight - targetTop - targetHeight + offsetY
  22. const onMousemove = (e) => {
  23. const moveX = Math.min(
  24. Math.max(offsetX + e.clientX - downX, minLeft),
  25. maxLeft
  26. )
  27. const moveY = Math.min(
  28. Math.max(offsetY + e.clientY - downY, minTop),
  29. maxTop
  30. )
  31. transform = {
  32. offsetX: moveX,
  33. offsetY: moveY,
  34. }
  35. targetRef.value.style.transform = `translate(${moveX}px, ${moveY}px)`
  36. }
  37. const onMouseup = () => {
  38. document.removeEventListener('mousemove', onMousemove)
  39. document.removeEventListener('mouseup', onMouseup)
  40. }
  41. document.addEventListener('mousemove', onMousemove)
  42. document.addEventListener('mouseup', onMouseup)
  43. }
  44. const onDraggable = () => {
  45. if (dragRef.value && targetRef.value) {
  46. dragRef.value.addEventListener('mousedown', onMousedown)
  47. }
  48. }
  49. const offDraggable = () => {
  50. if (dragRef.value && targetRef.value) {
  51. dragRef.value.removeEventListener('mousedown', onMousedown)
  52. }
  53. }
  54. onMounted(() => {
  55. watchEffect(() => {
  56. if (draggable.value) {
  57. onDraggable()
  58. } else {
  59. offDraggable()
  60. }
  61. })
  62. })
  63. onBeforeUnmount(() => {
  64. offDraggable()
  65. })
  66. }