123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- import { defineComponent, onMounted, reactive, ref } 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_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 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
- } from './setting';
- import { handleStartTick, hendleEndTick } from './tick';
- import { handleStartBeat, hendleEndBeat } from './beat-tick';
- import { browser } from '@/helpers/utils';
- import { useRoute } from 'vue-router';
- export default defineComponent({
- name: 'tempo-practice',
- setup() {
- const route = useRoute();
- const state = reactive({
- platform: route.query.platform, // microapp 老师端应用里面打开单独处理返回逻辑
- win: route.query.win,
- settingStatus: 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' }
- ]
- });
- // 返回
- const goback = () => {
- if (state.platform === 'microapp') {
- window.parent.postMessage(
- {
- api: 'iframe_exit'
- },
- '*'
- );
- return;
- }
- if (!browser().isApp) {
- window.close();
- return;
- }
- postMessage({ api: 'goBack' });
- };
- /** 播放切换 */
- const handlePlay = async () => {
- if (setting.playState === 'pause') {
- setting.playState = 'play';
- if (setting.playType === 'beat') {
- await handleStartTick();
- } else {
- await handleStartBeat();
- }
- } else {
- handleStop();
- }
- };
- /** 播放类型 */
- const handlePlayType = () => {
- handleStop();
- if (setting.playType === 'beat') {
- setting.playType = 'tempo';
- } else {
- setting.playType = 'beat';
- }
- };
- const handleStop = () => {
- setting.playState = 'pause';
- if (setting.playType === 'beat') {
- hendleEndTick();
- } else {
- hendleEndBeat();
- }
- };
- onMounted(() => {
- state.speedList.forEach((item: any) => {
- if (item.value === setting.speed) item.color = '#1CACF1';
- });
- renderScore();
- });
- return () => (
- <div class={[styles.tempoPractice, state.win === 'pc' ? styles.pc : '']}>
- <div class={styles.head}>
- <div class={styles.back} onClick={goback}>
- <img src={icon_back} />
- </div>
- <div class={styles.title}>
- <img src={icon_title} />
- </div>
- <div
- class={styles.back}
- onClick={() => {
- handleStop();
- state.settingStatus = true;
- }}>
- <img src={icon_setting} />
- </div>
- </div>
- <div class={styles.conCon}>
- <div class={styles.container}>
- {setting.scorePart.map((item: any, i: number) => (
- <div
- class={[
- styles.beatSection,
- setting.scorePart.length >= 2 &&
- item.length !== 1 &&
- styles.small
- ]}>
- {item.map((child: any, jIndex: number) => (
- <div
- class={[styles.beat, child.selected ? styles.active : '']}>
- <div class={styles.direction}>
- <div
- class={styles.up}
- onClick={() => {
- 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;
- }}></div>
- <div
- class={styles.down}
- onClick={() => {
- 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;
- }}></div>
- </div>
- <div class={styles.imgSection}>
- <img src={getImage(child.url)} />
- </div>
- </div>
- ))}
- </div>
- ))}
- </div>
- </div>
- <div class={styles.footer}>
- {/* 播放 */}
- <div class={styles.play} onClick={handlePlay}>
- {setting.playState === 'pause' ? (
- <img src={iconPause} />
- ) : (
- <img src={iconPlay} />
- )}
- </div>
- {/* 播放类型 */}
- <div class={styles.playType} onClick={handlePlayType}>
- {setting.playType === 'beat' ? (
- <img src={beat} />
- ) : (
- <img src={tempo} />
- )}
- </div>
- {/* 随机生成 */}
- <div
- class={styles.randomTempo}
- onClick={() => {
- renderScore();
- handleStop();
- }}>
- <img src={randDom} />
- </div>
- {/* 速度 */}
- <div class={styles.speedChange}>
- <img
- src={iconPlus}
- class={styles.speedPlus}
- onClick={() => {
- if (setting.speed <= 40) return;
- setting.speed -= 1;
- handleStop();
- }}
- />
- <Popover
- placement="top"
- class={styles.popupContainer}
- actions={state.speedList}
- onSelect={(val: any) => {
- if (val.value === setting.speed) return;
- state.speedList.forEach((item: any) => {
- if (item.value === val.value) {
- item.color = '#1CACF1';
- setting.speed = val.value;
- } else {
- item.color = '#060606';
- }
- });
- handleStop();
- }}>
- {{
- reference: () => (
- <div class={styles.speedNum}>{setting.speed}</div>
- )
- }}
- </Popover>
- <img
- src={iconAdd}
- class={styles.speedAdd}
- onClick={() => {
- if (setting.speed >= 200) return;
- setting.speed += 1;
- handleStop();
- }}
- />
- </div>
- </div>
- <Popup v-model:show={state.settingStatus} class={styles.settingPopup}>
- <SettingModal onClose={() => (state.settingStatus = false)} />
- </Popup>
- </div>
- );
- }
- });
|