lex 1 rok temu
rodzic
commit
e3522b3e50

+ 46 - 19
src/views/tempo-practice/index.module.less

@@ -13,6 +13,45 @@
   flex-direction: column;
 }
 
+.conCon {
+  flex: 1 auto;
+  display: flex;
+  align-items: center;
+}
+
+.pc {
+
+  .container {
+    max-width: 1200px;
+    gap: 30px 0;
+  }
+
+  .beatSection {
+    .beat {
+      width: 206px;
+      height: 284px;
+
+      img {
+        width: 140px;
+      }
+    }
+
+    &.small {
+      .beat {
+        width: 139px !important;
+        height: 191px !important;
+
+        // width: 65px;
+        //   height: 86px;
+
+        img {
+          width: 108px;
+        }
+      }
+    }
+  }
+}
+
 .head {
   position: relative;
   display: flex;
@@ -89,24 +128,6 @@
     }
   }
 
-  // &.minLength {
-  //   &:nth-child(2n + 1) {
-  //     margin-left: 10vw;
-  //   }
-
-  //   &:nth-child(2n + 2) {
-  //     margin-right: 10vw;
-  //   }
-  // }
-
-  // &.maxLength {
-  //   margin: 0 12px;
-
-  //   .beat {
-  //     margin: 0 7px;
-  //   }
-  // }
-
   .beat {
     display: flex;
     align-items: center;
@@ -238,14 +259,20 @@
 
 .popupContainer {
   margin-top: -10px !important;
-  --van-popover-action-height: 30px;
+  --van-popover-action-height: 32px;
   --van-popover-action-font-size: 14px;
   --van-popover-radius: 12px;
   --van-popover-action-width: 85px;
+  padding: 4Px 0;
+  border-radius: 12px;
+  background-color: #fff;
+  box-shadow: 0 0.05333rem 0.32rem rgba(50, 50, 51, .12);
+
 
   :global {
     .van-popover__content {
       max-height: 200px;
+      box-shadow: none;
       overflow-y: auto;
     }
 

+ 51 - 29
src/views/tempo-practice/index.tsx

@@ -19,11 +19,16 @@ import SettingModal from './setting-modal';
 import { randomScoreElement, renderScore, setting } 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' },
@@ -47,6 +52,20 @@ export default defineComponent({
     });
     // 返回
     const goback = () => {
+      if (state.platform === 'microapp') {
+        window.parent.postMessage(
+          {
+            api: 'iframe_exit'
+          },
+          '*'
+        );
+
+        return;
+      }
+      if (!browser().isApp) {
+        window.close();
+        return;
+      }
       postMessage({ api: 'goBack' });
     };
 
@@ -89,7 +108,7 @@ export default defineComponent({
       renderScore();
     });
     return () => (
-      <div class={styles.tempoPractice}>
+      <div class={[styles.tempoPractice, state.win === 'pc' ? styles.pc : '']}>
         <div class={styles.head}>
           <div class={styles.back} onClick={goback}>
             <img src={icon_back} />
@@ -102,36 +121,39 @@ export default defineComponent({
           </div>
         </div>
 
-        <div class={styles.container}>
-          {setting.scorePart.map((item: any, i: number) => (
-            <div
-              class={[
-                styles.beatSection,
-                // item.length !== 1 &&
-                setting.scorePart.length >= 2 &&
-                  item.length !== 1 &&
-                  styles.small
-              ]}>
-              {item.map((child: any, j: number) => (
-                <div
-                  class={[styles.beat, child.selected ? styles.active : '']}
-                  onClick={() => {
-                    if (setting.tempo.length <= 1) {
-                      showToast('无法切换,请选择至少2种节奏型');
-                      return;
-                    }
-                    const obj = randomScoreElement(child.index);
-                    child.index = obj.index;
-                    child.url = obj.url;
-                  }}>
-                  <div class={styles.imgSection}>
-                    <img src={getImage(child.url)} />
+        <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, j: number) => (
+                  <div
+                    class={[styles.beat, child.selected ? styles.active : '']}
+                    onClick={() => {
+                      if (setting.playState === 'play') return;
+                      if (setting.tempo.length <= 1) {
+                        showToast('无法切换,请选择至少2种节奏型');
+                        return;
+                      }
+                      const obj = randomScoreElement(child.index);
+                      child.index = obj.index;
+                      child.url = obj.url;
+                    }}>
+                    <div class={styles.imgSection}>
+                      <img src={getImage(child.url)} />
+                    </div>
                   </div>
-                </div>
-              ))}
-            </div>
-          ))}
+                ))}
+              </div>
+            ))}
+          </div>
         </div>
+
         <div class={styles.footer}>
           {/* 播放 */}
           <div class={styles.play} onClick={handlePlay}>

+ 3 - 1
src/views/tempo-practice/setting-modal/index.module.less

