index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import {
  2. toolOpen,
  3. whitePenShow,
  4. penShow,
  5. isPlay,
  6. isHidden
  7. } from './globalTools';
  8. import { defineComponent, onMounted, onUnmounted, ref, watch } from 'vue';
  9. import { useRoute } from 'vue-router';
  10. import styles from './index.module.less';
  11. import iconTool from './images/icon-tool.png';
  12. import iconNote from './images/icon-note.png';
  13. import iconWhiteboard from './images/icon-whiteboard.png';
  14. import gArrowRight from './images/g-arrow-right.png';
  15. import { nextTick } from 'process';
  16. import Pen from '@/tenant/music/coursewarePlay/component/tools/pen';
  17. import { useNetwork } from '@vueuse/core';
  18. import { Toast } from 'vant';
  19. export default defineComponent({
  20. name: 'globalTools',
  21. setup() {
  22. const { isOnline } = useNetwork()
  23. const isMask = ref(false); // 是否显示遮罩层,为了处理云教练里面拖动不了的问题
  24. const route = useRoute();
  25. // watch(
  26. // () => route.path,
  27. // () => {
  28. // handleStatus();
  29. // }
  30. // );
  31. const iconToolsDom = ref<HTMLDivElement>();
  32. const expendToolsDom = ref<HTMLDivElement>();
  33. function openTool() {
  34. if (isLock) return;
  35. isPlay.value = false
  36. toolOpen.value = !toolOpen.value;
  37. }
  38. function openType(type: 'note' | 'whiteboard') {
  39. if (isLock) return;
  40. console.log(isOnline.value, 'isOnline.value')
  41. if(!isOnline.value) {
  42. Toast('网络异常')
  43. return
  44. }
  45. if (type === 'note') {
  46. penShow.value = true;
  47. isHidden.value = true;
  48. } else if (type === 'whiteboard') {
  49. whitePenShow.value = true;
  50. isHidden.value = true;
  51. }
  52. }
  53. function handleStatus() {
  54. isHidden.value = route.path === '/login' ? true : false;
  55. }
  56. function computePos(type: 'width' | 'height', value: number) {
  57. const clientNum =
  58. type == 'width'
  59. ? document.documentElement.clientWidth
  60. : document.documentElement.clientHeight;
  61. console.log(value, clientNum)
  62. return {
  63. pos: ((clientNum - value) / 2).toFixed(5)
  64. };
  65. }
  66. /* 拖拽还没有兼容rem */
  67. let isLock = false;
  68. let toolMoveY = 0; // 移动的距离
  69. function drag(el: HTMLElement) {
  70. function mousedown(e: MouseEvent | TouchEvent) {
  71. const isTouchEv = isTouchEvent(e);
  72. const event = isTouchEv ? e.touches[0] : e;
  73. isLock = false;
  74. isMask.value = true;
  75. const parentElement = el;
  76. const parentElementRect = parentElement.getBoundingClientRect();
  77. const downX = event.clientX;
  78. const downY = event.clientY;
  79. // const clientWidth = document.documentElement.clientWidth
  80. const clientHeight = document.documentElement.clientHeight;
  81. // const minLeft = 0
  82. const minTop = 0;
  83. // const maxLeft = clientWidth - parentElementRect.width
  84. const maxTop = clientHeight - parentElementRect.height;
  85. function onMousemove(e: MouseEvent | TouchEvent) {
  86. const event = isTouchEvent(e) ? e.touches[0] : e;
  87. // let moveX = parentElementRect.left + (e.clientX - downX)
  88. let moveY = parentElementRect.top + (event.clientY - downY);
  89. // let moveY = e.clientY - downY
  90. // moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX
  91. moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY;
  92. toolMoveY = moveY;
  93. document.documentElement.style.setProperty(
  94. '--toolTranslateY',
  95. `${moveY}px`
  96. );
  97. // 计算移动的距离
  98. const cX = event.clientX - downX;
  99. const cY = event.clientY - downY;
  100. // 如果移动距离超过一定阈值,则认为是拖动
  101. if (Math.abs(cX) > 3 || Math.abs(cY) > 3) {
  102. isLock = true; // 设置为拖动状态
  103. }
  104. }
  105. function onMouseup() {
  106. document.removeEventListener(
  107. isTouchEv ? 'touchmove' : 'mousemove',
  108. onMousemove
  109. );
  110. document.removeEventListener(
  111. isTouchEv ? 'touchend' : 'mouseup',
  112. onMouseup
  113. );
  114. isMask.value = false;
  115. }
  116. document.addEventListener(
  117. isTouchEv ? 'touchmove' : 'mousemove',
  118. onMousemove
  119. );
  120. document.addEventListener(
  121. isTouchEv ? 'touchend' : 'mouseup',
  122. onMouseup
  123. );
  124. }
  125. el.addEventListener('mousedown', mousedown);
  126. el.addEventListener('touchstart', mousedown);
  127. }
  128. function isTouchEvent(e: MouseEvent | TouchEvent): e is TouchEvent {
  129. return window.TouchEvent && e instanceof window.TouchEvent;
  130. }
  131. //重新计算位置 居中
  132. function refreshPos() {
  133. // computePos("height", iconToolsDom.value?.clientHeight ||
  134. console.log(iconToolsDom.value?.clientHeight);
  135. const posHeight = computePos(
  136. 'height',
  137. iconToolsDom.value?.clientHeight || 0
  138. );
  139. if (iconToolsDom.value) {
  140. document.documentElement.style.setProperty(
  141. '--toolTranslateY',
  142. `${posHeight.pos}px`
  143. );
  144. }
  145. }
  146. let rect: any;
  147. function onResize() {
  148. rect = rect ? rect : iconToolsDom.value?.getBoundingClientRect();
  149. const clientHeight = document.documentElement.clientHeight;
  150. const maxTop = clientHeight - rect.height;
  151. if (toolMoveY >= maxTop) {
  152. document.documentElement.style.setProperty(
  153. '--toolTranslateY',
  154. `${maxTop}px`
  155. );
  156. }
  157. }
  158. onMounted(() => {
  159. handleStatus();
  160. drag(iconToolsDom.value!);
  161. drag(expendToolsDom.value!);
  162. nextTick(() => {
  163. refreshPos();
  164. })
  165. window.addEventListener('resize', onResize);
  166. });
  167. onUnmounted(() => {
  168. window.removeEventListener('resize', onResize);
  169. });
  170. return () => (
  171. <div>
  172. <div
  173. class={[
  174. styles.globalTools,
  175. isPlay.value ? styles.isPlay : '',
  176. isHidden.value ? styles.isHidden : ''
  177. ]}>
  178. {isMask.value && <div class={styles.mask}></div>}
  179. <div
  180. class={[[styles.iconTools, toolOpen.value ? styles.hideTools : '']]}
  181. ref={iconToolsDom}>
  182. <img onClick={openTool} src={iconTool} />
  183. </div>
  184. <div
  185. class={[styles.expendTools, toolOpen.value ? styles.showTools : '']}
  186. ref={expendToolsDom}>
  187. <img onClick={() => openType('note')} src={iconNote} />
  188. <img
  189. onClick={() => openType('whiteboard')}
  190. class={styles.iconWhiteboard}
  191. src={iconWhiteboard}
  192. />
  193. <img
  194. onClick={openTool}
  195. class={styles.iconArrow}
  196. src={gArrowRight}
  197. />
  198. </div>
  199. </div>
  200. <Pen
  201. show={penShow.value}
  202. tip="请确认是否退出批注?"
  203. close={() => {
  204. penShow.value = false;
  205. isHidden.value = false;
  206. }}
  207. />
  208. <Pen
  209. show={whitePenShow.value}
  210. isWhite
  211. tip="请确认是否退出白板?"
  212. close={() => {
  213. whitePenShow.value = false;
  214. isHidden.value = false;
  215. }}
  216. />
  217. </div>
  218. );
  219. }
  220. });