liushengqiang vor 2 Jahren
Ursprung
Commit
90b069d839
53 geänderte Dateien mit 658 neuen und 18 gelöschten Zeilen
  1. BIN
      public/soundfonts/pan-flute/A4.mp3
  2. BIN
      public/soundfonts/pan-flute/A5.mp3
  3. BIN
      public/soundfonts/pan-flute/A6.mp3
  4. BIN
      public/soundfonts/pan-flute/B4.mp3
  5. BIN
      public/soundfonts/pan-flute/B5.mp3
  6. BIN
      public/soundfonts/pan-flute/B6.mp3
  7. BIN
      public/soundfonts/pan-flute/C5.mp3
  8. BIN
      public/soundfonts/pan-flute/C6.mp3
  9. BIN
      public/soundfonts/pan-flute/C7.mp3
  10. BIN
      public/soundfonts/pan-flute/D5.mp3
  11. BIN
      public/soundfonts/pan-flute/D6.mp3
  12. BIN
      public/soundfonts/pan-flute/D7.mp3
  13. BIN
      public/soundfonts/pan-flute/E5.mp3
  14. BIN
      public/soundfonts/pan-flute/E6.mp3
  15. BIN
      public/soundfonts/pan-flute/E7.mp3
  16. BIN
      public/soundfonts/pan-flute/F5.mp3
  17. BIN
      public/soundfonts/pan-flute/F6.mp3
  18. BIN
      public/soundfonts/pan-flute/F7.mp3
  19. BIN
      public/soundfonts/pan-flute/G4.mp3
  20. BIN
      public/soundfonts/pan-flute/G5.mp3
  21. BIN
      public/soundfonts/pan-flute/G6.mp3
  22. 13 0
      src/helpers/communication.ts
  23. 10 5
      src/page-instrument/router.ts
  24. 32 2
      src/page-instrument/view-detail/index.tsx
  25. 1 0
      src/page-instrument/view-figner/image/icons.json
  26. 224 0
      src/page-instrument/view-figner/index.module.less
  27. 178 0
      src/page-instrument/view-figner/index.tsx
  28. 178 0
      src/view/figner-preview/index.ts
  29. 9 8
      src/view/fingering/fingering-config.ts
  30. BIN
      src/view/fingering/fingering-img/pan-flute/1.png
  31. BIN
      src/view/fingering/fingering-img/pan-flute/10.png
  32. BIN
      src/view/fingering/fingering-img/pan-flute/11.png
  33. BIN
      src/view/fingering/fingering-img/pan-flute/12.png
  34. BIN
      src/view/fingering/fingering-img/pan-flute/13.png
  35. BIN
      src/view/fingering/fingering-img/pan-flute/14.png
  36. BIN
      src/view/fingering/fingering-img/pan-flute/15.png
  37. BIN
      src/view/fingering/fingering-img/pan-flute/16.png
  38. BIN
      src/view/fingering/fingering-img/pan-flute/17.png
  39. BIN
      src/view/fingering/fingering-img/pan-flute/18.png
  40. BIN
      src/view/fingering/fingering-img/pan-flute/19.png
  41. BIN
      src/view/fingering/fingering-img/pan-flute/2.png
  42. BIN
      src/view/fingering/fingering-img/pan-flute/20.png
  43. BIN
      src/view/fingering/fingering-img/pan-flute/21.png
  44. BIN
      src/view/fingering/fingering-img/pan-flute/3.png
  45. BIN
      src/view/fingering/fingering-img/pan-flute/4.png
  46. BIN
      src/view/fingering/fingering-img/pan-flute/5.png
  47. BIN
      src/view/fingering/fingering-img/pan-flute/6.png
  48. BIN
      src/view/fingering/fingering-img/pan-flute/7.png
  49. BIN
      src/view/fingering/fingering-img/pan-flute/8.png
  50. BIN
      src/view/fingering/fingering-img/pan-flute/9.png
  51. BIN
      src/view/fingering/fingering-img/pan-flute/full.png
  52. 0 0
      src/view/fingering/fingering-img/pan-flute/index.json
  53. 13 3
      src/view/fingering/index.tsx

BIN
public/soundfonts/pan-flute/A4.mp3


BIN
public/soundfonts/pan-flute/A5.mp3


BIN
public/soundfonts/pan-flute/A6.mp3


BIN
public/soundfonts/pan-flute/B4.mp3


