index.tsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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 { useNetwork } from '@vueuse/core';
  17. import { showToast } from 'vant';
  18. import Pen from '@/views/coursewarePlay/component/tools/pen';
  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. showToast('网络异常')
  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. return {
  62. pos: ((clientNum - value) / 2).toFixed(5)
  63. };
  64. }
  65. /* 拖拽还没有兼容rem */
  66. let isLock = false;
  67. let toolMoveY = 0; // 移动的距离
  68. function drag(el: HTMLElement) {
  69. function mousedown(e: MouseEvent | TouchEvent) {
  70. const isTouchEv = isTouchEvent(e);
  71. const event = isTouchEv ? e.touches[0] : e;
  72. isLock = false;
  73. isMask.value = true;
  74. const parentElement = el;
  75. const parentElementRect = parentElement.getBoundingClientRect();
  76. const downX = event.clientX;
  77. const downY = event.clientY;
  78. // const clientWidth = document.documentElement.clientWidth
  79. const clientHeight = document.documentElement.clientHeight;
  80. // const minLeft = 0
  81. const minTop = 0;
  82. // const maxLeft = clientWidth - parentElementRect.width
  83. const maxTop = clientHeight - parentElementRect.height;
  84. function onMousemove(e: MouseEvent | TouchEvent) {
  85. const event = isTouchEvent(e) ? e.touches[0] : e;
  86. // let moveX = parentElementRect.left + (e.clientX - downX)
  87. let moveY = parentElementRect.top + (event.clientY - downY);
  88. // let moveY = e.clientY - downY
  89. // moveX = moveX < minLeft ? minLeft : moveX > maxLeft ? maxLeft : moveX
  90. moveY = moveY < minTop ? minTop : moveY > maxTop ? maxTop : moveY;
  91. toolMoveY = moveY;
  92. document.documentElement.style.setProperty(
  93. '--toolTranslateY',
  94. `${moveY}px`
  95. );
  96. // 计算移动的距离
  97. const cX = event.clientX - downX;
  98. const cY = event.clientY - downY;
  99. // 如果移动距离超过一定阈值,则认为是拖动
  100. if (Math.abs(cX) > 3 || Math.abs(cY) > 3) {
  101. isLock = true; // 设置为拖动状态
  102. }
  103. }
  104. function onMouseup() {
  105. document.removeEventListener(
  106. isTouchEv ? 'touchmove' : 'mousemove',
  107. onMousemove
  108. );
  109. document.removeEventListener(
  110. isTouchEv ? 'touchend' : 'mouseup',
  111. onMouseup
  112. );
  113. isMask.value = false;
  114. }
  115. document.addEventListener(
  116. isTouchEv ? 'touchmove' : 'mousemove',
  117. onMousemove
  118. );
  119. document.addEventListener(
  120. isTouchEv ? 'touchend' : 'mouseup',
  121. onMouseup
  122. );
  123. }
  124. el.addEventListener('mousedown', mousedown);
  125. el.addEventListener('touchstart', mousedown);
  126. }
  127. function isTouchEvent(e: MouseEvent | TouchEvent): e is TouchEvent {
  128. return window.TouchEvent && e instanceof window.TouchEvent;
  129. }
  130. //重新计算位置 居中
  131. function refreshPos() {
  132. // computePos("height", iconToolsDom.value?.clientHeight ||
  133. // console.log(iconToolsDom.value?.clientHeight);
  134. const posHeight = computePos(
  135. 'height',
  136. iconToolsDom.value?.clientHeight || 0
  137. );
  138. if (iconToolsDom.value) {
  139. document.documentElement.style.setProperty(
  140. '--toolTranslateY',
  141. `${posHeight.pos}px`
  142. );
  143. }
  144. }
  145. let rect: any;
  146. function onResize() {
  147. rect = rect ? rect : iconToolsDom.value?.getBoundingClientRect();
  148. const clientHeight = document.documentElement.clientHeight;
  149. const maxTop = clientHeight - rect.height;
  150. if (toolMoveY >= maxTop) {
  151. document.documentElement.style.setProperty(
  152. '--toolTranslateY',
  153. `${maxTop}px`
  154. );
  155. }
  156. }
  157. onMounted(() => {
  158. handleStatus();
  159. drag(iconToolsDom.value!);
  160. drag(expendToolsDom.value!);
  161. nextTick(() => {
  162. refreshPos();
  163. })
  164. window.addEventListener('resize', onResize);
  165. });
  166. onUnmounted(() => {
  167. window.removeEventListener('resize', onResize);
  168. });
  169. return () => (
  170. <div>
  171. <div
  172. class={[
  173. styles.globalTools,
  174. isPlay.value ? styles.isPlay : '',
  175. isHidden.value ? styles.isHidden : ''
  176. ]}>
  177. {isMask.value && <div class={styles.mask}></div>}
  178. <div
  179. class={[[styles.iconTools, toolOpen.value ? styles.hideTools : '']]}
  180. ref={iconToolsDom}>
  181. <img onClick={openTool} src={iconTool} />
  182. </div>
  183. <div
  184. class={[styles.expendTools, toolOpen.value ? styles.showTools : '']}
  185. ref={expendToolsDom}>
  186. <img onClick={() => openType('note')} src={iconNote} />
  187. <img
  188. onClick={() => openType('whiteboard')}
  189. class={styles.iconWhiteboard}
  190. src={iconWhiteboard}
  191. />
  192. <img
  193. onClick={openTool}
  194. class={styles.iconArrow}
  195. src={gArrowRight}
  196. />
  197. </div>
  198. </div>
  199. <Pen
  200. show={penShow.value}
  201. tip="请确认是否退出批注?"
  202. close={() => {
  203. penShow.value = false;
  204. isHidden.value = false;
  205. }}
  206. />
  207. <Pen
  208. show={whitePenShow.value}
  209. isWhite
  210. tip="请确认是否退出白板?"
  211. close={() => {
  212. whitePenShow.value = false;
  213. isHidden.value = false;
  214. }}
  215. />
  216. </div>
  217. );
  218. }
  219. });