index.tsx 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. import { Transition, defineComponent, onMounted, ref } from 'vue';
  2. import LayoutSilder from './layoutSilder';
  3. import LayoutTop from './layoutTop';
  4. import styles from './index.module.less';
  5. import { NImage, NModal, NPopover } from 'naive-ui';
  6. import Moveable from 'moveable';
  7. import toolbox from './images/toolbox.png';
  8. import setTimeIcon from './images/setTimeIcon.png';
  9. import beatIcon from './images/beatIcon.png';
  10. import toneIcon from './images/toneIcon.png';
  11. import beatImage from './images/beatImage.png';
  12. import toneImage from './images/toneImage.png';
  13. import setTimeImage from './images/setTimeImage.png';
  14. import dragingBoxIcon from './images/dragingBoxIcon.png';
  15. import TimerMeter from '../timerMeter';
  16. import { useRoute } from 'vue-router';
  17. export default defineComponent({
  18. name: 'layoutView',
  19. setup() {
  20. const directionType = ref('left');
  21. const showModalBeat = ref(false);
  22. const showModalTone = ref(false);
  23. const showModalTime = ref(true);
  24. const route = useRoute();
  25. const isDragIng = ref(false);
  26. const initMoveable = async () => {
  27. if (document.querySelector('.wrap')) {
  28. const moveable = new Moveable(document.querySelector('.wrap') as any, {
  29. target: document.querySelector('#moveNPopover') as any,
  30. // If the container is null, the position is fixed. (default: parentElement(document.body))
  31. container: document.querySelector('.wrap') as any,
  32. // snappable: true,
  33. // bounds: {"left":100,"top":100,"right":100,"bottom":100},
  34. draggable: true,
  35. resizable: false,
  36. scalable: false,
  37. rotatable: false,
  38. warpable: false,
  39. pinchable: false, // ["resizable", "scalable", "rotatable"]
  40. origin: false,
  41. keepRatio: false,
  42. // Resize, Scale Events at edges.
  43. edge: false,
  44. throttleDrag: 0,
  45. throttleResize: 0,
  46. throttleScale: 0,
  47. throttleRotate: 0
  48. });
  49. moveable
  50. // .on('dragStart', ({ target, clientX, clientY }) => {
  51. // console.log('dragStart');
  52. // })
  53. .on(
  54. 'drag',
  55. ({
  56. target,
  57. // transform,
  58. left,
  59. top,
  60. right,
  61. bottom
  62. // beforeDelta,
  63. // beforeDist,
  64. // delta,
  65. // dist,
  66. // clientX,
  67. // clientY
  68. }) => {
  69. isDragIng.value = true;
  70. const subdEl = document.getElementById(
  71. `moveNPopover`
  72. ) as HTMLDivElement;
  73. // console.log(subdEl, "subdEl", "drag");
  74. const subdElStyle = getComputedStyle(subdEl, null);
  75. const RectInfo = {
  76. left: Number(subdElStyle.left.replace('px', '')),
  77. top: Number(subdElStyle.top.replace('px', '')),
  78. width: Number(subdElStyle.width.replace('px', '')),
  79. height: Number(subdElStyle.height.replace('px', ''))
  80. };
  81. const mainWidth =
  82. parseInt(
  83. window.getComputedStyle(
  84. document.querySelector('.wrap') as Element
  85. ).width
  86. ) - RectInfo.width;
  87. const mainHeight =
  88. parseInt(
  89. window.getComputedStyle(
  90. document.querySelector('.wrap') as Element
  91. ).height
  92. ) - RectInfo.height;
  93. if (left < 0) {
  94. left = 2;
  95. }
  96. if (top < 0) {
  97. top = 2;
  98. }
  99. if (right < 0) {
  100. right = 2;
  101. }
  102. if (bottom < 0) {
  103. bottom = 2;
  104. }
  105. if (left > mainWidth - 2) {
  106. left = mainWidth - 2;
  107. }
  108. if (top > mainHeight - 2) {
  109. top = mainHeight - 2;
  110. }
  111. target!.style.left = `${left}px`;
  112. target!.style.top = `${top}px`;
  113. }
  114. )
  115. .on(
  116. 'dragEnd',
  117. async ({
  118. // target, isDrag,
  119. clientX
  120. // clientY
  121. }) => {
  122. if (document.body.clientWidth / 2 - clientX > 0) {
  123. // 往左出
  124. directionType.value = 'right';
  125. } else {
  126. // 往又出
  127. directionType.value = 'left';
  128. }
  129. isDragIng.value = false;
  130. }
  131. );
  132. }
  133. };
  134. onMounted(() => {
  135. initMoveable();
  136. });
  137. const startShowModal = (val: 'setTimeIcon' | 'beatIcon' | 'toneIcon') => {
  138. if (val == 'setTimeIcon') {
  139. showModalTime.value = true;
  140. }
  141. if (val == 'beatIcon') {
  142. showModalBeat.value = true;
  143. }
  144. if (val == 'toneIcon') {
  145. showModalTone.value = true;
  146. }
  147. };
  148. return () => (
  149. <div class={[styles.wrap, 'wrap']}>
  150. <div>
  151. <LayoutSilder></LayoutSilder>
  152. </div>
  153. <div class={styles.Wrapcore}>
  154. <LayoutTop></LayoutTop>
  155. <div class={styles.WrapcoreView}>
  156. {/* <div class={styles.WrapcoreViewInfo}> */}
  157. <router-view>
  158. {(obj: any) => (
  159. <Transition name="fade-slide" mode="out-in">
  160. <obj.Component />
  161. </Transition>
  162. )}
  163. </router-view>
  164. {/* </div> */}
  165. </div>
  166. </div>
  167. <NPopover
  168. raw
  169. trigger="click"
  170. show-arrow={false}
  171. placement={directionType.value as 'left' | 'right'}
  172. v-slots={{
  173. trigger: () => (
  174. // 首页不显示工具箱
  175. <img
  176. src={isDragIng.value ? dragingBoxIcon : toolbox}
  177. id="moveNPopover"
  178. style={{
  179. display: ['/', '/home'].includes(route.path)
  180. ? 'none'
  181. : 'block'
  182. }}
  183. class={[
  184. styles.toolboxImg,
  185. 'moveNPopover',
  186. isDragIng.value ? styles.isDragIng : ''
  187. ]}
  188. alt=""
  189. />
  190. )
  191. }}>
  192. <div class={styles.booxToolWrap}>
  193. <div
  194. class={styles.booxToolItem}
  195. onClick={() => startShowModal('beatIcon')}>
  196. <img src={beatIcon} alt="" />
  197. 节拍器
  198. </div>
  199. <div
  200. class={styles.booxToolItem}
  201. onClick={() => startShowModal('toneIcon')}>
  202. <img src={toneIcon} alt="" />
  203. 调音器
  204. </div>
  205. <div
  206. class={styles.booxToolItem}
  207. onClick={() => startShowModal('setTimeIcon')}>
  208. <img src={setTimeIcon} alt="" />
  209. 计时器
  210. </div>
  211. </div>
  212. </NPopover>
  213. <NModal
  214. class={['modalTitle background']}
  215. title={'节拍器'}
  216. preset="card"
  217. v-model:show={showModalBeat.value} style={{ width: '687px' }}>
  218. <div
  219. class={styles.modeWrap}
  220. >
  221. {/* <NImage
  222. src={beatImage}
  223. previewDisabled
  224. class={styles.beatImage}></NImage> */}
  225. <iframe src="https://test.lexiaoya.cn/metronome/" scrolling='no' frameborder="0" width='100%' height={'650px'} ></iframe>
  226. </div>
  227. </NModal>
  228. <NModal v-model:show={showModalTone.value}>
  229. <div
  230. onClick={() => {
  231. showModalTone.value = false;
  232. }}>
  233. <NImage
  234. src={toneImage}
  235. previewDisabled
  236. class={styles.beatImage}></NImage>
  237. </div>
  238. </NModal>
  239. <NModal v-model:show={showModalTime.value} class={['modalTitle background']}
  240. title={'计时器'} preset="card" style={{ width: '772px' }}>
  241. <div
  242. >
  243. <TimerMeter></TimerMeter>
  244. </div>
  245. </NModal>
  246. </div>
  247. );
  248. }
  249. });