BIN
public/soundfonts/pan-flute/B5.mp3


BIN
public/soundfonts/pan-flute/B6.mp3


BIN
public/soundfonts/pan-flute/C5.mp3


BIN
public/soundfonts/pan-flute/C6.mp3


BIN
public/soundfonts/pan-flute/C7.mp3


BIN
public/soundfonts/pan-flute/D5.mp3


BIN
public/soundfonts/pan-flute/D6.mp3


BIN
public/soundfonts/pan-flute/D7.mp3


BIN
public/soundfonts/pan-flute/E5.mp3


BIN
public/soundfonts/pan-flute/E6.mp3


BIN
public/soundfonts/pan-flute/E7.mp3


BIN
public/soundfonts/pan-flute/F5.mp3


BIN
public/soundfonts/pan-flute/F6.mp3


BIN
public/soundfonts/pan-flute/F7.mp3


BIN
public/soundfonts/pan-flute/G4.mp3


BIN
public/soundfonts/pan-flute/G5.mp3


BIN
public/soundfonts/pan-flute/G6.mp3


+ 13 - 0
src/helpers/communication.ts

@@ -259,6 +259,18 @@ export const api_keepScreenLongLight = () => {
 		},
 	});
 };
+/** 设置横竖屏
+ * 0:横屏
+ * 1:竖屏
+ */
+export const api_setRequestedOrientation = (orientation: number) => {
+	postMessage({
+		api: "setRequestedOrientation",
+		content: {
+			orientation,
+		},
+	});
+};
 
 /** 监听APP播放 */
 export const api_playProgress = (callback: any) => {
@@ -268,3 +280,4 @@ export const api_playProgress = (callback: any) => {
 export const api_remove_playProgress = (callback: any) => {
 	removeListenerMessage("playProgress", callback);
 };
+

+ 10 - 5
src/page-instrument/router.ts

@@ -16,20 +16,25 @@ const routes: RouteRecordRaw[] = [
 		component: () => import("./view-evaluat-report/index"),
 	},
 	{
+		path: "/preview",
+		component: () => import("./view-preview/index"),
+	},
+	{
+		path: "/view-figner",
+		component: () => import("./view-figner/index"),
+	},
+	{
 		path: "/:pathMatch(.*)*",
 		component: Notfind,
 		meta: {
 			title: "404 Not Fund",
 		},
 	},
-	{
-		path: "/preview",
-		component: () => import("./view-preview/index"),
-	},
+	
 ];
 
 const router = createRouter({
-	history: createWebHashHistory(),
+	history: createWebHashHistory('/notation/'),
 	routes,
 });
 

+ 32 - 2
src/page-instrument/view-detail/index.tsx

@@ -1,4 +1,4 @@
-import { Skeleton } from "vant";
+import { Popup, Skeleton } from "vant";
 import {
 	computed,
 	defineComponent,
@@ -33,7 +33,9 @@ import {
 	api_cloudLoading,
 	api_keepScreenLongLight,
 	api_openCamera,
+	api_openWebView,
 	api_setEventTracking,
+	api_setRequestedOrientation,
 	api_setStatusBarVisibility,
 	isSpecialShapedScreen,
 } from "/src/helpers/communication";
@@ -50,6 +52,7 @@ import RecordingTime from "../custom-plugins/recording-time";
 import WorkIndex from "../custom-plugins/work-index";
 import TheMusicList from "../component/the-music-list";
 import { storeData } from "/src/store";
+import ViewFigner from "../view-figner";
 
 /** 需要处理频率的乐器
  * 120: 竖笛
@@ -75,6 +78,8 @@ export default defineComponent({
 			skeletonLoading: true,
 			paddingLeft: "",
 			headerHide: false,
+			fingerPreView: false,
+			orientation: 0,
 		});
 		const getAPPData = async () => {
 			const screenData = await isSpecialShapedScreen();
@@ -307,6 +312,27 @@ export default defineComponent({
 			window.removeEventListener("resize", resetMusicScore);
 		});
 		const browsInfo = browser();
+		const handleOpenFignerView = () => {
+			detailData.orientation = state.fingeringInfo.orientation || 0;
+			api_setRequestedOrientation(detailData.orientation);
+			// const url = `${
+			// 	/(192|localhost)/.test(location.origin)
+			// 		? "http://192.168.3.114:3000/instrument.html"
+			// 		: location.origin + location.pathname
+			// }#/view-figner`;
+			// console.log("🚀 ~ url:", url);
+			// api_openWebView({
+			// 	url: url,
+			// 	orientation: state.fingeringInfo.orientation || 0,
+			// });
+			detailData.fingerPreView = true;
+		};
+		const handleCloseFignerView = () => {
+			if (detailData.orientation == 1) {
+				api_setRequestedOrientation(0);
+			}
+			detailData.fingerPreView = false;
+		};
 		return () => (
 			<div
 				class={[
@@ -349,7 +375,7 @@ export default defineComponent({
 					{/* 指法 */}
 					{state.setting.displayFingering && state.fingeringInfo?.name && (
 						<div style={{ ...fingerConfig.value.fingerBox }}>
-							<Fingering />
+							<Fingering onOpen={() => handleOpenFignerView()} />
 						</div>
 					)}
 				</div>
@@ -393,6 +419,10 @@ export default defineComponent({
 						)}
 					</>
 				)}
