moveable.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { ObjectDirective } from 'vue';
  2. export const bindMoveTool = (el: HTMLElement, binding) => {
  3. const initScale = binding.value ? binding.value : 1;
  4. const targetkey = binding.arg ? Number(binding.arg) : 0;
  5. const transInfo = {
  6. zoom: initScale,
  7. toMove: false,
  8. toScale: false,
  9. transOriginX: 50,
  10. transOriginY: 50,
  11. translateX: 0,
  12. translateY: 0,
  13. distance: 1,
  14. mouseInit: { x: 0, y: 0 },
  15. curMousePos: { x: 0, y: 0 },
  16. };
  17. const setBgStyle = () => {
  18. el.setAttribute(
  19. 'style',
  20. `transform-origin: ${transInfo.transOriginX}% ${transInfo.transOriginY}%; transform: translate(${transInfo.translateX}px, ${transInfo.translateY}px) scale(${transInfo.zoom})`,
  21. );
  22. };
  23. const calcTransOrigin = (mouseX: number, mouseY: number) => {
  24. const mapBgInfo = el.getBoundingClientRect();
  25. if (transInfo.zoom !== initScale) {
  26. transInfo.translateX += (1 - 1 / transInfo.zoom) * (mouseX - transInfo.mouseInit.x);
  27. transInfo.translateY += (1 - 1 / transInfo.zoom) * (mouseY - transInfo.mouseInit.y);
  28. }
  29. transInfo.transOriginX = ((mouseX - mapBgInfo!.left!) / mapBgInfo!.width!) * 100;
  30. transInfo.transOriginY = ((mouseY - mapBgInfo!.top!) / mapBgInfo!.height!) * 100;
  31. transInfo.mouseInit = { x: mouseX, y: mouseY };
  32. };
  33. const handleScale = (e) => {
  34. if (e.ctrlKey) {
  35. e.preventDefault();
  36. calcTransOrigin(e.clientX, e.clientY);
  37. if (e.wheelDelta > 0) {
  38. const newZoom = transInfo.zoom + 0.2;
  39. transInfo.zoom = newZoom > 10 ? 10 : newZoom;
  40. } else if (e.wheelDelta < 0) {
  41. const newZoom = transInfo.zoom - 0.2;
  42. transInfo.zoom = newZoom < 0.2 ? 0.2 : newZoom;
  43. }
  44. setBgStyle();
  45. }
  46. };
  47. const handleMouseDown = (e) => {
  48. if (e.button === targetkey) {
  49. transInfo.toMove = true;
  50. transInfo.curMousePos = { x: e.clientX, y: e.clientY };
  51. }
  52. };
  53. const handleMouseMove = (e) => {
  54. if (transInfo.toMove) {
  55. transInfo.translateX += e.clientX - transInfo.curMousePos.x;
  56. transInfo.translateY += e.clientY - transInfo.curMousePos.y;
  57. transInfo.mouseInit = {
  58. x: transInfo.mouseInit.x + (e.clientX - transInfo.curMousePos.x),
  59. y: transInfo.mouseInit.y + (e.clientY - transInfo.curMousePos.y),
  60. };
  61. }
  62. transInfo.curMousePos = { x: e.clientX, y: e.clientY };
  63. setBgStyle();
  64. };
  65. const handleMouseUp = () => {
  66. transInfo.toMove = false;
  67. transInfo.curMousePos = { x: 0, y: 0 };
  68. };
  69. // const calcMobileTransOrigin = (mouseX: number, mouseY: number) => {
  70. // const mapBgInfo = el.getBoundingClientRect();
  71. // if (transInfo.zoom !== initScale) {
  72. // transInfo.translateX += (1 - 1 / transInfo.zoom) * (mouseX - transInfo.mouseInit.x);
  73. // transInfo.translateY += (1 - 1 / transInfo.zoom) * (mouseY - transInfo.mouseInit.y);
  74. // }
  75. // transInfo.transOriginX = ((mouseX - mapBgInfo!.top!) / mapBgInfo!.height!) * 100;
  76. // transInfo.transOriginY = (1 - (mouseY - mapBgInfo!.left!) / mapBgInfo!.width!) * 100;
  77. // transInfo.mouseInit = { x: mouseX, y: mouseY };
  78. // };
  79. // const handleTouchStart = (e) => {
  80. // const touches = e.touches;
  81. // if (touches.length == 1) {
  82. // transInfo.toMove = true;
  83. // transInfo.toScale = false;
  84. // transInfo.curMousePos = { x: touches[0].pageY, y: touches[0].pageX };
  85. // } else if (touches.length == 2) {
  86. // transInfo.toMove = false;
  87. // transInfo.toScale = true;
  88. // // 计算中点
  89. // const midX = (touches[0].pageY + touches[1].pageY) / 2;
  90. // const midY = (touches[0].pageX + touches[1].pageX) / 2;
  91. // calcMobileTransOrigin(midX, midY);
  92. // // 计算距离
  93. // const disX = Math.abs(touches[0].pageY - touches[1].pageY);
  94. // const disY = Math.abs(touches[0].pageX - touches[1].pageX);
  95. // transInfo.distance = Math.sqrt(disX * disX + disY * disY);
  96. // }
  97. // };
  98. // const handleTouchMove = (e) => {
  99. // const touches = e.touches;
  100. // if (touches.length == 1 && transInfo.toMove) {
  101. // transInfo.toMove = true;
  102. // transInfo.toScale = false;
  103. // transInfo.translateX += touches[0].pageY - transInfo.curMousePos.x;
  104. // transInfo.translateY -= touches[0].pageX - transInfo.curMousePos.y;
  105. // transInfo.mouseInit = {
  106. // x: transInfo.mouseInit.x + (touches[0].pageY - transInfo.curMousePos.x),
  107. // y: transInfo.mouseInit.y - (touches[0].pageX - transInfo.curMousePos.y),
  108. // };
  109. // transInfo.curMousePos = { x: touches[0].pageY, y: touches[0].pageX };
  110. // setBgStyle();
  111. // } else if (touches.length == 2 && transInfo.toScale) {
  112. // e.preventDefault();
  113. // transInfo.toMove = false;
  114. // transInfo.toScale = true;
  115. // // 计算距离
  116. // const disX = Math.abs(touches[0].pageY - touches[1].pageY);
  117. // const disY = Math.abs(touches[0].pageX - touches[1].pageX);
  118. // const curDistance = Math.sqrt(disX * disX + disY * disY);
  119. // transInfo.zoom = transInfo.zoom * (curDistance / transInfo.distance);
  120. // setBgStyle();
  121. // transInfo.distance = curDistance;
  122. // }
  123. // };
  124. // const handleTouchEnd = () => {
  125. // transInfo.toMove = false;
  126. // transInfo.toScale = false;
  127. // transInfo.distance = 1;
  128. // transInfo.curMousePos = { x: 0, y: 0 };
  129. // };
  130. setBgStyle();
  131. el.addEventListener('mousewheel', handleScale);
  132. el.addEventListener('mousedown', handleMouseDown);
  133. el.addEventListener('mousemove', handleMouseMove);
  134. el.addEventListener('mouseup', handleMouseUp);
  135. };
  136. export const moveable: ObjectDirective = {
  137. mounted(el: HTMLElement, binding) {
  138. bindMoveTool(el, binding);
  139. },
  140. };