useResize.ts 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { ref } from 'vue'
  2. export const useResize = (props?: {
  3. minHeightPx?: number
  4. minWidthPx?: number
  5. initHeight?: number
  6. initWidth?: number
  7. }) => {
  8. const {
  9. minHeightPx = 400,
  10. minWidthPx = window.innerWidth / 2,
  11. initHeight = 400,
  12. initWidth = window.innerWidth / 2
  13. } = props || {}
  14. // 屏幕宽度的 50% 作为最小宽度
  15. // const minWidthPx = window.innerWidth / 2
  16. // 固定的最小高度 400px
  17. // const minHeightPx = 400
  18. // 初始高度限制为 400px
  19. const maxHeight = ref(initHeight + 'px')
  20. // 初始宽度限制为 50%
  21. const minWidth = ref(initWidth + 'px')
  22. const setupDrag = (elDialog: any, el: any) => {
  23. // 获取对话框元素
  24. // 是否正在调整大小的标志
  25. let isResizing = false
  26. // 当前调整的方向
  27. let currentResizeDirection = ''
  28. // 鼠标移动时的事件处理器,用于检测鼠标位置并设置相应的光标样式
  29. const handleMouseMove = (e: any) => {
  30. const rect = elDialog.getBoundingClientRect()
  31. // 鼠标相对于对话框左侧的偏移量
  32. const offsetX = e.clientX - rect.left
  33. // 鼠标相对于对话框顶部的偏移量
  34. const offsetY = e.clientY - rect.top
  35. const width = elDialog.clientWidth
  36. const height = elDialog.clientHeight
  37. // 获取对话框的内边距
  38. const computedStyle = window.getComputedStyle(elDialog)
  39. const paddingLeft = parseFloat(computedStyle.paddingLeft)
  40. const paddingRight = parseFloat(computedStyle.paddingRight)
  41. const paddingBottom = parseFloat(computedStyle.paddingBottom)
  42. const paddingTop = parseFloat(computedStyle.paddingTop)
  43. // 根据鼠标位置设置相应的光标样式和调整方向
  44. if (!isResizing) {
  45. if (offsetX < paddingLeft && offsetY > paddingTop && offsetY < height - paddingBottom) {
  46. elDialog.style.cursor = 'ew-resize' // 左右箭头
  47. currentResizeDirection = 'left'
  48. } else if (
  49. offsetX > width - paddingRight &&
  50. offsetY > paddingTop &&
  51. offsetY < height - paddingBottom
  52. ) {
  53. elDialog.style.cursor = 'ew-resize' // 左右箭头
  54. currentResizeDirection = 'right'
  55. } else if (
  56. offsetY < paddingTop &&
  57. offsetX > paddingLeft &&
  58. offsetX < width - paddingRight
  59. ) {
  60. elDialog.style.cursor = 'ns-resize' // 上下箭头
  61. currentResizeDirection = 'top'
  62. } else if (
  63. offsetY > height - paddingBottom &&
  64. offsetX > paddingLeft &&
  65. offsetX < width - paddingRight
  66. ) {
  67. elDialog.style.cursor = 'ns-resize' // 上下箭头
  68. currentResizeDirection = 'bottom'
  69. } else if (offsetX < paddingLeft && offsetY < paddingTop) {
  70. elDialog.style.cursor = 'nwse-resize' // 左上右下箭头
  71. currentResizeDirection = 'top-left'
  72. } else if (offsetX > width - paddingRight && offsetY < paddingTop) {
  73. elDialog.style.cursor = 'nesw-resize' // 右上左下箭头
  74. currentResizeDirection = 'top-right'
  75. } else if (offsetX < paddingLeft && offsetY > height - paddingBottom) {
  76. elDialog.style.cursor = 'nesw-resize' // 右上左下箭头
  77. currentResizeDirection = 'bottom-left'
  78. } else if (offsetX > width - paddingRight && offsetY > height - paddingBottom) {
  79. elDialog.style.cursor = 'nwse-resize' // 左上右下箭头
  80. currentResizeDirection = 'bottom-right'
  81. } else {
  82. elDialog.style.cursor = 'default'
  83. currentResizeDirection = ''
  84. }
  85. }
  86. }
  87. // 鼠标按下时的事件处理器,开始调整对话框大小
  88. const handleMouseDown = (e) => {
  89. if (currentResizeDirection) {
  90. isResizing = true
  91. const initialX = e.clientX
  92. const initialY = e.clientY
  93. const initialWidth = elDialog.clientWidth
  94. const initialHeight = el.querySelector('.el-dialog__body').clientHeight
  95. // 调整大小的事件处理器
  96. const handleResizing = (e: any) => {
  97. if (!isResizing) return
  98. let newWidth = initialWidth
  99. let newHeight = initialHeight
  100. // 根据当前调整方向计算新的宽度和高度
  101. if (currentResizeDirection.includes('right')) {
  102. newWidth = Math.max(minWidthPx, initialWidth + (e.clientX - initialX) * 2)
  103. minWidth.value = `${newWidth}px`
  104. }
  105. if (currentResizeDirection.includes('left')) {
  106. newWidth = Math.max(minWidthPx, initialWidth - (e.clientX - initialX) * 2)
  107. minWidth.value = `${newWidth}px`
  108. }
  109. if (currentResizeDirection.includes('bottom')) {
  110. newHeight = Math.max(minHeightPx, initialHeight + (e.clientY - initialY) * 2 - 20)
  111. maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
  112. }
  113. if (currentResizeDirection.includes('top')) {
  114. newHeight = Math.max(minHeightPx, initialHeight - (e.clientY - initialY) * 2 - 20)
  115. maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
  116. }
  117. if (currentResizeDirection === 'top-left') {
  118. newWidth = Math.max(minWidthPx, initialWidth - (e.clientX - initialX) * 2)
  119. minWidth.value = `${newWidth}px`
  120. newHeight = Math.max(minHeightPx, initialHeight - (e.clientY - initialY) * 2 - 20)
  121. maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
  122. }
  123. if (currentResizeDirection === 'top-right') {
  124. newWidth = Math.max(minWidthPx, initialWidth + (e.clientX - initialX) * 2)
  125. minWidth.value = `${newWidth}px`
  126. newHeight = Math.max(minHeightPx, initialHeight - (e.clientY - initialY) * 2 - 20)
  127. maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
  128. }
  129. if (currentResizeDirection === 'bottom-left') {
  130. newWidth = Math.max(minWidthPx, initialWidth - (e.clientX - initialX) * 2)
  131. minWidth.value = `${newWidth}px`
  132. newHeight = Math.max(minHeightPx, initialHeight + (e.clientY - initialY) * 2 - 20)
  133. maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
  134. }
  135. if (currentResizeDirection === 'bottom-right') {
  136. newWidth = Math.max(minWidthPx, initialWidth + (e.clientX - initialX) * 2)
  137. minWidth.value = `${newWidth}px`
  138. newHeight = Math.max(minHeightPx, initialHeight + (e.clientY - initialY) * 2 - 20)
  139. maxHeight.value = `${Math.min(newHeight, window.innerHeight - 165)}px`
  140. }
  141. }
  142. // 停止调整大小的事件处理器
  143. const stopResizing = () => {
  144. isResizing = false
  145. document.removeEventListener('mousemove', handleResizing)
  146. document.removeEventListener('mouseup', stopResizing)
  147. }
  148. document.addEventListener('mousemove', handleResizing)
  149. document.addEventListener('mouseup', stopResizing)
  150. }
  151. }
  152. elDialog.addEventListener('mousemove', handleMouseMove)
  153. elDialog.addEventListener('mousedown', handleMouseDown)
  154. }
  155. return {
  156. setupDrag,
  157. maxHeight,
  158. minWidth
  159. }
  160. }