+
+				<Popup teleport="body" v-model:show={detailData.fingerPreView} position="bottom">
+					<ViewFigner subject={state.fingeringInfo.name} isComponent={true} onClose={handleCloseFignerView} />
+				</Popup>
 			</div>
 		);
 	},

Datei-Diff unterdrückt, da er zu groß ist
+ 1 - 0
src/page-instrument/view-figner/image/icons.json


+ 224 - 0
src/page-instrument/view-figner/index.module.less

@@ -0,0 +1,224 @@
+.fingerBox {
+    position: relative;
+    display: flex;
+    flex-direction: column;
+    width: 100vw;
+    height: 100vh;
+    background-color: antiquewhite;
+}
+
+.head {
+    position: relative;
+    width: 100%;
+
+    .backBtn {
+        width: 22px;
+        height: 22px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        border: none;
+        background: none;
+
+        img {
+            width: 100%;
+            height: 100%;
+        }
+
+        &::after {
+            content: '';
+            position: absolute;
+            top: 0;
+            left: 0;
+            right: 0;
+            width: 100%;
+            height: 140%;
+            z-index: 10;
+        }
+        &.backRight{
+            &::after{
+                right: 85px;
+                width: auto;
+            }
+        }
+    }
+
+    .left {
+        position: absolute;
+        top: 0;
+        left: 0;
+        padding-left: 33px;
+        padding-top: 25px;
+        display: flex;
+        align-items: center;
+
+        button {
+            margin-right: 30px;
+        }
+    }
+
+    .baseBtn {
+        width: 85px;
+        height: 33px;
+        background: linear-gradient(180deg, #FEF0AF 0%, #F7D656 100%);
+        box-shadow: 0px 2px 1px 0px rgba(168, 121, 0, 0.24), inset 0px 1px 3px 0px rgba(255, 255, 255, 0.5), inset 0px -2px 1px 0px rgba(255, 255, 255, 0.5);
+        border-radius: 9px;
+        font-size: 13px;
+        font-weight: 600;
+        color: #A14927;
+        line-height: 33px;
+        text-align: center;
+
+        &:active {
+            transform: translateY(2px);
+        }
+    }
+
+    .rightBtn {
+        position: absolute;
+        right: 23px;
+        top: 20px;
+        display: flex;
+        align-items: center;
+        justify-content: space-evenly;
+        width: 100px;
+        height: 44px;
+        background: linear-gradient(180deg, #FEF0AF 0%, #F7D656 100%);
+        box-shadow: 0px 2px 1px 0px rgba(168, 121, 0, 0.24), inset 0px 1px 3px 0px rgba(255, 255, 255, 0.5), inset 0px -2px 1px 0px rgba(255, 255, 255, 0.5);
+        border-radius: 11px;
+        font-weight: 600;
+        color: #A14927;
+
+        .item {
+            flex: 1;
+            display: flex;
+            flex-direction: column;
+            justify-content: center;
+            align-items: center;
+
+            &:first-child {
+                border-right: 1Px solid #a149275e;
+            }
+
+            img {
+                width: 13px;
+                height: 13px;
+            }
+        }
+    }
+}
+
+.fingerContent {
+    flex: 1;
+    overflow: hidden;
+}
+
+.notes {
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
+    height: 65px;
+
+    .noteBox {
+        max-width: calc(100% - 92px);
+        display: flex;
+        background: rgba(255, 255, 255, 0.53);
+        border-radius: 25px;
+        border: 1px solid rgba(255, 255, 255, 0.81);
+        overflow-y: hidden;
+        overflow-x: auto;
+    }
+
+    .note {
+        position: relative;
+        margin: 0 2.5Px;
+        width: 42px;
+        height: 42px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        flex-shrink: 0;
+        padding: 6px;
+
+        img {
+            position: absolute;
+            left: 0;
+            top: 0;
+            width: 100%;
+            height: 100%;
+        }
+
+        .noteKey {
+            position: relative;
+            display: flex;
+            flex-direction: column;
+            justify-content: space-evenly;
+            align-items: center;
+            z-index: 1;
+            font-size: 16px;
+            font-family: GJJSZJW--GB1-0, GJJSZJW--GB1;
+            font-weight: normal;
+            color: #FFFFFF;
+            text-shadow: 0px 1px 3px #1EADF1;
+            line-height: 1;
+            height: 100%;
+
+            .dot {
+                width: 3px;
+                height: 3px;
+                border-radius: 50%;
+                background-color: #fff;
+            }
+        }
+    }
+}
+
+.fingeringContainer {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: space-evenly;
+    align-items: center;
+    padding: 0 10px 6px 10px;
+}
+
+
+.imgs {
+    position: relative;
+    width: 84%;
+    height: 100%;
+
+    &>img {
+        position: absolute;
+        left: 50%;
+        top: 50%;
+        transform: translate(-50%, -50%);
+        display: block;
+        max-width: 100%;
+        max-height: 100%;
+    }
+}
+
+.tizhi {
+    position: absolute;
+    width: 30px;
+    height: 30px;
+    text-align: center;
+    line-height: 30px;
+    border-radius: 100%;
+    background-color: var(--van-primary-color);
+    color: #fff;
+    box-shadow: 0 0 10px rgba(0, 0, 0, .05);
+    font-size: 12Px;
+    opacity: 0;
+    pointer-events: none;
+
+    &:active {
+        opacity: .8;
+    }
+}
+
+.canDisplay {
+    opacity: 1;
+    pointer-events: auto;
+}

+ 178 - 0
src/page-instrument/view-figner/index.tsx

@@ -0,0 +1,178 @@
+import { PropType, computed, defineComponent, onBeforeMount, reactive } from "vue";
+import styles from "./index.module.less";
+import icons from "./image/icons.json";
+import { FIGNER_INSTRUMENT_DATA, IFIGNER_INSTRUMENT_Note } from "/src/view/figner-preview";
+import {
+	ITypeFingering,
+	IVocals,
+	getFingeringConfig,
+	subjectFingering,
+} from "/src/view/fingering/fingering-config";
+import { Howl } from "howler";
+import { storeData } from "/src/store";
+import { api_back } from "/src/helpers/communication";
+
+export default defineComponent({
+	name: "viewFigner",
+	emits: ["close"],
+	props: {
+		isComponent: {
+			type: Boolean,
+			default: false,
+		},
+        subject:{
+            type: String as PropType<IVocals>,
+            default: ""
+        }
+	},
+	setup(props, { emit }) {
+        const subject = props.subject || "pan-flute"
+		const data = reactive({
+			subject: subject,
+			realKey: 0,
+			notes: [] as IFIGNER_INSTRUMENT_Note[],
+			soundFonts: {} as any,
+		});
+		const fingerData = reactive({
+			relationshipIndex: 0,
+			subject: null as unknown as ITypeFingering,
+			fingeringInfo: subjectFingering(data.subject),
+		});
+		const getNotes = () => {
+			const fignerData = FIGNER_INSTRUMENT_DATA[data.subject as keyof typeof FIGNER_INSTRUMENT_DATA];
+			if (fignerData) {
+				data.notes = fignerData.list;
+			}
+		};
+		const getFingeringData = async () => {
+			fingerData.subject = await getFingeringConfig(data.subject);
+		};
+		const getSounFonts = () => {
+			for (let i = 0; i < data.notes.length; i++) {
+				const note = data.notes[i];
+				// console.log("🚀 ~ note:", note)
+				// console.log(`/soundfonts/${data.subject}/${note.name}${note.octave}.mp3`)
+				const noteAudio = new Howl({
+					src: `/soundfonts/${data.subject}/${note.name}${note.octave}.mp3`,
+					loop: true,
+				});
+				data.soundFonts[note.realKey] = noteAudio;
+			}
+			// console.log("🚀 ~ data.soundFonts:", data.soundFonts);
+		};
+		onBeforeMount(() => {
+			getNotes();
+			getFingeringData();
+			getSounFonts();
+		});
+
+		const noteClick = (item: IFIGNER_INSTRUMENT_Note, type: "start" | "stop") => {
+			// console.log("🚀 ~ item:", item);
+			const noteAudio = data.soundFonts[item.realKey];
+			if (type === "start") {
+				data.realKey = item.realKey;
+				if (noteAudio) {
+					noteAudio.play();
+				}
+			} else {
+				data.realKey = 0;
+				if (noteAudio) {
+					noteAudio.stop();
+				}
+			}
+		};
+
+		/** 返回 */
+		const handleBack = () => {
+			if (props.isComponent) {
+				console.log("关闭");
+				emit("close");
+				return;
+			}
+			// 不在APP中,
+			if (!storeData.isApp) {
+				window.close();
+				return;
+			}
+			api_back();
+		};
+
+		return () => {
+			const relationship = fingerData.subject?.relationship?.[data.realKey] || [];
+			const rs: number[] = Array.isArray(relationship[1])
+				? relationship[fingerData.relationshipIndex]
+				: relationship;
+			const canTizhi = Array.isArray(relationship[1]);
+			return (
+				<div class={styles.fingerBox}>
+					<div class={styles.head}>
+						<div class={styles.left}>
+							<button class={[styles.backBtn, data.subject === 'pan-flute' && styles.backRight]} onClick={() => handleBack()}>
+								<img src={icons.icon_back} />
+							</button>
+							{data.subject === 'pan-flute' && <div class={styles.baseBtn}>切换视图</div>}
+						</div>
+						<div class={styles.rightBtn}>
+							<div class={styles.item}>
+								<img src={icons.icon_2_0} />
+								<span>还原</span>
+							</div>
+							<div class={styles.item}>
+								<img src={icons.icon_2_1} />
+								<span>小技巧</span>
+							</div>
+						</div>
+					</div>
+					<div class={styles.fingerContent}>
+						<div class={[styles.fingeringContainer]}>
+							<div class={styles.imgs}>
+								<img src={fingerData.subject?.json?.full} />
+								{rs.map((key: number | string, index: number) => {
+									const nk: string = typeof key === "string" ? key.replace("active-", "") : String(key);
+									return <img data-index={nk} src={fingerData.subject?.json?.[nk]} />;
+								})}
+							</div>
+
+							<div
+								class={[styles.tizhi, canTizhi && styles.canDisplay]}
+								onClick={() =>
+									(fingerData.relationshipIndex = fingerData.relationshipIndex === 0 ? 1 : 0)
+								}
+							>
+								替指
+							</div>
+						</div>
+					</div>
+					<div class={styles.notes}>
+						<div class={styles.noteBox}>
+							{data.notes.map((note: IFIGNER_INSTRUMENT_Note) => {
+								const steps = new Array(Math.abs(note.step)).fill(1);
+								return (
+									<div
+										class={styles.note}
+										onKeydown={() => noteClick(note, "start")}
+										onKeyup={() => noteClick(note, "start")}
+										onTouchstart={() => noteClick(note, "start")}
+										onTouchend={() => noteClick(note, "stop")}
+									>
+										{data.realKey === note.realKey ? (
+											<img src={icons.icon_btn_ylow} />
+										) : (
+											<img src={icons.icon_btn_blue} />
+										)}
+
+										<div class={styles.noteKey}>
+											{note.step > 0 ? steps.map((n) => <span class={styles.dot}></span>) : null}
+											<span>{note.key}</span>
+											{note.step < 0 ? steps.map((n) => <span class={styles.dot}></span>) : null}
+										</div>
+									</div>
+								);
+							})}
+						</div>
+					</div>
+				</div>
+			);
+		};
+	},
+});

+ 178 - 0
src/view/figner-preview/index.ts

@@ -0,0 +1,178 @@
+export interface IFIGNER_INSTRUMENT_Note {
+	key: number;
+	name: string;
+	octave: number;
+	step: number;
+	realKey: number;
+}
+interface IFIGNER_INSTRUMENT_DATA {
+	list: IFIGNER_INSTRUMENT_Note[];
+	[_: string]: IFIGNER_INSTRUMENT_Note[]
+}
+export const FIGNER_INSTRUMENT_DATA: { [_: string]: IFIGNER_INSTRUMENT_DATA } = {
+	"pan-flute": {
+		list: [
+			{
+				key: 5,
+				name: "G",
+				octave: 4,
+				step: -1,
+				realKey: 55,
+			},
+			{
+				key: 6,
+				name: "A",
+				octave: 4,
+				step: -1,
+				realKey: 57,
+			},
+			{
+				key: 7,
+				name: "B",
+				octave: 4,
+				step: -1,
+				realKey: 59,
+			},
+			{
+				key: 1,
+				name: "C",
+				octave: 5,
+				step: 0,
+				realKey: 60,
+			},
+			{
+				key: 2,
+				name: "D",
+				octave: 5,
+				step: 0,
+				realKey: 62,
+			},
+			{
+				key: 3,
+				name: "E",
+				octave: 5,
+				step: 0,
+				realKey: 64,
+			},
+			{
+				key: 4,
+				name: "F",
+				octave: 5,
+				step: 0,
+				realKey: 65,
+			},
+			{
+				key: 5,
+				name: "G",
+				octave: 5,
+				step: 0,
+				realKey: 67,
+			},
+			{
+				key: 6,
+				name: "A",
+				octave: 5,
+				step: 0,
+				realKey: 69,
+			},
+			{
+				key: 7,
+				name: "B",
+				octave: 5,
+				step: 0,
+				realKey: 71,
+			},
+			{
+				key: 1,
+				name: "C",
+				octave: 6,
+				step: 1,
+				realKey: 72,
+			},
+			{
+				key: 2,
+				name: "D",
+				octave: 6,
+				step: 1,
+				realKey: 74,
+			},
+			{
+				key: 3,
+				name: "E",
+				octave: 6,
+				step: 1,
+				realKey: 76,
+			},
+			{
+				key: 4,
+				name: "F",
+				octave: 6,
+				step: 1,
+				realKey: 77,
+			},
+			{
+				key: 5,
+				name: "G",
+				octave: 6,
+				step: 1,
+				realKey: 79,
+			},
+			{
+				key: 6,
+				name: "A",
+				octave: 6,
+				step: 1,
+				realKey: 81,
+			},
+			{
+				key: 7,
+				name: "B",
+				octave: 6,
+				step: 1,
+				realKey: 83,
+			},
+			{
+				key: 1,
+				name: "C",
+				octave: 7,
+				step: 2,
+				realKey: 84,
+			},
+			{
+				key: 2,
+				name: "D",
+				octave: 7,
+				step: 2,
+				realKey: 86,
+			},
+			{
+				key: 3,
+				name: "E",
+				octave: 7,
+				step: 2,
+				realKey: 88,
+			},
+			{
+				key: 4,
+				name: "F",
+				octave: 7,
+				step: 2,
+				realKey: 89,
+			},
+		],
+	},
+	"hulusi-flute":{
+		list: [
+			{
+				key: 3,
+				name: "E",
+				octave: 4,
+				step: -1,
+				realKey: 55,
+			}
+		],
+		list1: [
+
+		]
+	}
+};

+ 9 - 8
src/view/fingering/fingering-config.ts

@@ -16,6 +16,8 @@ export type IFingering = {
 	height?: string;
 	/** 禁用替指 */
 	disabledFinger?: boolean;
+	/** 横竖屏 0:横屏 1: 竖屏 */
+	orientation?: number;
 };
 
 type ITypeContent = {
@@ -100,8 +102,8 @@ export const mappingVoicePart = (
 			Mouthorgan: 140,
 			Piano: 150,
 			4: 120,
-			// 3: "hulusi-flute",
-			// 1: "pan-flute",
+			3: "hulusi-flute",
+			1: "pan-flute",
 			// 2: "ocarina",
 			// 5: "melodica",
 			"Tenor Recorder": 120,
@@ -172,18 +174,14 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
 				name: "piccolo",
 				direction: "vertical",
 				width: "3rem",
+				orientation: 1
 			};
-		// case 23: // 打击乐
-		// 	return {
-		// 		name: "small-drum",
-		// 		direction: "transverse",
-		// 		height: "1.6rem",
-		// 	};
 		case "hulusi-flute": // 葫芦丝
 			return {
 				name: "hulusi-flute",
 				direction: "vertical",
 				width: "3rem",
+				orientation: 1
 			};
 		case "pan-flute": // 排箫
 			return {
@@ -191,6 +189,7 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
 				direction: "vertical",
 				width: "3rem",
 				disabledFinger: true,
+				orientation: 0
 			};
 		case "ocarina": // 陶笛
 			return {
@@ -198,12 +197,14 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
 				direction: "vertical",
 				width: "3rem",
 				disabledFinger: true,
+				orientation: 0
 			};
 		case "melodica": // 口风琴
 			return {
 				name: "melodica",
 				direction: "transverse",
 				height: "1.8rem",
+				orientation: 0
 			};
 		default:
 			return {};

BIN
src/view/fingering/fingering-img/pan-flute/1.png


BIN
src/view/fingering/fingering-img/pan-flute/10.png


BIN
src/view/fingering/fingering-img/pan-flute/11.png


BIN
src/view/fingering/fingering-img/pan-flute/12.png


BIN
src/view/fingering/fingering-img/pan-flute/13.png


BIN
src/view/fingering/fingering-img/pan-flute/14.png


BIN
src/view/fingering/fingering-img/pan-flute/15.png


BIN
src/view/fingering/fingering-img/pan-flute/16.png


BIN
src/view/fingering/fingering-img/pan-flute/17.png


BIN
src/view/fingering/fingering-img/pan-flute/18.png


BIN
src/view/fingering/fingering-img/pan-flute/19.png


BIN
src/view/fingering/fingering-img/pan-flute/2.png


BIN
src/view/fingering/fingering-img/pan-flute/20.png


BIN
src/view/fingering/fingering-img/pan-flute/21.png


BIN
src/view/fingering/fingering-img/pan-flute/3.png


BIN
src/view/fingering/fingering-img/pan-flute/4.png


BIN
src/view/fingering/fingering-img/pan-flute/5.png


BIN
src/view/fingering/fingering-img/pan-flute/6.png


BIN
src/view/fingering/fingering-img/pan-flute/7.png


BIN
src/view/fingering/fingering-img/pan-flute/8.png


BIN
src/view/fingering/fingering-img/pan-flute/9.png


BIN
src/view/fingering/fingering-img/pan-flute/full.png


Datei-Diff unterdrückt, da er zu groß ist
+ 0 - 0
src/view/fingering/fingering-img/pan-flute/index.json


+ 13 - 3
src/view/fingering/index.tsx

@@ -5,10 +5,12 @@ import { getFingeringConfig, ITypeFingering } from "./fingering-config";
 
 export default defineComponent({
 	name: "fingering",
-	setup(props, { expose }) {
+	emits: ['open'],
+	setup(props, { emit }) {
 		const fingerData = reactive({
 			relationshipIndex: 0,
 			subject: null as unknown as ITypeFingering,
+			delay: 0
 		});
 		const getFingeringData = async () => {
 			fingerData.subject = await getFingeringConfig(state.fingeringInfo.name);
@@ -22,6 +24,14 @@ export default defineComponent({
 			return state.times[state.activeNoteIndex]?.realKey || -1;
 		});
 
+		const doubeClick = () => {
+			const nowTime = Date.now();
+			if (nowTime - fingerData.delay < 300) {
+				emit('open')
+				return;
+			}
+			fingerData.delay = nowTime;
+		}
 		return () => {
 			const relationship = fingerData.subject?.relationship?.[realKey.value] || [];
 			const rs: number[] = Array.isArray(relationship[1])
@@ -31,7 +41,7 @@ export default defineComponent({
 			return (
 				<>
 					{state.fingeringInfo.direction === "transverse" ? (
-						<div class={[styles.fingeringContainer]}>
+						<div onClick={() => doubeClick()} class={[styles.fingeringContainer]}>
 							<span class={[styles.yidiao, rs.includes(0) && styles.canDisplay]}>转调</span>
 
 							<div class={styles.imgs}>
@@ -52,7 +62,7 @@ export default defineComponent({
 							</div>
 						</div>
 					) : (
-						<div class={[styles.fingeringContainer, styles.vertical, state.fingeringInfo.name]}>
+						<div onClick={() => doubeClick()} class={[styles.fingeringContainer, styles.vertical, state.fingeringInfo.name]}>
 							<div class={styles.imgs}>
 								<img src={fingerData.subject?.json?.full} />
 								{rs.map((key: number | string, index: number) => {

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.