drag_component.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <div class="fixed-box">
  3. <div class="content-bottom">
  4. <div
  5. class="draw draggable"
  6. ref="draggableRef"
  7. :style="{ top: position.y - 360 + 'px', left: position.x + 'px' }"
  8. >
  9. <img src="@/assets/images/wakeup/float-box.png" />
  10. </div>
  11. <div class="ai-rabit">
  12. <img src="@/assets/images/wakeup/ai-rabit.png" />
  13. </div>
  14. </div>
  15. </div>
  16. </template>
  17. <script setup>
  18. import { ref, onMounted, onUnmounted } from "vue";
  19. const draggableRef = ref(null);
  20. const position = ref({ x: 0, y: 0 });
  21. const dragging = ref(false);
  22. const startX = ref(0);
  23. const startY = ref(0);
  24. const onMouseDown = (event) => {
  25. dragging.value = true;
  26. startX.value = event.clientX - position.value.x;
  27. startY.value = event.clientY - position.value.y;
  28. document.addEventListener("mousemove", onMouseMove);
  29. document.addEventListener("mouseup", onMouseUp);
  30. };
  31. const onTouchStart = (event) => {
  32. if (event.touches.length === 1) {
  33. dragging.value = true;
  34. startX.value = event.touches[0].clientX - position.value.x;
  35. startY.value = event.touches[0].clientY - position.value.y;
  36. document.addEventListener("touchmove", onTouchMove, { passive: true });
  37. document.addEventListener("touchend", onTouchEnd, { passive: true });
  38. }
  39. };
  40. const onMouseMove = (event) => {
  41. if (dragging.value) {
  42. position.value.x = event.clientX - startX.value;
  43. position.value.y = event.clientY - startY.value;
  44. }
  45. };
  46. const onTouchMove = (event) => {
  47. if (dragging.value && event.touches.length === 1) {
  48. position.value.x = event.touches[0].clientX - startX.value;
  49. position.value.y = event.touches[0].clientY - startY.value;
  50. }
  51. };
  52. const onMouseUp = () => {
  53. dragging.value = false;
  54. document.removeEventListener("mousemove", onMouseMove);
  55. document.removeEventListener("mouseup", onMouseUp);
  56. };
  57. const onTouchEnd = () => {
  58. dragging.value = false;
  59. document.removeEventListener("touchmove", onTouchMove);
  60. document.removeEventListener("touchend", onTouchEnd);
  61. };
  62. onMounted(() => {
  63. const draggable = draggableRef.value;
  64. draggable.addEventListener("mousedown", onMouseDown);
  65. draggable.addEventListener("touchstart", onTouchStart, { passive: true });
  66. });
  67. onUnmounted(() => {
  68. const draggable = draggableRef.value;
  69. if (draggable) {
  70. draggable.removeEventListener("mousedown", onMouseDown);
  71. draggable.removeEventListener("touchstart", onTouchStart);
  72. }
  73. document.removeEventListener("mousemove", onMouseMove);
  74. document.removeEventListener("mouseup", onMouseUp);
  75. document.removeEventListener("touchmove", onTouchMove);
  76. document.removeEventListener("touchend", onTouchEnd);
  77. });
  78. </script>
  79. <style scoped lang="scss">
  80. .draggable {
  81. width: 100px;
  82. height: 100px;
  83. display: flex;
  84. align-items: center;
  85. justify-content: center;
  86. position: absolute;
  87. cursor: pointer;
  88. user-select: none;
  89. }
  90. .fixed-box {
  91. position: fixed;
  92. bottom: 0;
  93. left: 0;
  94. width: 100%;
  95. height: auto;
  96. pointer-events: none; /* 让背景不阻挡其他元素的点击 */
  97. z-index: 9999; /* 确保在最上层显示 */
  98. }
  99. .content-bottom {
  100. width: 100%;
  101. height: 0px; /* 给容器一个明确的高度 */
  102. display: flex;
  103. justify-content: space-between;
  104. position: relative;
  105. align-items: flex-end;
  106. pointer-events: auto; /* 恢复子元素的点击事件 */
  107. .draw {
  108. width: 109px;
  109. height: 170px;
  110. pointer-events: auto;
  111. position: absolute;
  112. img {
  113. width: 109px;
  114. height: 170px;
  115. }
  116. }
  117. .ai-rabit {
  118. position: absolute;
  119. right: 0px;
  120. bottom: 0px;
  121. display: flex;
  122. align-items: flex-end;
  123. pointer-events: auto;
  124. .ai-rabit-text {
  125. width: 345px;
  126. height: 89px;
  127. background: #e8eef7;
  128. font-weight: 300;
  129. margin-bottom: 20px;
  130. font-size: 22px;
  131. color: #000000;
  132. padding: 16px;
  133. border-radius: 24px 24px 24px 24px;
  134. }
  135. img {
  136. width: 178px;
  137. height: 270px;
  138. }
  139. }
  140. }
  141. </style>