liushengqiang 2 anni fa
parent
commit
8c57a68ed9

+ 2 - 0
src/page-instrument/component/mode-type-mode/index.tsx

@@ -9,6 +9,7 @@ import TheVip from "../../custom-plugins/the-vip";
 import { storeData } from "/src/store";
 import { studentQueryUserInfo } from "../../api";
 import { usePageVisibility } from "@vant/use";
+import GuideIndex from "../../view-figner/guide/guide-index";
 export default defineComponent({
 	name: "modelWraper",
 
@@ -91,6 +92,7 @@ export default defineComponent({
 					{data.showPC && headTopData.modeType === "init" ? <TeacherBootom></TeacherBootom> : null}
 					{data.showStudent && headTopData.modeType === "init" ? <StudentBottom></StudentBottom> : null}
 					{data.showVip && headTopData.modeType === "init" && <TheVip />}
+					{headTopData.modeType === 'show' && state.modeType !== 'evaluating' && <GuideIndex list={['detail']} />}
 				</div>
 			</>
 		);

+ 22 - 0
src/page-instrument/view-figner/guide/detail-guide.tsx

@@ -0,0 +1,22 @@
+import { defineComponent, onMounted, ref } from "vue";
+import styles from "./index.module.less";
+import { Icon } from "vant";
+
+export default defineComponent({
+	name: "DetailGuide",
+	emits: ["close"],
+	setup(props, { emit }) {
+		const detailRef = ref();
+		onMounted(() => {
+			document.body.appendChild(detailRef.value);
+		});
+		return () => (
+			<div ref={detailRef} class={styles.detail}>
+				<div class={styles.btn} onClick={() => emit("close", true)}>
+					不再提醒
+				</div>
+				<Icon class={styles.close} name="cross" onClick={() => emit("close")} />
+			</div>
+		);
+	},
+});

+ 100 - 0
src/page-instrument/view-figner/guide/finger-guide.tsx

@@ -0,0 +1,100 @@
+import { defineComponent, onMounted, reactive, ref } from "vue";
+import styles from "./index.module.less";
+import { Button, Icon, Popup } from "vant";
+import icons from "./image/icons.json";
+import state from "/src/state";
+
+export default defineComponent({
+	name: "DetailGuide",
+	emits: ["close"],
+	setup(props, { emit }) {
+		const data = reactive({
+			box: {},
+			show: true,
+			steps: [
+				{
+					className: "boxItem1",
+					des: `快点击下排按钮听听${state.fingeringInfo.code}的声音吧,按钮可以滑动哦~`,
+					img: icons.icon_cursor_1,
+				},
+				{
+					className: "boxItem2",
+					des: "这里可以切换音调,查看不同音调的指法~",
+					img: icons.icon_cursor_2,
+				},
+				{
+					className: "boxItem3",
+					des: "可以通过手势放大缩小乐器哦~",
+					img: icons.icon_cursor_3,
+				},
+			],
+			step: 0,
+		});
+		const steps = ["finger-note-0", "finger-note-1", "finger-note-2"];
+		const getStepELe = () => {
+			const ele: HTMLElement = document.getElementById(steps[data.step])!;
+			console.log(data.step, ele);
+			if (ele) {
+				const eleRect = ele.getBoundingClientRect();
+				const increment = data.step === 2 ? eleRect.width : 0;
+				data.box = {
+					left: eleRect.x - increment + "px",
+					top: eleRect.y + "px",
+					width: (data.step === 2 ? 0 : eleRect.width) + "px",
+					height: (data.step === 2 ? 0 : eleRect.height) + "px",
+				};
+			}
+		};
+		onMounted(() => {
+			getStepELe();
+		});
+
+		const handleNext = () => {
+			if (data.step >= 2) {
+				endGuide();
+				return;
+			}
+			data.step = data.step + 1;
+			getStepELe();
+		};
+
+		const endGuide = () => {
+            emit('close', true)
+		};
+		return () => (
+			<Popup
+				teleport="body"
+				overlay={false}
+				closeOnClickOverlay={false}
+				class={["popup-custom", styles.fingerGuide]}
+				v-model:show={data.show}
+			>
+				<div class={styles.content} onClick={() => handleNext()}>
+					<div class={styles.box} style={data.box}>
+						{data.steps.map((item, index) => (
+							<div style={{ display: index === data.step ? "" : "none" }} class={styles[item.className]}>
+								<img src={item.img} />
+							</div>
+						))}
+					</div>
+					<div onClick={(e: Event) => e.stopPropagation()}>
+						{data.steps.map((item, index) => (
+							<div style={{ display: index === data.step ? "" : "none" }} class={styles.item}>
+								<div class={styles.title}>
+									<img src={icons.guide_2} />
+									<div class={styles.des}>{item.des}</div>
+								</div>
+								<div class={styles.icon}>
+									<img src={icons.guide_1} />
+								</div>
+								<Button class={styles.btn} round type="primary" onClick={() => handleNext()}>
+									我知道了
+								</Button>
+							</div>
+						))}
+					</div>
+				</div>
+			</Popup>
+		);
+	},
+});

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

@@ -0,0 +1,60 @@
+import { PropType, defineComponent, onMounted, reactive } from "vue";
+import DetailGuide from "./detail-guide";
+import FingerGuide from "./finger-guide";
+
+type guideType = "detail" | "finger";
+export default defineComponent({
+	name: "guide-index",
+	props: {
+		list: {
+			type: Array as PropType<guideType[]>,
+			default: "",
+		},
+	},
+	setup(props) {
+		const detailGuideKey = "detailGuideKey";
+		const fingerGuideKey = "fingerGuideKey";
+		const data = reactive({
+			list: props.list,
+			detailShow: false,
+			fingerShow: false,
+		});
+		const init = () => {
+			if (data.list.includes("detail")) {
+				if (localStorage.getItem(detailGuideKey)) return;
+				data.detailShow = true;
+			}
+			if (data.list.includes("finger")) {
+				if (localStorage.getItem(fingerGuideKey)) return;
+				data.fingerShow = true;
+			}
+		};
+		onMounted(() => {
+			init();
+		});
+		return () => (
+			<>
+				{data.detailShow && (
+					<DetailGuide
+						onClose={(val) => {
+							if (val) {
+								localStorage.setItem(detailGuideKey, "1");
+							}
+							data.detailShow = false;
+						}}
+					/>
+				)}
+				{data.fingerShow && (
+					<FingerGuide
+						onClose={(val) => {
+							if (val) {
+								localStorage.setItem(fingerGuideKey, "1");
+							}
+							data.fingerShow = false;
+						}}
+					/>
+				)}
+			</>
+		);
+	},
+});

BIN
src/page-instrument/view-figner/guide/image/icon_detail.png


File diff suppressed because it is too large
+ 1 - 0
src/page-instrument/view-figner/guide/image/icons.json


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

@@ -0,0 +1,128 @@
+.detail {
+    position: fixed;
+    left: 50%;
+    bottom: 90px;
+    transform: translateX(-50%);
+    width: 357px;
+    height: 47px;
+    background: url('./image/icon_detail.png') no-repeat;
+    background-size: 100%;
+    display: flex;
+    justify-content: flex-end;
+    padding: 14px 10px 0 0;
+
+    .btn {
+        width: 55px;
+        height: 22px;
+        background: linear-gradient(180deg, #44C9FF 0%, #259CFE 100%);
+        border-radius: 12px;
+        color: #FFFFFF;
+        font-size: 11px;
+        line-height: 22px;
+        text-align: center;
+    }
+
+    .close {
+        color: #fff;
+        font-size: 14px;
+        padding: 0 8px;
+        padding-top: 6px;
+    }
+}
+
+.fingerGuide {
+    width: 100%;
+    height: 100%;
+
+    .content {
+        width: 100%;
+        height: 100%;
+    }
+
+    .box {
+        position: fixed;
+        box-shadow: rgba(33, 33, 33, 0.8) 0px 0px 0px 5000px;
+        transition: all 0.25s;
+        border-radius: 8px;
+    }
+    .boxItem1{
+        position: absolute;
+        left: -16px;
+        top: -55px;
+        img{
+            width: 94px;
+        }
+    }
+    .boxItem2{
+        position: absolute;
+        left: -12px;
+        top: -40px;
+        img{
+            width: 42px;
+        }
+    }
+    .boxItem3{
+        position: absolute;
+        left: -120px;
+        top: 0;
+        img{
+            width: 83px;
+        }
+    }
+
+    .item {
+        position: absolute;
+        right: 50px;
+        bottom: 0;
+
+        .title {
+            width: 182px;
+
+            img {
+                width: 100%;
+                display: block;
+            }
+
+            .des {
+                position: absolute;
+                left: 0;
+                top: 0;
+                padding: 8px 0 0 8px;
+                font-size: 12px;
+                color: #FFFFFF;
+                line-height: 19px;
+            }
+        }
+
+        .icon {
+            width: 88px;
+            height: 99px;
+            margin-left: auto;
+            margin-right: -39px;
+            margin-top: -17px;
+
+            img {
+                width: 100%;
+                height: 100%;
+                object-fit: contain;
+                display: block;
+            }
+        }
+
+        .btn {
+            position: absolute;
+            left: 0;
+            bottom: 45px;
+            width: 83px;
+            height: 27px;
+            line-height: 27px;
+            background: linear-gradient(180deg, #FFF385 0%, #FFC036 100%);
+            border-radius: 13px;
+            border: 1px solid #FFF9DA;
+            font-size: 13px;
+            font-weight: 500;
+            color: #131415;
+            padding: 0;
+        }
+    }
+}

+ 11 - 3
src/page-instrument/view-figner/index.tsx

@@ -13,6 +13,7 @@ import { storeData } from "/src/store";
 import { api_back } from "/src/helpers/communication";
 import Hammer from "hammerjs";
 import { Button, Icon, Popup, Space } from "vant";
+import GuideIndex from "./guide/guide-index";
 
 export default defineComponent({
 	name: "viewFigner",
@@ -30,6 +31,7 @@ export default defineComponent({
 	setup(props, { emit }) {
 		const subject = props.subject || "pan-flute";
 		const data = reactive({
+			loading: true,
 			subject: subject,
 			realKey: 0,
 			notes: [] as IFIGNER_INSTRUMENT_Note[],
@@ -67,6 +69,9 @@ export default defineComponent({
 				}
 				data.tips = fignerData.tips || [];
 				setNotes();
+				setTimeout(() => {
+					data.loading = false;
+				}, 600)
 			}
 		};
 		const setNotes = () => {
@@ -257,6 +262,7 @@ export default defineComponent({
 									</div>
 
 									<div
+										id="finger-note-2"
 										class={[styles.tizhi, canTizhi && styles.canDisplay]}
 										onClick={() =>
 											(fingerData.relationshipIndex = fingerData.relationshipIndex === 0 ? 1 : 0)
@@ -272,10 +278,10 @@ export default defineComponent({
 						</Button> */}
 								<div class={styles.noteContent}>
 									<div class={styles.noteBox}>
-										{data.notes.map((note: IFIGNER_INSTRUMENT_Note) => {
+										{data.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => {
 											const steps = new Array(Math.abs(note.step)).fill(1);
 											return (
-												<div draggable={false} class={styles.note} onClick={() => noteClick(note)}>
+												<div id={index == 0 ? 'finger-note-0' : ''} draggable={false} class={styles.note} onClick={() => noteClick(note)}>
 													{data.realKey === note.realKey ? (
 														<img draggable={false} src={icons.icon_btn_ylow} />
 													) : (
@@ -324,7 +330,7 @@ export default defineComponent({
 							</div>
 						</div>
 					</div>
-					<div class={styles.toggleBtn} onClick={() => (data.tnoteShow = true)}>
+					<div id="finger-note-1" class={styles.toggleBtn} onClick={() => (data.tnoteShow = true)}>
 						<div>
 							<sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
 							{data.activeTone.name}
@@ -381,6 +387,8 @@ export default defineComponent({
 							</Space>
 						</div>
 					</Popup>
+
+					{!data.loading && <GuideIndex list={['finger']} />}
 				</div>
 			);
 		};

Some files were not shown because too many files changed in this diff