| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- import { computed, defineComponent, nextTick, reactive, ref, toRefs } from "vue";
- import styles from "./index.module.less";
- import { api_back } from "/src/helpers/communication";
- import state from "/src/state";
- import iconBack from "./image/icon-back.svg";
- import iconShiyi from "./image/icon-shiyi.svg";
- import iconhuifang from "./image/icon-huifang.svg";
- import { Grid, GridItem, Popup } from "vant";
- import videobg from "./image/videobg.png";
- import "plyr/dist/plyr.css";
- import Plyr from "plyr";
- import { browser } from "/src/utils";
- import Note from "../note";
- import { storeData } from "/src/store";
- type IItemType = "intonation" | "cadence" | "integrity";
- export default defineComponent({
- name: "header-top",
- props: {
- scoreData: {
- type: Object,
- default: () => ({}),
- },
- },
- setup(props, {expose}) {
- const browserInfo = browser();
- const { scoreData } = toRefs(props);
- const shareData = reactive({
- show: false,
- shiyiShow: false,
- isInitPlyr: false,
- _plrl: null as any,
- });
- const level: any = {
- BEGINNER: "入门级",
- ADVANCED: "进阶级",
- PERFORMER: "大师级",
- };
- // console.log("🚀 ~ scoreData:", scoreData.value)
- const itemType = ref<IItemType>("intonation");
- /** 返回 */
- const handleBack = () => {
- api_back();
- };
- const handleChange = (type: IItemType) => {
- itemType.value = type;
- scoreData.value.itemType = type
- };
- // 资源类型
- const mediaType = computed((): "audio" | "video" => {
- const subfix = (scoreData.value.videoFilePath || "").split(".").pop();
- if (subfix === "wav" || subfix === "mp3" || subfix === "m4a") {
- return "audio";
- }
- return "video";
- });
- const openAudioAndVideo = () => {
- shareData.show = true;
- if (shareData.isInitPlyr) return;
- nextTick(() => {
- const id = mediaType.value === "audio" ? "#audioSrc" : "#videoSrc";
- shareData._plrl = new Plyr(id, {
- controls: ["play-large", "play", "progress", "current-time"],
- fullscreen: { enabled: false },
- });
- shareData.isInitPlyr = true;
- });
- };
- return () => (
- <div class={[styles.headerTop, browserInfo.android && styles.android]}>
- <div class={[styles.back, !storeData.isApp && styles.disabled]} onClick={handleBack}>
- <img src={iconBack} />
- </div>
- <div class={styles.center}>
- <div class={styles.cItem}>
- <div>{level[scoreData.value.heardLevel]}</div>
- <div>难度</div>
- </div>
- <div class={styles.cItem}>
- <div>{scoreData.value.score}分</div>
- <div>评测分数</div>
- </div>
- {state.isPercussion ? null : (
- <>
- <div
- onClick={() => handleChange("intonation")}
- class={[styles.cItem, itemType.value === "intonation" && styles.active]}
- >
- <div style={{ color: "rgb(45, 199, 170)" }}>{scoreData.value.intonation}分</div>
- <div>音准</div>
- </div>
- <div
- onClick={() => handleChange("cadence")}
- class={[styles.cItem, itemType.value === "cadence" && styles.active]}
- >
- <div style={{ color: "#FF4E19" }}>{scoreData.value.cadence}分</div>
- <div>节奏</div>
- </div>
- <div
- onClick={() => handleChange("integrity")}
- class={[styles.cItem, itemType.value === "integrity" && styles.active]}
- >
- <div style={{ color: "rgb(255, 196, 89)" }}>{scoreData.value.integrity}分</div>
- <div>完成度</div>
- </div>
- </>
- )}
- </div>
- <div class={styles.right}>
- <div
- style={{ display: scoreData.value.videoFilePath ? "" : "none" }}
- class={styles.btn}
- onClick={openAudioAndVideo}
- >
- <img class={styles.iconBtn} src={iconhuifang} />
- <span>回放</span>
- </div>
- <div class={styles.btn} onClick={() => (shareData.shiyiShow = true)}>
- <img class={styles.iconBtn} src={iconShiyi} />
- <span>释义</span>
- </div>
- {/* <div class={styles.btn}>
- <img class={styles.iconBtn} src={iconhuifang} />
- <span>再来一遍</span>
- </div> */}
- </div>
- {state.isPercussion ? null : (
- <div class={styles.demos}>
- <div>
- <Note fill="#01C1B5" />
- <span>演奏正确</span>
- </div>
- {itemType.value === "intonation" && (
- <>
- <div>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FFAB25" shadow x={-2} y={0} />
- <span>音高了</span>
- </div>
- <div>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FFAB25" shadow x={-1} y={-3} />
- <span>音低了</span>
- </div>
- </>
- )}
- {itemType.value === "cadence" && (
- <>
- <div>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FF4444" shadow x={0.5} y={-1} />
- <span>节奏过快</span>
- </div>
- <div>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FF4444" shadow x={-3} y={-2.5} />
- <span>节奏慢了</span>
- </div>
- </>
- )}
- {itemType.value === "integrity" && (
- <div>
- <Note fill="#CC75FF" />
- <span>完成度不足</span>
- </div>
- )}
- <div>
- <Note fill="#AEAEAE" />
- <span>未演奏</span>
- </div>
- </div>
- )}
- <Popup
- teleport="body"
- class={["popup-custom", "van-scale", styles.popup]}
- transition="van-scale"
- v-model:show={shareData.show}
- closeable
- onClose={() => {
- shareData._plrl?.pause();
- }}
- >
- {mediaType.value === "audio" && (
- <div class={styles.audiobox}>
- <audio
- id="audioSrc"
- src={scoreData.value.videoFilePath}
- controls="false"
- preload="metadata"
- playsinline
- />
- </div>
- )}
- {mediaType.value === "video" && (
- <div class={styles.videobox}>
- <video
- id="videoSrc"
- class={styles.videoBox}
- src={scoreData.value.videoFilePath}
- data-poster={videobg}
- preload="metadata"
- playsinline
- />
- </div>
- )}
- </Popup>
- <Popup
- v-model:show={shareData.shiyiShow}
- class="popup-custom van-scale center-closeBtn"
- transition="van-scale"
- teleport="body"
- closeable
- >
- <div class={styles.shiyiPopup}>
- <div class={styles.shiyiTitle}>图标释义</div>
- <div class={styles.items}>
- <div class={styles.item}>
- <Note fill="#01C1B5" />
- <span>绿色音符:演奏正确</span>
- </div>
- <div class={styles.item}>
- <Note fill="#FF4444" />
- <span>红色音符:错音</span>
- </div>
- <div class={styles.item}>
- <Note fill="#CC75FF" />
- <span>紫色音符:完成度不足</span>
- </div>
- <div class={styles.item}>
- <Note fill="#AEAEAE" />
- <span>灰色音符:未演奏</span>
- </div>
- <div class={styles.item}>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FF4444" shadow x={0.5} y={-1} />
- <span>音符重影(红色在前):节奏过快</span>
- </div>
- <div class={styles.item}>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FF4444" shadow x={-3} y={-2.5} />
- <span>音符重影(红色在后):节奏慢了</span>
- </div>
- <div class={styles.item}>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FFAB25" shadow x={-2} y={0} />
- <span>音符重影(黄色在上):音高了</span>
- </div>
- <div class={styles.item}>
- <Note fill="rgba(1, 193, 181, .8)" shadowFill="#FFAB25" shadow x={-1} y={-3} />
- <span>音符重影(黄色在下):音低了</span>
- </div>
- </div>
- </div>
- </Popup>
- </div>
- );
- },
- });
|