import { defineComponent, onMounted, onUnmounted, reactive, ref, watch, toRef } from 'vue'; import styles from './index.module.less'; import { postMessage } from '@/helpers/native-message'; import icon_title from './images/icon-title.png'; import icon_back from './images/icon-back.png'; import icon_back1 from './images/icon-back1.png'; import icon_setting from './images/icon-setting.png'; import iconPlay from './images/icon-play.png'; import iconPause from './images/icon-pause.png'; import beat from './images/btn-2.png'; import tempo from './images/btn-3.png'; import randDom from './images/btn-1.png'; import setImg from './images/setting.png'; import iconPlus from './images/icon-plus.png'; import iconAdd from './images/icon-add.png'; import { getImage } from './images/music'; import '@vant/touch-emulator'; // import j2 from './images/music/j-2.png'; import { Popover, Popup, showToast } from 'vant'; import SettingModal from './setting-modal'; import { randomScoreElement, renderScore, setting, elementDirection, setting_modal, initSelectScorePartModal, renderScoreModal } from './setting'; import { handleStartTick, hendleEndTick } from './tick'; import { handleStartBeat, hendleEndBeat } from './beat-tick'; import { browser } from '@/helpers/utils'; import { useRoute } from 'vue-router'; import useDrag from '@/hooks/useDrag'; import useDragGuidance from '@/hooks/useDrag/useDragGuidance'; import { state as stateData } from '@/state'; import SettingPcModal from './setting-pc-modal'; import Draggable from 'vuedraggable'; export default defineComponent({ name: 'tempo-practice', props: { dataJson: { type: Object, default: () => {} }, modeType: { type: String, default: '' }, show: { type: Boolean, default: false } }, setup(props, { expose }) { const route = useRoute(); const state = reactive({ modeType: '' as any, platform: route.query.platform, win: route.query.win, settingStatus: false, settingPcStatus: false, speedList: [ { text: '40', value: 40, color: '#060606' }, { text: '50', value: 50, color: '#060606' }, { text: '60', value: 60, color: '#060606' }, { text: '70', value: 70, color: '#060606' }, { text: '80', value: 80, color: '#060606' }, { text: '90', value: 90, color: '#060606' }, { text: '100', value: 100, color: '#060606' }, { text: '110', value: 110, color: '#060606' }, { text: '120', value: 120, color: '#060606' }, { text: '130', value: 130, color: '#060606' }, { text: '140', value: 140, color: '#060606' }, { text: '150', value: 150, color: '#060606' }, { text: '160', value: 160, color: '#060606' }, { text: '170', value: 170, color: '#060606' }, { text: '180', value: 180, color: '#060606' }, { text: '190', value: 190, color: '#060606' }, { text: '200', value: 200, color: '#060606' } ], dataJson: {} as any, playPos: (route.query.imagePos || 'left') as 'left' | 'right' // 数字课堂老师端上课 镜像字段 }); // 拖拽临时数据 const tempDragData = ref({}); // 返回 const goback = (e: any) => { e.stopPropagation(); if (route.query.backBtnType === 'microapp') { // microapp 老师端应用里面打开单独处理返回逻辑 window.parent.postMessage( { api: 'iframe_exit' }, '*' ); return; } if (!browser().isApp) { window.close(); return; } postMessage({ api: 'goBack' }); }; /* 修改设置的某个值 */ const updateSettingValue = (key: string, value: any) => { if (state.settingStatus) { setting_modal[key] = value; } else { setting[key] = value; } }; /* 获取设置的某一个值 */ const getSettingValue = (key: string) => { let value: any = null; if (state.settingStatus) { value = setting_modal[key]; } else { value = setting[key]; } return value; }; /** 播放切换 */ const handlePlay = async () => { const playState = getSettingValue('playState'); const playType = getSettingValue('playType'); if (playState === 'pause') { updateSettingValue('playState', 'play'); if (playType === 'beat') { await handleStartTick(state.settingStatus); } else { await handleStartBeat(state.settingStatus); } } else { handleStop(); } }; /** 播放切换 */ const handlePlay2 = async () => { const playState = getSettingValue('playState'); const playType = getSettingValue('playType'); if (playState === 'pause') { updateSettingValue('playState', 'play'); if (playType === 'beat') { await handleStartTick(state.settingStatus); } else { await handleStartBeat(state.settingStatus); } } }; /** 播放类型 */ const handlePlayType = () => { handleStop(); // 判断是否有设置 const playType = getSettingValue('playType'); if (playType === 'beat') { updateSettingValue('playType', 'tempo'); } else { updateSettingValue('playType', 'beat'); } }; const handleStop = () => { const playType = getSettingValue('playType'); updateSettingValue('playState', 'pause'); if (playType === 'beat') { hendleEndTick(state.settingStatus); } else { hendleEndBeat(state.settingStatus); } }; // {"element":"jianpu","beat":"4-4","barLine":"1","tempo":["1","2","3"]}' const onIframeHandle = (ev: MessageEvent) => { // 获取配置 if (ev.data.api === 'getTempoSetting') { window.parent.postMessage( { api: 'getTempoSetting', data: JSON.stringify({ setting: { element: setting.element, beat: setting.beat, barLine: setting.barLine, tempo: setting.tempo, scorePart: setting.scorePart, playType: setting.playType, speed: setting.speed }, coverImg: '' }) }, '*' ); } if (ev.data.api === 'setPlayState') { if (ev.data.data) { handlePlay(); } else { handleStop(); } } if (ev.data.api === 'resetPlay') { resetSetting(); } if (ev.data.api === 'imagePos') { if (ev.data.data === 'right') { state.playPos = 'right'; } else { state.playPos = 'left'; } } }; const resetSetting = () => { try { let dataJson = props.dataJson; if (route.query.dataJson) { dataJson = JSON.parse(route.query.dataJson as any); } if (dataJson) { setting.element = dataJson.element; setting.beat = dataJson.beat; setting.barLine = dataJson.barLine; setting.tempo = dataJson.tempo; setting.scorePart = dataJson.scorePart; setting.playType = dataJson.playType; setting.speed = dataJson.speed; setting_modal.element = dataJson.element; setting_modal.beat = dataJson.beat; setting_modal.barLine = dataJson.barLine; setting_modal.tempo = dataJson.tempo; setting_modal.scorePart = dataJson.scorePart; setting_modal.playType = dataJson.playType; setting_modal.speed = dataJson.speed; state.dataJson = dataJson; } } catch (e) { // console.log(e, '1'); } }; // watch( // () => props.show, // val => { // console.log(val, props.show); // if (!val) { // // resetSetting(); // handleStop(); // } else { // resetSetting(); // } // } // ); /** 打开设置 */ const onOpenSetting = () => { handleStop(); // 初始化设置的数据 for (let i in setting) { setting_modal[i] = JSON.parse(JSON.stringify(setting[i])); } if (state.win === 'pc' || state.platform === 'modal') { state.settingPcStatus = true; } else { state.settingStatus = true; } }; onMounted(() => { // 安卓的状态栏 postMessage({ api: 'setStatusBarVisibility', content: { isVisibility: 0 } }); if (route.query.modeType) { state.modeType = route.query.modeType; } resetSetting(); state.speedList.forEach((item: any) => { if (item.value === setting.speed) item.color = '#1CACF1'; }); if (setting?.scorePart?.length <= 0) { renderScore(); } window.addEventListener('message', onIframeHandle); }); onUnmounted(() => { window.removeEventListener('message', onIframeHandle); }); watch( () => state.settingStatus, () => { if (!state.settingStatus) { state.speedList.forEach((item: any) => { if (item.value === getSettingValue('speed')) { item.color = '#1CACF1'; } else { item.color = '#060606'; } }); handleStop(); } } ); expose({ resetSetting }); let settingBoxDragData: any; let settingBoxClass: string; if (state.platform === 'modal') { settingBoxClass = 'settingBoxClass_drag'; settingBoxDragData = useDrag( [ `${settingBoxClass} .iconTitBoxMove`, `${settingBoxClass} .bom_drag_point`, `${settingBoxClass} .bom_drag_point_right` ], settingBoxClass, toRef(state, 'settingPcStatus'), stateData.user.data.id ); } // 引导页 const { guidanceShow, setGuidanceShow } = useDragGuidance(); return () => (
{ state.settingStatus = false; window.parent.postMessage( { api: 'clickTempo' }, '*' ); }} class={[ styles.tempoPractice, state.win === 'pc' ? styles.pc : '', state.platform === 'modal' ? styles.modal : '', state.modeType === 'courseware' ? styles.courseware : '' ]}>
{state.modeType !== 'courseware' && (
)}
{state.modeType !== 'courseware' && state.platform !== 'modal' && !state.settingStatus ? (
{ e.stopPropagation(); onOpenSetting(); }}>
) : (
)}
{getSettingValue('scorePart')?.map((item: any, i: number) => (
= 2 && item.length !== 1 && styles.small ]}> {item.map((child: any, jIndex: number) => ( { tempDragData.value = evt.added || ''; }} onAdd={() => { const added = tempDragData.value?.element || {}; // 判断是否有数据 if (added.url && added.sourceFrom === 'setting-modal') { handleStop(); setting_modal.scorePart.forEach( (part: Array, ci: number) => { part.forEach((child: any, cj: number) => { if (i === ci && jIndex === cj) { child.url = added.url; child.index = added.index; } }); } ); } }} onStart={(evt: any) => { evt.from.classList.add('onstart'); tempDragData.value = {}; }} onEnd={(evt: any) => { evt.from.classList.remove('onstart'); tempDragData.value = {}; }} onClick={(e: any) => { e.stopPropagation(); // 编辑时可以操作 if (state.settingStatus) { handleStop(); if (setting_modal.scorePart[i][jIndex].selected) { initSelectScorePartModal(); } else { initSelectScorePartModal(i, jIndex); } } }} class={[ styles.beat, child.selected ? styles.active : '', state.settingStatus && styles.disabledChange ]}> {{ item: (element: any) => { const child = element.element; const jIndex = element.index; return (
{/* 编辑时不可上下切换 */} {!state.settingStatus && (
{ if (setting.playState === 'play') return; if (setting.tempo.length <= 1) { showToast( '无法切换,请选择至少2种节奏型' ); return; } // const obj = randomScoreElement(child.index); const obj = elementDirection( 'up', child.index ); child.index = obj.index; child.url = obj.url; }}>
{ if (setting.playState === 'play') return; if (setting.tempo.length <= 1) { showToast( '无法切换,请选择至少2种节奏型' ); return; } // const obj = randomScoreElement(child.index); const obj = elementDirection( 'down', child.index ); child.index = obj.index; child.url = obj.url; }}>
)}
); } }}
))}
))}
{ e.stopPropagation(); }}> {/* 播放 */} {state.playPos === 'left' && ( <> {route.query.back === 'show' && (
)}
{getSettingValue('playState') === 'pause' ? ( ) : ( )}
)} {/* 老师端来的时候的设置按钮 */} {state.platform === 'modal' && state.playPos === 'right' && (
{ onOpenSetting(); }}>
)} {/* 播放类型 */}
{getSettingValue('playType') === 'beat' ? ( ) : ( )}
{/* 随机生成 */}
{ if (state.settingStatus) { renderScoreModal(); } else { renderScore(); } handleStop(); }}>
{/* 速度 */}
{ const speed = getSettingValue('speed'); if (speed <= 40) return; updateSettingValue('speed', speed - 1); handleStop(); state.speedList.forEach((item: any) => { if (item.value === getSettingValue('speed')) { item.color = '#1CACF1'; updateSettingValue('speed', getSettingValue('speed')); } else { item.color = '#060606'; } }); }} /> { const speed = getSettingValue('speed'); if (val.value === speed) return; state.speedList.forEach((item: any) => { if (item.value === val.value) { item.color = '#1CACF1'; updateSettingValue('speed', val.value); } else { item.color = '#060606'; } }); handleStop(); }}> {{ reference: () => (
{getSettingValue('speed')}
) }}
{ const speed = getSettingValue('speed'); if (speed >= 200) return; updateSettingValue('speed', speed + 1); handleStop(); state.speedList.forEach((item: any) => { if (item.value === getSettingValue('speed')) { item.color = '#1CACF1'; updateSettingValue('speed', getSettingValue('speed')); } else { item.color = '#060606'; } }); }} />
{/* 播放 */} {state.playPos === 'right' && (
{getSettingValue('playState') === 'pause' ? ( ) : ( )}
)} {/* 老师端来的时候的设置按钮 */} {state.platform === 'modal' && state.playPos === 'left' && (
{ onOpenSetting(); }}>
)}
{ e.stopPropagation(); }}> (state.settingStatus = false)} />
(state.settingPcStatus = false)} />
); } });