123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696 |
- import { Transition, defineComponent, onMounted, ref, reactive,onUnmounted } from 'vue';
- import LayoutSilder from './layoutSilder';
- import LayoutTop from './layoutTop';
- import styles from './index.module.less';
- import { NButton, NImage, NModal, NPopover, NSpace, useDialog } from 'naive-ui';
- import Moveable from 'moveable';
- import toolStartClass from './images/toolStartClass.png';
- import toolbox from './images/toolbox.png';
- import setTimeIcon from './images/setTimeIcon.png';
- import beatIcon from './images/beatIcon.png';
- import toneIcon from './images/toneIcon.png';
- import beatImage from './images/beatImage.png';
- import toneImage from './images/toneImage.png';
- import setTimeImage from './images/setTimeImage.png';
- import dragingBoxIcon from './images/dragingBoxIcon.png';
- import TimerMeter from '../timerMeter';
- import { useRoute, useRouter } from 'vue-router';
- import { vaildUrl } from '/src/utils/urlUtils';
- import ChioseModal from '/src/views/home/modals/chioseModal';
- import { px2vw, px2vwH } from '@/utils/index';
- import PlaceholderTone from './modals/placeholderTone';
- import { state } from '/src/state';
- import PreviewWindow from '/src/views/preview-window';
- import {fscreen} from '@/utils/index'
- export default defineComponent({
- name: 'layoutView',
- setup() {
- const router = useRouter();
- const previewModal = ref(false);
- const previewItem = ref({});
- const directionType = ref('left');
- const showClass = ref(false);
- const showModalBeat = ref(false);
- const showModalTone = ref(false);
- const showModalTime = ref(false);
- const showBoxConent = ref(false);
- const dialog = useDialog();
- const boxBoundaryInfo = reactive({
- isBoundary: true,
- isBoundaryType: 'right' as any,
- mainWidth: '' as any,
- mainHeight: '' as any,
- subWidth: '' as any,
- subHeight: '' as any
- });
- const classBoundaryInfo = reactive({
- isBoundary: true,
- isBoundaryType: 'right' as any,
- mainWidth: '' as any,
- mainHeight: '' as any,
- subWidth: '' as any,
- subHeight: '' as any
- });
- const route = useRoute();
- const isDragIng = ref(false);
- const NPopoverRef = ref()
- const initMoveable = async () => {
- if (document.querySelector('.wrap')) {
- const moveable = new Moveable(document.querySelector('.wrap') as any, {
- target: document.querySelector('#moveNPopover') as any,
- // If the container is null, the position is fixed. (default: parentElement(document.body))
- container: document.querySelector('.wrap') as any,
- // snappable: true,
- // bounds: {"left":100,"top":100,"right":100,"bottom":100},
- draggable: true,
- resizable: false,
- scalable: false,
- rotatable: false,
- warpable: false,
- pinchable: false, // ["resizable", "scalable", "rotatable"]
- origin: false,
- keepRatio: false,
- // Resize, Scale Events at edges.
- edge: false,
- throttleDrag: 0,
- throttleResize: 0,
- throttleScale: 0,
- throttleRotate: 0
- });
- moveable
- // .on('dragStart', ({ target, clientX, clientY }) => {
- // console.log('dragStart');
- // })
- .on(
- 'drag',
- ({
- target,
- // transform,
- left,
- top,
- right,
- bottom
- // beforeDelta,
- // beforeDist,
- // delta,
- // dist,
- // clientX,
- // clientY
- }) => {
- isDragIng.value = true;
- NPopoverRef.value.setShow(false)
- const subdEl = document.getElementById(
- `moveNPopover`
- ) as HTMLDivElement;
- // console.log(subdEl, "subdEl", "drag");
- const subdElStyle = getComputedStyle(subdEl, null);
- const RectInfo = {
- left: Number(subdElStyle.left.replace('px', '')),
- top: Number(subdElStyle.top.replace('px', '')),
- width: Number(subdElStyle.width.replace('px', '')),
- height: Number(subdElStyle.height.replace('px', ''))
- };
- // target.style.transition = ''
- const mainWidth =
- parseInt(
- window.getComputedStyle(
- document.querySelector('.wrap') as Element
- ).width
- ) - RectInfo.width;
- const mainHeight =
- parseInt(
- window.getComputedStyle(
- document.querySelector('.wrap') as Element
- ).height
- ) - RectInfo.height;
- subdEl.style.transition = '';
- boxBoundaryInfo.isBoundary = false;
- boxBoundaryInfo.isBoundaryType = '';
- boxBoundaryInfo.mainHeight = mainHeight;
- boxBoundaryInfo.mainWidth = mainWidth;
- boxBoundaryInfo.subWidth = RectInfo.width;
- boxBoundaryInfo.subHeight = RectInfo.height;
- if (left < 0) {
- left = 2;
- boxBoundaryInfo.isBoundary = true;
- boxBoundaryInfo.isBoundaryType = 'left';
- }
- if (top < 0) {
- top = 2;
- boxBoundaryInfo.isBoundary = true;
- boxBoundaryInfo.isBoundaryType = 'top';
- }
- if (right < 0) {
- right = 2;
- }
- if (bottom < 0) {
- bottom = 2;
- }
- if (left > mainWidth - 2) {
- left = mainWidth - 2;
- // top = 2;
- boxBoundaryInfo.isBoundary = true;
- boxBoundaryInfo.isBoundaryType = 'right';
- }
- if (top > mainHeight - 2) {
- top = mainHeight - 2;
- boxBoundaryInfo.isBoundary = true;
- boxBoundaryInfo.isBoundaryType = 'bottom';
- }
- target!.style.left = `${left}px`;
- target!.style.top = `${top}px`;
- }
- )
- .on(
- 'dragEnd',
- async ({
- target,
- // isDrag,
- clientX
- // clientY
- }) => {
- if (document.body.clientWidth / 2 - clientX > 0) {
- // 往左出
- directionType.value = 'right';
- } else {
- // 往又出
- directionType.value = 'left';
- }
- isDragIng.value = false;
- // 在这里进行动画
- if (boxBoundaryInfo.isBoundary) {
- // 这里说明贴边了
- target.style.transition = '.3s';
- actionEnd(target, boxBoundaryInfo.isBoundaryType);
- }
- }
- );
- }
- };
- const initMoveableClass = async () => {
- if (document.querySelector('.wrap')) {
- const moveable = new Moveable(document.querySelector('.wrap') as any, {
- target: document.querySelector('#moveNPopover2') as any,
- // If the container is null, the position is fixed. (default: parentElement(document.body))
- container: document.querySelector('.wrap') as any,
- // snappable: true,
- // bounds: {"left":100,"top":100,"right":100,"bottom":100},
- draggable: true,
- resizable: false,
- scalable: false,
- rotatable: false,
- warpable: false,
- pinchable: false, // ["resizable", "scalable", "rotatable"]
- origin: false,
- keepRatio: false,
- // Resize, Scale Events at edges.
- edge: false,
- throttleDrag: 0,
- throttleResize: 0,
- throttleScale: 0,
- throttleRotate: 0
- });
- moveable
- .on(
- 'drag',
- ({
- target,
- // transform,
- left,
- top,
- right,
- bottom
- }) => {
- isDragIng.value = true;
- const subdEl = document.getElementById(
- `moveNPopover2`
- ) as HTMLDivElement;
- // console.log(subdEl, "subdEl", "drag");
- const subdElStyle = getComputedStyle(subdEl, null);
- const RectInfo = {
- left: Number(subdElStyle.left.replace('px', '')),
- top: Number(subdElStyle.top.replace('px', '')),
- width: Number(subdElStyle.width.replace('px', '')),
- height: Number(subdElStyle.height.replace('px', ''))
- };
- const mainWidth =
- parseInt(
- window.getComputedStyle(
- document.querySelector('.wrap') as Element
- ).width
- ) - RectInfo.width;
- const mainHeight =
- parseInt(
- window.getComputedStyle(
- document.querySelector('.wrap') as Element
- ).height
- ) - RectInfo.height;
- subdEl.style.transition = '';
- classBoundaryInfo.isBoundary = false;
- classBoundaryInfo.isBoundaryType = '';
- classBoundaryInfo.mainHeight = mainHeight;
- classBoundaryInfo.mainWidth = mainWidth;
- classBoundaryInfo.subWidth = RectInfo.width;
- classBoundaryInfo.subHeight = RectInfo.height;
- if (left < 0) {
- left = 2;
- classBoundaryInfo.isBoundary = true;
- classBoundaryInfo.isBoundaryType = 'left';
- }
- if (top < 0) {
- top = 2;
- classBoundaryInfo.isBoundary = true;
- classBoundaryInfo.isBoundaryType = 'top';
- }
- if (right < 0) {
- right = 2;
- }
- if (bottom < 0) {
- bottom = 2;
- }
- if (left > mainWidth - 2) {
- left = mainWidth - 2;
- // top = 2;
- classBoundaryInfo.isBoundary = true;
- classBoundaryInfo.isBoundaryType = 'right';
- }
- if (top > mainHeight - 2) {
- top = mainHeight - 2;
- classBoundaryInfo.isBoundary = true;
- classBoundaryInfo.isBoundaryType = 'bottom';
- }
- target!.style.left = `${left}px`;
- target!.style.top = `${top}px`;
- }
- )
- .on(
- 'dragEnd',
- async ({
- target,
- // isDrag,
- clientX
- // clientY
- }) => {
- if (document.body.clientWidth / 2 - clientX > 0) {
- // 往左出
- directionType.value = 'right';
- } else {
- // 往又出
- directionType.value = 'left';
- }
- if (classBoundaryInfo.isBoundary) {
- // 这里说明贴边了
- target.style.transition = '.3s';
- actionEnd(target, classBoundaryInfo.isBoundaryType);
- }
- isDragIng.value = false;
- }
- )
- .on('click', () => {
- showClass.value = true;
- });
- }
- };
- onMounted(() => {
- initMoveable();
- // // initMoveableClass();
- const subdEl = document.getElementById(`moveNPopover`) as HTMLDivElement;
- // // const classEl = document.getElementById(
- // // `moveNPopover2`
- // // ) as HTMLDivElement;
- initBoxRectInfo(subdEl, boxBoundaryInfo);
- // // initBoxRectInfo(classEl, classBoundaryInfo);
- initBoundaryWrap(subdEl, boxBoundaryInfo);
- // // initBoundaryWrap(classEl, classBoundaryInfo);
- window.addEventListener("resize", resetSize);
- });
- const resetSize = ()=>{
- const subdEl = document.getElementById(`moveNPopover`) as HTMLDivElement;
- subdEl.style.display = 'none'
- // const boxBoundaryInfo = reactive({
- // isBoundary: true,
- // isBoundaryType: 'right' as any,
- // mainWidth: '' as any,
- // mainHeight: '' as any,
- // subWidth: '' as any,
- // subHeight: '' as any
- // });
- // boxBoundaryInfo.isBoundary = true;
- // boxBoundaryInfo.isBoundaryType= 'right'
- NPopoverRef.value.setShow(false)
- setTimeout(()=>{
- subdEl.style.transition = ''
- initBoxRectInfo(subdEl, boxBoundaryInfo);
- initBoundaryWrap(subdEl, boxBoundaryInfo);
- console.log('resize')
- subdEl.style.display = 'block'
- },100)
- }
- onUnmounted(()=>{
- window.removeEventListener("resize", resetSize);
- })
- const initBoundaryWrap = (target: any, wrapInfo: any) => {
- target.addEventListener('mouseenter', () => {
- if (wrapInfo.isBoundary) {
- // 如果在边框 就得还原 元素位置 还原完毕后 去除transition
- if (wrapInfo.isBoundaryType == 'left') {
- target.style.left = '2px';
- } else if (wrapInfo.isBoundaryType == 'right') {
- target.style.left = `${wrapInfo.mainWidth - 2}px`;
- } else if (wrapInfo.isBoundaryType == 'top') {
- target.style.top = `${2}px`;
- } else if (wrapInfo.isBoundaryType == 'bottom') {
- target.style.top = `${wrapInfo.mainHeight - 2}px`;
- }
- }
- rate(target, 0);
- });
- target.addEventListener('mouseleave', () => {
- if (wrapInfo.isBoundary) {
- // 如果在边框 就得还原 元素位置 还原完毕后 去除transition
- if (wrapInfo.isBoundaryType == 'left') {
- actionEnd(target, 'left');
- } else if (wrapInfo.isBoundaryType == 'right') {
- actionEnd(target, 'right');
- } else if (wrapInfo.isBoundaryType == 'top') {
- actionEnd(target, 'top');
- } else if (wrapInfo.isBoundaryType == 'bottom') {
- actionEnd(target, 'bottom');
- }
- }
- // rate(target, 0)
- });
- target.addEventListener('contextmenu', (event: any) => {
- event.preventDefault();
- dialog.warning({
- title: '提示',
- content: '是否收入托盘',
- positiveText: '确定',
- negativeText: '取消',
- onPositiveClick: () => {
- console.log('确定')
- },
- onNegativeClick: () => {
- console.log('取消')
- }
- })
- });
- actionEnd(target, 'right');
- };
- const startShowModal = (val: 'setTimeIcon' | 'beatIcon' | 'toneIcon') => {
- if (val == 'setTimeIcon') {
- showModalTime.value = true;
- }
- if (val == 'beatIcon') {
- showModalBeat.value = true;
- }
- if (val == 'toneIcon') {
- showModalTone.value = true;
- }
- };
- // const moveTargetBoundary = (target: any, type: any) => {
- // console.log('moveTargetBoundary', target, type);
- // };
- // 这里是旋转
- const rate = (target: any, rate: any) => {
- target.style.transform = ' rotate(' + rate + ')';
- };
- // 这里是选装的方式
- const actionEnd = (target: any, type: any) => {
- switch (type) {
- case 'left':
- rate(target, '90deg');
- target!.style.left = `${2 - boxBoundaryInfo.subWidth / 2}px`;
- target!.style.top = `${top}px`;
- break;
- case 'right':
- rate(target, '-90deg');
- target!.style.left = `${
- boxBoundaryInfo.mainWidth - 2 + boxBoundaryInfo.subWidth / 2
- }px`;
- target!.style.top = `${top}px`;
- break;
- case 'top':
- target!.style.top = `${2 - boxBoundaryInfo.subHeight / 2}px`;
- rate(target, '-180deg');
- break;
- case 'bottom':
- target!.style.top = `${
- boxBoundaryInfo.mainHeight - 2 + boxBoundaryInfo.subHeight / 2
- }px`;
- break;
- default:
- rate(target, '-0');
- break;
- }
- };
- const initBoxRectInfo = (target: any, wrapInfo: any) => {
- // const subdEl = document.getElementById(`moveNPopover`) as HTMLDivElement;
- // console.log(subdEl, "subdEl", "drag");
- const subdElStyle = getComputedStyle(target, null);
- const RectInfo = {
- left: Number(subdElStyle.left.replace('px', '')),
- top: Number(subdElStyle.top.replace('px', '')),
- width: Number(subdElStyle.width.replace('px', '')),
- height: Number(subdElStyle.height.replace('px', ''))
- };
- // target.style.transition = ''
- const mainWidth =
- parseInt(
- window.getComputedStyle(document.querySelector('.wrap') as Element)
- .width
- ) - RectInfo.width;
- const mainHeight =
- parseInt(
- window.getComputedStyle(document.querySelector('.wrap') as Element)
- .height
- ) - RectInfo.height;
- // boxBoundaryInfo.isBoundary = false;
- // boxBoundaryInfo.isBoundaryType = '';
- wrapInfo.mainHeight = mainHeight;
- wrapInfo.mainWidth = mainWidth;
- wrapInfo.subWidth = RectInfo.width;
- wrapInfo.subHeight = RectInfo.height;
- target.style.transition = '.3s';
- };
- return () => (
- <div class={[styles.wrap, 'wrap']}>
- <div>
- <LayoutSilder></LayoutSilder>
- </div>
- <div class={styles.Wrapcore}>
- <LayoutTop></LayoutTop>
- <div class={styles.WrapcoreView}>
- {/* <div class={styles.WrapcoreViewInfo}> */}
- <router-view>
- {(obj: any) => (
- <Transition name="fade-slide" mode="out-in">
- <obj.Component />
- </Transition>
- )}
- </router-view>
- {/* </div> */}
- </div>
- </div>
- {/* <img
- src={toolStartClass}
- id="moveNPopover2"
- style={{
- display: ['/', '/home', '/classList', '/prepare-lessons'].includes(
- route.path
- )
- ? 'none'
- : 'block'
- }}
- class={[
- styles.toolClassImg,
- 'moveNPopover2',
- isDragIng.value ? styles.isDragIng : ''
- ]}
- alt=""
- /> */}
- <NPopover
- raw
- trigger="click"
- ref={NPopoverRef}
- show-arrow={false}
- placement={directionType.value as 'left' | 'right'}
- v-slots={{
- trigger: () => (
- // 首页不显示工具箱
- <img
- // src={isDragIng.value ? dragingBoxIcon : toolbox}
- src={toolbox}
- id="moveNPopover"
- style={{
- display: ['/', '/home'].includes(route.path)
- ? 'none'
- : 'block'
- }}
- class={[
- styles.toolboxImg,
- 'moveNPopover',
- isDragIng.value ? styles.isDragIng : ''
- ]}
- alt=""
- />
- )
- }}>
- <div class={styles.booxToolWrap}>
- <div
- class={styles.booxToolItem}
- onClick={() => startShowModal('beatIcon')}>
- <img src={beatIcon} alt="" />
- 节拍器
- </div>
- <div
- class={styles.booxToolItem}
- onClick={() => startShowModal('toneIcon')}>
- <img src={toneIcon} alt="" />
- 调音器
- </div>
- <div
- class={styles.booxToolItem}
- onClick={() => startShowModal('setTimeIcon')}>
- <img src={setTimeIcon} alt="" />
- 计时器
- </div>
- <div class={styles.booxToolItem} onClick={()=>{
- showClass.value = true
- }} style={{
- display: [
- '/',
- '/home',
- '/classList',
- '/prepare-lessons'
- ].includes(route.path)
- ? 'none'
- : 'block'
- }}>
- <img
- src={toolStartClass}
- style={{
- display: [
- '/',
- '/home',
- '/classList',
- '/prepare-lessons'
- ].includes(route.path)
- ? 'none'
- : 'block'
- }}
- class={[
- styles.toolClassImg,
- ]}
- alt=""
- />
- 开始上课
- </div>
- </div>
- </NPopover>
- <NModal
- class={['modalTitle background']}
- title={'节拍器'}
- preset="card"
- v-model:show={showModalBeat.value}
- style={{ width: '687px' }}>
- <div class={styles.modeWrap}>
- <iframe
- src={`${vaildUrl()}/metronome/?id=${new Date().getTime()}`}
- scrolling="no"
- frameborder="0"
- width="100%"
- height={'650px'}></iframe>
- </div>
- </NModal>
- <NModal v-model:show={showModalTone.value} class={['background']}>
- {/* <div
- onClick={() => {
- showModalTone.value = false;
- }}>
- <NImage
- src={toneImage}
- previewDisabled
- class={styles.beatImage}></NImage>
- </div> */}
- <div>
- <PlaceholderTone
- onClose={() => {
- showModalTone.value = false;
- }}></PlaceholderTone>
- </div>
- </NModal>
- <NModal
- v-model:show={showModalTime.value}
- class={['modalTitle background']}
- title={'计时器'}
- preset="card"
- style={{ width: px2vw(772) }}>
- <div>
- <TimerMeter></TimerMeter>
- </div>
- </NModal>
- <NModal
- v-model:show={showClass.value}
- class={['modalTitle background', styles.showClass]}
- preset="card"
- title={'开始上课'}>
- <ChioseModal
- onClose={() => (showClass.value = false)}
- onPreview={(item: any) => {
- if (window.matchMedia('(display-mode: standalone)').matches) {
- previewModal.value = true;
- previewItem.value = {
- ...item
- };
- state.application = window.matchMedia('(display-mode: standalone)').matches
- fscreen()
- } else {
- const { href } = router.resolve({
- path: '/attend-class',
- query: {
- ...item
- }
- });
- window.open(href, +new Date() + '');
- }
- }}
- />
- </NModal>
- {/* 弹窗查看 */}
- <PreviewWindow
- v-model:show={previewModal.value}
- type="attend"
- params={previewItem.value}
- />
- </div>
- );
- }
- });
|