@@ -1,7 +1,7 @@
 .settingContainer {
   position: relative;
   width: 430px;
-  height: 86vh;
+  height: min(86vh, 340px);
   background: #fff;
   border-radius: 26px;
   padding: 20px 0;
@@ -100,6 +100,8 @@
   align-items: center;
   justify-content: center;
   padding: 14px 0;
+  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
+  border-radius: 0 0 26px 26px;
 
   .btnSubmit {
     width: 143px;

+ 35 - 13
src/views/tempo-practice/setting-modal/index.tsx

@@ -13,6 +13,7 @@ import {
 import { getImage } from '../images/music';
 import { hendleEndTick } from '../tick';
 import { hendleEndBeat } from '../beat-tick';
+import deepClone from '@/helpers/deep-clone';
 
 export default defineComponent({
   emits: ['close'],
@@ -43,7 +44,7 @@ export default defineComponent({
       }
     };
 
-    const handleStopPlay = () => {
+    const handleStop = () => {
       setting.playState = 'pause';
       if (setting.playType === 'beat') {
         hendleEndTick();
@@ -57,21 +58,43 @@ export default defineComponent({
         showToast('节奏型不能为空');
         return;
       }
-      setting.element = state.element;
-      setting.beat = state.beat;
-      setting.barLine = state.barLine;
-      setting.tempo = state.tempo;
+      let status = false; // 是否有更改
+      if (
+        setting.element !== state.element ||
+        setting.beat !== state.beat ||
+        setting.barLine !== state.barLine ||
+        setting.tempo.join(',') !== state.tempo.join(',')
+      ) {
+        status = true;
+      }
+
+      // 判断是否有数据变化
+      handleStop();
+      if (status) {
+        setting.element = state.element;
+        setting.beat = state.beat;
+        setting.barLine = state.barLine;
+        setting.tempo = state.tempo;
+        renderScore();
+      }
 
-      handleStopPlay();
-      renderScore();
       emit('close');
     };
 
-    onMounted(() => {});
     return () => (
       <div class={styles.settingContainer}>
         <div class={styles.title}></div>
-        <i class={styles.iconClose} onClick={() => emit('close')}></i>
+        <i
+          class={styles.iconClose}
+          onClick={() => {
+            emit('close');
+            setTimeout(() => {
+              state.element = setting.element;
+              state.beat = setting.beat;
+              state.barLine = setting.barLine;
+              state.tempo = setting.tempo;
+            }, 100);
+          }}></i>
 
         <div class={styles.settingContent}>
           <div class={styles.settingParams}>
@@ -135,10 +158,9 @@ export default defineComponent({
               ))}
             </div>
           </div>
-
-          <div class={styles.btnGroup}>
-            <Button class={styles.btnSubmit} onClick={onSubmit}></Button>
-          </div>
+        </div>
+        <div class={styles.btnGroup}>
+          <Button class={styles.btnSubmit} onClick={onSubmit}></Button>
         </div>
       </div>
     );

+ 7 - 3
src/views/tempo-practice/setting.ts

@@ -9,7 +9,7 @@ export const setting = reactive({
   tempo: ['1', '2', '3'] as any[], // 节奏形筛选
   scorePart: [] as any, // 生成谱面
   playState: 'pause' as 'pause' | 'play',
-  playType: 'beat' as 'beat' | 'tempo',
+  playType: 'tempo' as 'beat' | 'tempo',
   speed: 60 // 默认速度
 });
 
@@ -102,9 +102,13 @@ export const renderScore = () => {
 
   const beatLengthInMilliseconds = (60 / setting.speed) * 1000;
   if (setting.playType === 'beat') {
-    handleInitTick(beatLengthInMilliseconds, Number(beat) || 4);
+    handleInitTick(
+      beatLengthInMilliseconds,
+      Number(beatA[1]) || 4,
+      Number(beatA[0])
+    );
   } else {
-    handleInitBeat(beatLengthInMilliseconds, Number(beat) || 4);
+    handleInitBeat(beatLengthInMilliseconds, Number(beatA[1]) || 4);
   }
   initSelectScorePart();
 };

+ 23 - 14
src/views/tempo-practice/tick.ts

@@ -6,7 +6,8 @@ import { beatDesc } from './beat-desc';
 
 const tickData = reactive({
   list: [] as number[],
-  len: 0,
+  len: 0, // 有几拍
+  afterBeat: 0, // 一小节里面有几拍
   tickEnd: false,
   /** 节拍器时间 */
   beatLengthInMilliseconds: 0,
@@ -74,11 +75,13 @@ const handlePlay = (i: number, source: any) => {
  */
 export const handleInitTick = (
   beatLengthInMilliseconds: number,
-  beat: number
+  beat: number,
+  afterBeat: number
 ) => {
   tickData.state = '';
   tickData.beatLengthInMilliseconds = beatLengthInMilliseconds;
   tickData.len = beat;
+  tickData.afterBeat = afterBeat;
 };
 
 /** 开始节拍器 */
@@ -96,25 +99,31 @@ export const handleStartTick = async () => {
   }
   tickData.index = 0;
   tickData.beatLengthInMilliseconds = (60 / setting.speed) * 1000;
-  // let startTime = +new Date();
-  // const allTick: any = [];
-  // console.log(setting.scorePart, tickData.len);
+
+  if (tickData.afterBeat === 8) {
+    tickData.beatLengthInMilliseconds = tickData.beatLengthInMilliseconds * 0.5;
+  }
+
   for (let i = 0; i < setting.scorePart.length; i++) {
     if (tickData.tickEnd) return false;
     const temp = setting.scorePart[i];
-    // console.log(temp, 'temp', beatDesc[i.index]);
-    for (let j = 0; j < temp.length; j++) {
+    let len = temp.length;
+    if (tickData.afterBeat === 8) {
+      len = tickData.len;
+    }
+
+    for (let j = 0; j < len; j++) {
       // 提前结束, 直接放回false
       if (tickData.tickEnd) return false;
       const source =
-        j === 0
-          ? tickData.source1
-          : j === temp.length
-          ? null
-          : tickData.source2;
-      console.log(j, 'source');
+        j === 0 ? tickData.source1 : j === len ? null : tickData.source2;
+
       await handlePlay(j, source);
-      initSelectScorePart(i, j);
+      if (tickData.afterBeat === 8) {
+        initSelectScorePart(i, Math.floor((j <= 0 ? 1 : j) / 3));
+      } else {
+        initSelectScorePart(i, j);
+      }
     }
   }