useDragBox.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // WIP
  2. import { ref, onUnmounted } from "vue";
  3. export default () => {
  4. const dragBox = ref({
  5. top: 0,
  6. left: 0,
  7. pos1: 0,
  8. pos2: 0,
  9. pos3: 0,
  10. pos4: 0,
  11. width: 400,
  12. height: 50,
  13. initial: {
  14. top: 0,
  15. left: 0
  16. },
  17. latest: {
  18. top: null,
  19. left: null
  20. },
  21. debounceTimeout: null,
  22. lastTappedDate: 0
  23. });
  24. const onDragBoxUpdate = ref();
  25. const setInitialBox = (initial, reset) => {
  26. dragBox.value.initial = initial || dragBox.value.initial;
  27. if (reset)
  28. dragBox.value = { ...dragBox.value, ...dragBox.value.initial };
  29. };
  30. const resetBoxPosition = preventUpdate => {
  31. setInitialBox(null, true);
  32. dragBox.value.latest.top = dragBox.value.top;
  33. dragBox.value.latest.left = dragBox.value.left;
  34. if (!preventUpdate && typeof onDragBoxUpdate.value === "function")
  35. onDragBoxUpdate.value();
  36. };
  37. const onDragBox = e => {
  38. const e1 = e || window.event;
  39. const e1IsTouch = e1.type === "touchstart";
  40. e1.preventDefault();
  41. if (e1IsTouch) {
  42. // Handle double click from touch (if this method is twice in a row within one second)
  43. if (Date.now() - dragBox.value.lastTappedDate <= 1000) {
  44. resetBoxPosition();
  45. dragBox.value.lastTappedDate = 0;
  46. return;
  47. }
  48. dragBox.value.lastTappedDate = Date.now();
  49. }
  50. dragBox.value.pos3 = e1IsTouch
  51. ? e1.changedTouches[0].clientX
  52. : e1.clientX;
  53. dragBox.value.pos4 = e1IsTouch
  54. ? e1.changedTouches[0].clientY
  55. : e1.clientY;
  56. document.onmousemove = document.ontouchmove = e => {
  57. const e2 = e || window.event;
  58. const e2IsTouch = e2.type === "touchmove";
  59. if (!e2IsTouch) e2.preventDefault();
  60. // Get the clientX and clientY
  61. const e2ClientX = e2IsTouch
  62. ? e2.changedTouches[0].clientX
  63. : e2.clientX;
  64. const e2ClientY = e2IsTouch
  65. ? e2.changedTouches[0].clientY
  66. : e2.clientY;
  67. // calculate the new cursor position:
  68. dragBox.value.pos1 = dragBox.value.pos3 - e2ClientX;
  69. dragBox.value.pos2 = dragBox.value.pos4 - e2ClientY;
  70. dragBox.value.pos3 = e2ClientX;
  71. dragBox.value.pos4 = e2ClientY;
  72. // set the element's new position:
  73. dragBox.value.top -= dragBox.value.pos2;
  74. dragBox.value.left -= dragBox.value.pos1;
  75. if (
  76. dragBox.value.top >
  77. document.body.clientHeight - dragBox.value.height
  78. )
  79. dragBox.value.top =
  80. document.body.clientHeight - dragBox.value.height;
  81. if (dragBox.value.top < 0) dragBox.value.top = 0;
  82. if (
  83. dragBox.value.left >
  84. document.body.clientWidth - dragBox.value.width
  85. )
  86. dragBox.value.left =
  87. document.body.clientWidth - dragBox.value.width;
  88. if (dragBox.value.left < 0) dragBox.value.left = 0;
  89. };
  90. document.onmouseup = document.ontouchend = () => {
  91. document.onmouseup = null;
  92. document.ontouchend = null;
  93. document.onmousemove = null;
  94. document.ontouchmove = null;
  95. if (typeof onDragBoxUpdate.value === "function")
  96. onDragBoxUpdate.value();
  97. };
  98. };
  99. const onWindowResizeDragBox = () => {
  100. if (dragBox.value.debounceTimeout)
  101. clearTimeout(dragBox.value.debounceTimeout);
  102. dragBox.value.debounceTimeout = setTimeout(() => {
  103. if (
  104. dragBox.value.top === dragBox.value.latest.top &&
  105. dragBox.value.left === dragBox.value.latest.left
  106. )
  107. resetBoxPosition();
  108. else {
  109. if (
  110. dragBox.value.top >
  111. document.body.clientHeight - dragBox.value.height
  112. )
  113. dragBox.value.top =
  114. document.body.clientHeight - dragBox.value.height;
  115. if (dragBox.value.top < 0) dragBox.value.top = 0;
  116. if (
  117. dragBox.value.left >
  118. document.body.clientWidth - dragBox.value.width
  119. )
  120. dragBox.value.left =
  121. document.body.clientWidth - dragBox.value.width;
  122. if (dragBox.value.left < 0) dragBox.value.left = 0;
  123. if (typeof onDragBoxUpdate.value === "function")
  124. onDragBoxUpdate.value();
  125. }
  126. }, 50);
  127. };
  128. resetBoxPosition(true);
  129. onWindowResizeDragBox();
  130. window.addEventListener("resize", onWindowResizeDragBox);
  131. onUnmounted(() => {
  132. window.removeEventListener("resize", onWindowResizeDragBox);
  133. if (dragBox.value.debounceTimeout)
  134. clearTimeout(dragBox.value.debounceTimeout);
  135. });
  136. return {
  137. dragBox,
  138. setInitialBox,
  139. onDragBox,
  140. resetBoxPosition,
  141. onWindowResizeDragBox,
  142. onDragBoxUpdate
  143. };
  144. };