- {{ (props.accuracy * 100).toFixed(2) }} %
+
+ {{ info }}
-
- {{ props.speed.toFixed(2) }} 字每分
-
-
- {{ props.avgpress.toFixed(2) }} 次每字
+
{{ (accuracy * 100).toFixed(2) }} %
+
{{ speed.toFixed(2) }} 字每分
+
+ {{ avgpress.toFixed(2) }} 次每字
diff --git a/src/pages/KeyPositionPracticeMode.vue b/src/pages/KeyPositionPracticeMode.vue
new file mode 100644
index 0000000..786b047
--- /dev/null
+++ b/src/pages/KeyPositionPracticeMode.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/src/pages/KeyPositionPracticeModeLead.vue b/src/pages/KeyPositionPracticeModeLead.vue
new file mode 100644
index 0000000..9ef5329
--- /dev/null
+++ b/src/pages/KeyPositionPracticeModeLead.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/src/router.ts b/src/router.ts
index 9d74c20..d6777c6 100644
--- a/src/router.ts
+++ b/src/router.ts
@@ -2,6 +2,8 @@ import RandomMode from "./pages/RandomMode.vue";
import LeadMode from "./pages/LeadMode.vue";
import FollowMode from "./pages/FollowMode.vue";
import ParagraphMode from "./pages/PragraphMode.vue";
+import KeyPositionPracticeMode from "./pages/KeyPositionPracticeMode.vue";
+import KeyPositionPracticeModeLead from "./pages/KeyPositionPracticeModeLead.vue";
import Settings from "./pages/Settings.vue";
import { RouteRecordRaw } from "vue-router";
@@ -27,6 +29,16 @@ export const routes: RouteRecordRaw[] = [
name: "长句模式",
component: ParagraphMode,
},
+ {
+ path: "/key-practice-mode",
+ name: "韵母练习",
+ component: KeyPositionPracticeMode,
+ },
+ {
+ path: "/key-practice-mode-lead",
+ name: "声母练习",
+ component: KeyPositionPracticeModeLead,
+ },
{
path: "/settings",
name: "设置",
diff --git a/src/styles/keyboard.less b/src/styles/keyboard.less
index f1fe6f0..d90da09 100644
--- a/src/styles/keyboard.less
+++ b/src/styles/keyboard.less
@@ -43,6 +43,10 @@
background-color: var(--gray-010);
}
+ &.empty {
+ opacity: 0;
+ }
+
.main-content {
display: flex;
justify-content: space-between;
diff --git a/src/utils/courseConfig.gen.ts b/src/utils/courseConfig.gen.ts
new file mode 100644
index 0000000..84e8a2e
--- /dev/null
+++ b/src/utils/courseConfig.gen.ts
@@ -0,0 +1,98 @@
+//#region normal course
+const course_1_1 = ["a", "s", "d", "f", ";", "l", "k", "j", "a", "s", "d", "f", ";", "l", "k", "j", "a", "s", "d", "f", ";", "l", "k", "j", "a", "s", "d", "f", ";", "l", "k", "j", "a", "s", "d", "f", ";", "l", "k", "j", "a", "s", "d", "f", ";", "l", "k", "j"];
+const course_1_2 = ["a", "s", "d", "e", "f", ";", "l", "k", "i", "j", "a", "s", "d", "e", "f", ";", "l", "k", "i", "j", "a", "s", "d", "e", "f", ";", "l", "k", "i", "j", "a", "s", "d", "e", "f", ";", "l", "k", "i", "j", "a", "s", "d", "e", "f", ";", "l", "k", "i", "j"];
+const course_1_3 = ["a", "s", "a", "d", "a", "e", "a", "f", "a", "l", "a", "k", "a", "i", "a", "j", "s", "a", "s", "d", "s", "e", "s", "f", "s", "l", "s", "k", "s", "i", "s", "j", "d", "a", "d", "s", "d", "e", "d", "f", "d", "l", "d", "k", "d", "i", "d", "j", "e", "a", "e", "s", "e", "d", "e", "f", "e", "l", "e", "k", "e", "i", "e", "j", "f", "a", "f", "s", "f", "d", "f", "e", "f", "l", "f", "k", "f", "i", "f", "j", "l", "a", "l", "s", "l", "d", "l", "e", "l", "f", "l", "k", "l", "i", "l", "j", "k", "a", "k", "s", "k", "d", "k", "e", "k", "f", "k", "l", "k", "i", "k", "j", "i", "a", "i", "s", "i", "d", "i", "e", "i", "f", "i", "l", "i", "k", "i", "j", "j", "a", "j", "s", "j", "d", "j", "e", "j", "f", "j", "l", "j", "k", "j", "i"];
+const course_2_1 = ["a", ";", "s", "l", "d", "k", "f", "j", "g", "h", "a", ";", "s", "l", "d", "k", "f", "j", "g", "h", "a", ";", "s", "l", "d", "k", "f", "j", "g", "h", "a", ";", "s", "l", "d", "k", "f", "j", "g", "h", "a", ";", "s", "l", "d", "k", "f", "j", "g", "h", "a", ";", "s", "l", "d", "k", "f", "j", "g", "h"];
+const course_2_2 = ["a", "s", "d", "e", "f", "g", "h", "k", "l", "o", "k", "i", "j", "u", "j", "h", "j", "n", "a", "s", "d", "e", "f", "g", "h", "k", "l", "o", "k", "i", "j", "u", "j", "h", "j", "n", "a", "s", "d", "e", "f", "g", "h", "k", "l", "o", "k", "i", "j", "u", "j", "h", "j", "n", "a", "s", "d", "e", "f", "g", "h", "k", "l", "o", "k", "i", "j", "u", "j", "h", "j", "n"];
+const course_2_3 = ["l", ".", "a", ".", "l", ".", "s", ".", "l", ".", "d", ".", "l", ".", "e", ".", "l", ".", "n", ".", "l", ".", "t", ".", "l", ".", "o", ".", "l", ".", "a", ".", "l", ".", "s", ".", "l", ".", "d", ".", "l", ".", "e", ".", "l", ".", "n", ".", "l", ".", "t", ".", "l", ".", "o", "."];
+const course_2_4 = ["a", "s", "a", "d", "a", "f", "a", "g", "a", "t", "a", "l", "a", "o", "a", "k", "a", "j", "a", "u", "a", "h", "a", "n", "s", "a", "s", "d", "s", "f", "s", "g", "s", "t", "s", "l", "s", "o", "s", "k", "s", "j", "s", "u", "s", "h", "s", "n", "d", "a", "d", "s", "d", "f", "d", "g", "d", "t", "d", "l", "d", "o", "d", "k", "d", "j", "d", "u", "d", "h", "d", "n", "f", "a", "f", "s", "f", "d", "f", "g", "f", "t", "f", "l", "f", "o", "f", "k", "f", "j", "f", "u", "f", "h", "f", "n", "g", "a", "g", "s", "g", "d", "g", "f", "g", "t", "g", "l", "g", "o", "g", "k", "g", "j", "g", "u", "g", "h", "g", "n", "t", "a", "t", "s", "t", "d", "t", "f", "t", "g", "t", "l", "t", "o", "t", "k", "t", "j", "t", "u", "t", "h", "t", "n", "l", "a", "l", "s", "l", "d", "l", "f", "l", "g", "l", "t", "l", "o", "l", "k", "l", "j", "l", "u", "l", "h", "l", "n", "o", "a", "o", "s", "o", "d", "o", "f", "o", "g", "o", "t", "o", "l", "o", "k", "o", "j", "o", "u", "o", "h", "o", "n", "k", "a", "k", "s", "k", "d", "k", "f", "k", "g", "k", "t", "k", "l", "k", "o", "k", "j", "k", "u", "k", "h", "k", "n", "j", "a", "j", "s", "j", "d", "j", "f", "j", "g", "j", "t", "j", "l", "j", "o", "j", "k", "j", "u", "j", "h", "j", "n", "u", "a", "u", "s", "u", "d", "u", "f", "u", "g", "u", "t", "u", "l", "u", "o", "u", "k", "u", "j", "u", "h", "u", "n", "h", "a", "h", "s", "h", "d", "h", "f", "h", "g", "h", "t", "h", "l", "h", "o", "h", "k", "h", "j", "h", "u", "h", "n", "n", "a", "n", "s", "n", "d", "n", "f", "n", "g", "n", "t", "n", "l", "n", "o", "n", "k", "n", "j", "n", "u", "n", "h"];
+const course_3_1 = ["d", "e", "k", "i", "f", "r", "j", "u", "d", "c", "k", ",", "d", "c", "l", ".", "f", "r", "j", "u", "f", "t", "j", "y", "f", "g", "j", "h", ";", "p", ";", "p", "j", "u", "j", "y", "d", "e", "d", "c", "l", "o", "l", ".", "k", "i", "k", ",", "f", "g", "j", "u", ";", ":", ";", ":", "f", "r", "f", "k", "j", "u", "j", "y", "d", "e", "d", "c", "k", "i", "k", ",", "d", "e", "k", "i", "f", "r", "j", "u", "d", "c", "k", ",", "d", "c", "l", ".", "f", "r", "j", "u", "f", "t", "j", "y", "f", "g", "j", "h", ";", "p", ";", "p", "j", "u", "j", "y", "d", "e", "d", "c", "l", "o", "l", ".", "k", "i", "k", ",", "f", "g", "j", "u", ";", ":", ";", ":", "f", "r", "f", "k", "j", "u", "j", "y", "d", "e", "d", "c", "k", "i", "k", ",", "d", "e", "k", "i", "f", "r", "j", "u", "d", "c", "k", ",", "d", "c", "l", ".", "f", "r", "j", "u", "f", "t", "j", "y", "f", "g", "j", "h", ";", "p", ";", "p", "j", "u", "j", "y", "d", "e", "d", "c", "l", "o", "l", ".", "k", "i", "k", ",", "f", "g", "j", "u", ";", ":", ";", ":", "f", "r", "f", "k", "j", "u", "j", "y", "d", "e", "d", "c", "k", "i", "k", ","];
+const course_3_2 = ["a", "s", "a", "d", "a", "c", "a", "f", "a", "r", "a", "p", "a", "l", "a", "k", "a", "j", "a", "h", "a", "y", "s", "a", "s", "d", "s", "c", "s", "f", "s", "r", "s", "p", "s", "l", "s", "k", "s", "j", "s", "h", "s", "y", "d", "a", "d", "s", "d", "c", "d", "f", "d", "r", "d", "p", "d", "l", "d", "k", "d", "j", "d", "h", "d", "y", "c", "a", "c", "s", "c", "d", "c", "f", "c", "r", "c", "p", "c", "l", "c", "k", "c", "j", "c", "h", "c", "y", "f", "a", "f", "s", "f", "d", "f", "c", "f", "r", "f", "p", "f", "l", "f", "k", "f", "j", "f", "h", "f", "y", "r", "a", "r", "s", "r", "d", "r", "c", "r", "f", "r", "p", "r", "l", "r", "k", "r", "j", "r", "h", "r", "y", "p", "a", "p", "s", "p", "d", "p", "c", "p", "f", "p", "r", "p", "l", "p", "k", "p", "j", "p", "h", "p", "y", "l", "a", "l", "s", "l", "d", "l", "c", "l", "f", "l", "r", "l", "p", "l", "k", "l", "j", "l", "h", "l", "y", "k", "a", "k", "s", "k", "d", "k", "c", "k", "f", "k", "r", "k", "p", "k", "l", "k", "j", "k", "h", "k", "y", "j", "a", "j", "s", "j", "d", "j", "c", "j", "f", "j", "r", "j", "p", "j", "l", "j", "k", "j", "h", "j", "y", "h", "a", "h", "s", "h", "d", "h", "c", "h", "f", "h", "r", "h", "p", "h", "l", "h", "k", "h", "j", "h", "y", "y", "a", "y", "s", "y", "d", "y", "c", "y", "f", "y", "r", "y", "p", "y", "l", "y", "k", "y", "j", "y", "h"];
+const course_4_1 = ["d", "e", "d", "c", "k", "i", "k", ",", "f", "r", "f", "v", "j", "u", "j", "m", "s", "w", "s", "x", "l", "o", "l", ".", "a", "q", "a", "z", ";", "p", ";", "p", "f", "r", "f", "v", "j", "u", "j", "m", "f", "t", "f", "b", "j", "y", "j", "n", "a", "q", "s", "w", "a", "z", ";", "p", "s", "x", "l", ".", "f", "v", "j", "m", "f", "v", "j", "n", "f", "b", "j", "n"];
+const course_4_2 = ["a", "q", "a", "z", "a", "s", "a", "w", "a", "x", "a", "d", "a", "f", "a", "v", "a", "b", "a", "l", "a", "k", "a", "j", "a", "m", "q", "a", "q", "z", "q", "s", "q", "w", "q", "x", "q", "d", "q", "f", "q", "v", "q", "b", "q", "l", "q", "k", "q", "j", "q", "m", "z", "a", "z", "q", "z", "s", "z", "w", "z", "x", "z", "d", "z", "f", "z", "v", "z", "b", "z", "l", "z", "k", "z", "j", "z", "m", "s", "a", "s", "q", "s", "z", "s", "w", "s", "x", "s", "d", "s", "f", "s", "v", "s", "b", "s", "l", "s", "k", "s", "j", "s", "m", "w", "a", "w", "q", "w", "z", "w", "s", "w", "x", "w", "d", "w", "f", "w", "v", "w", "b", "w", "l", "w", "k", "w", "j", "w", "m", "x", "a", "x", "q", "x", "z", "x", "s", "x", "w", "x", "d", "x", "f", "x", "v", "x", "b", "x", "l", "x", "k", "x", "j", "x", "m", "d", "a", "d", "q", "d", "z", "d", "s", "d", "w", "d", "x", "d", "f", "d", "v", "d", "b", "d", "l", "d", "k", "d", "j", "d", "m", "f", "a", "f", "q", "f", "z", "f", "s", "f", "w", "f", "x", "f", "d", "f", "v", "f", "b", "f", "l", "f", "k", "f", "j", "f", "m", "v", "a", "v", "q", "v", "z", "v", "s", "v", "w", "v", "x", "v", "d", "v", "f", "v", "b", "v", "l", "v", "k", "v", "j", "v", "m", "b", "a", "b", "q", "b", "z", "b", "s", "b", "w", "b", "x", "b", "d", "b", "f", "b", "v", "b", "l", "b", "k", "b", "j", "b", "m", "l", "a", "l", "q", "l", "z", "l", "s", "l", "w", "l", "x", "l", "d", "l", "f", "l", "v", "l", "b", "l", "k", "l", "j", "l", "m", "k", "a", "k", "q", "k", "z", "k", "s", "k", "w", "k", "x", "k", "d", "k", "f", "k", "v", "k", "b", "k", "l", "k", "j", "k", "m", "j", "a", "j", "q", "j", "z", "j", "s", "j", "w", "j", "x", "j", "d", "j", "f", "j", "v", "j", "b", "j", "l", "j", "k", "j", "m", "m", "a", "m", "q", "m", "z", "m", "s", "m", "w", "m", "x", "m", "d", "m", "f", "m", "v", "m", "b", "m", "l", "m", "k", "m", "j"];
+//#endregion
+
+//#region paragraph course
+const course_1_4 = ["j", "s", "i", "h", "d", "e", "u", "j", ",", "f", "g", "l", "l", "e", "m", "w", ".", "d", "a", "i", "g", "u", "i", "d", "e", "j", "x", "t", "k", ",", "s", "i", "j", "i", "k", "e", "d", ".", "k", "j", "j", "m", "u", "v", "i", "s", "d", "e", "l", "o", "y", "e", ",", "y", "z", "x", "l", "q", "i", "j", "x", ".", "j", "i", "d", "d", "e", "h", "d", "z", "i", "m", "f", ",", "z", "d", "y", "r", "j", "d", "e", "y", "r", "z", "i", "l", "i", "w", "j", ".", "l", "k", "j", "x", "d", "e", "f", "h", "z", "i", ",", "q", "k", "j", "p", "l", "l", "u", "l", ".", "d", "a", "j", "x", "d", "z", "x", "l", "g", "e", "d", "i", "f", "h", "d", "e", "u", "g", "h", "o", ",", "j", "b", "q", "l", "d", "l", "m", "."];
+const course_2_5 = ["u", "h", "j", "k", "t", "s", "u", "o", "s", "j", "l", "h", "j", "m", "u", "j", "k", "d", "g", "o", "h", "d", "l", "k", "x", "n", "f", "g", "d", "c", "u", "k", "j", "s", "t", "r", "f", "g", "y", "r", "k", "h", "d", "g", ".", "t", "m", "q", "m", "u", "g", "k", "l", "j", "n", "j", "g", "r", "u", "e", "h", "v", "t", "s", "v", "l", ".", "u", "h", "n", "j", "u", "h", "k", "d", "l", "u", "j", "q", "h", "r", ".", "y", "r", "u", "h", "d", "c", "j", "m", "f", "g", "x", "l", "k", "k", "v", "k", "d", "m", "j", "m", "k", "h", "."];
+const course_3_3 = ["Sha", "r", "c", "c", "g", "d", "s", "l", "m", ",", "p", "d", "f", "s", "y", "p", ".", "Ji", "d", "ail", "s", "s", "l", "d", ",", "k", "d", "j", "m", "l", "k", ".", "Fu", "l", "a", "j", "k", "y", "j", ",", "p", "on", "k", "m", ".", "Ca", "p", "e", "l", "h", ",", "k", "y", "s", "l", "j", "y", ".", "Li", "p", "n", "u", "g", ",", "q", "y", "j", "i", "y", ".", "Suan", "j", "k", "d", "l", ",", "l", "l", "l", "j", ".", "Piao", "j", "m", "s", "s", ",", "y", "s", "d", "m", "c", "h", ".", "Luo", "k", "h", "y", "r", ",", "v", "c", "r", "g", "j", "s", ".", "Pian", "l", "k", "c", "r", ",", "j", "k", "p", "j", "."];
+const course_4_3 = ["v", "h", "d", "s", "w", "w", "m", "m", ",", "j", "x", "l", "i", "v", "u", "u", "a", "x", "s", ".", "b", "a", "u", "a", "x", "s", "d", "s", "x", "i", "v", "c", "s", "j", "d", "s", "u", "h", ".", "q", "i", "l", "i", "u", "o", ":", "\"", "m", "m", "b", "m", "k", "k", "u", "h", "j", "x", "l", "e", ".", "\"", "u", "a", "x", "s", "j", "q", "m", "m", "x", "l", "j", "x", ".", "v", "e", "u", "i", "j", "m", "b", "m", "d", "e", "u", "i", "q", "k", ".", "x", "x", "w", "u", ",", "q", "m", "m", "m", "d", "e", "l", "m", "u", "i", "h", "v", ",", "v", "r", "x", "m", "b", "a", "l", "w", "j", "p", "y", "i", "q", "i", ".", "d", "s", "t", "m", "l", "d", "l", "e", ",", "u", "a", "x", "s", "y", "s", "q", "k", "q", "m", "d", "e", "h", "x", "x", "i", "j", "m", "y", "i", "g", "e", "j", "n", "k", "d", "e", "j", "x", "y", "r", "."];
+//#endregion
+
+export const courses = [
+ course_1_1,
+ course_1_2,
+ course_1_3,
+ course_1_4,
+ course_2_1,
+ course_2_2,
+ course_2_3,
+ course_2_4,
+ course_2_5,
+ course_3_1,
+ course_3_2,
+ course_3_3,
+ course_4_1,
+ course_4_2,
+ course_4_3,
+]
+
+export const courseNames = [
+ '课程 1-1',
+ '课程 1-2',
+ '课程 1-3',
+ '课程 1-4',
+
+ '课程 2-1',
+ '课程 2-2',
+ '课程 2-3',
+ '课程 2-4',
+ '课程 2-5',
+
+ '课程 3-1',
+ '课程 3-2',
+ '课程 3-3',
+
+ '课程 4-1',
+ '课程 4-2',
+ '课程 4-3',
+]
+
+export const courseTitles = [
+ "训练键位: 左手 - a s d e f 右手 - ; l k i j",
+ "训练键位: 左手 - a s d e f 右手 - ; l k i j",
+ "训练键位: 左手 - a s d e f 右手 - ; l k i j",
+ "训练键位: 左手 - a s d e f 右手 - ; l k i j (文章练习)",
+
+ "训练键位: 左手 - g t 右手 - h o u n",
+ "训练键位: 左手 - g t 右手 - h o u n",
+ "训练键位: 左手 - g t 右手 - h o u n",
+ "训练键位: 左手 - g t 右手 - h o u n",
+ "训练键位: 左手 - g t 右手 - h o u n (文章练习)",
+
+ "训练键位: 左手 - r c 右手 - y , : p",
+ "训练键位: 左手 - r c 右手 - y , : p",
+ "训练键位: 左手 - r c 右手 - y , : p (文章练习)",
+
+ "训练键位: 左手 - q w z x v b 右手 - m",
+ "训练键位: 左手 - q w z x v b 右手 - m",
+ "训练键位: 左手 - q w z x v b 右手 - m (文章练习)",
+];
+
+export const paragraphCourseIndexs = [
+ 3, 8, 11, 14
+]
+
+//#region paragraph course display char
+const courseDisplay_1_4 = ["j", "iong", "ch", "ang", "d", "e", "sh", "an", ",", "f", "eng", "l", "iang", "e", "m", "ei", ".", "d", "a", "ch", "eng", "sh", "i", "d", "e", "j", "ia", "t", "ing", ",", "s", "i", "j", "i", "k", "e", "ai", ".", "k", "an", "j", "ian", "sh", "ui", "ch", "ong", "d", "e", "l", "uo", "y", "e", ",", "y", "ou", "x", "iang", "q", "i", "j", "ia", ".", "j", "i", "ai", "d", "e", "h", "ai", "z", "i", "m", "en", ",", "z", "ai", "y", "uan", "an", "d", "e", "y", "uan", "z", "i", "l", "i", "w", "an", ".", "l", "ing", "j", "ia", "d", "e", "f", "ang", "z", "i", ",", "q", "ing", "j", "ie", "l", "iang", "sh", "uang", ".", "d", "a", "j", "ia", "d", "ou", "x", "iang", "g", "e", "d", "i", "f", "ang", "d", "e", "sh", "eng", "h", "uo", ",", "j", "in", "q", "iang", "ai", "l", "ian", "."];
+const courseDisplay_2_5 = ["sh", "ang", "j", "ing", "t", "ong", "sh", "uo", "s", "an", "l", "ang", "j", "ian", "sh", "an", "k", "ai", "g", "uo", "h", "ai", "l", "ing", "x", "iao", "f", "eng", "d", "ao", "sh", "uai", "j", "iong", "t", "uan", "f", "eng", "y", "uan", "k", "ang", "d", "eng", ".", "t", "ian", "q", "ian", "sh", "eng", "k", "uang", "j", "iao", "an", "g", "uan", "sh", "e", "h", "ui", "t", "ong", "zh", "uang", ".", "sh", "ang", "n", "an", "sh", "ang", "k", "ai", "l", "u", "j", "iu", "h", "uan", ".", "y", "uan", "sh", "ang", "d", "ao", "j", "ian", "f", "eng", "x", "iang", "k", "uai", "zh", "uai", "d", "ian", "j", "ian", "k", "ang", "."];
+const courseDisplay_3_3 = ["Sha", "r", "ao", "c", "eng", "d", "iong", "l", "ian", ",", "p", "ai", "f", "ong", "y", "ie", ".", "Ji", "d", "ail", "s", "ong", "l", "ai", ",", "k", "ai", "j", "ian", "l", "ing", ".", "Fu", "l", "a", "j", "ing", "y", "an", ",", "p", "on", "k", "ian", ".", "Ca", "p", "e", "l", "ang", ",", "k", "un", "s", "iang", "j", "un", ".", "Li", "p", "iao", "sh", "eng", ",", "q", "un", "j", "i", "un", ".", "Suan", "j", "ing", "d", "iang", ",", "l", "iang", "l", "an", ".", "Piao", "j", "ian", "s", "ong", ",", "y", "ong", "d", "ian", "c", "ang", ".", "Luo", "k", "ang", "y", "uan", ",", "zh", "ao", "r", "eng", "j", "iong", ".", "Pian", "l", "ing", "c", "uan", ",", "j", "uai", "p", "an", "."];
+const courseDisplay_4_3 = ["zh", "ang", "d", "ong", "w", "ei", "m", "ian", ",", "j", "ia", "l", "i", "zh", "u", "sh", "a", "x", "iong", ".", "b", "a", "sh", "a", "x", "iong", "d", "ong", "x", "i", "zh", "ao", "s", "an", "d", "ong", "sh", "ang", ".", "q", "i", "l", "i", "sh", "uo", ":", "\"", "m", "ian", "b", "ian", "k", "uai", "sh", "ang", "j", "ia", "l", "e", ".", "\"", "sh", "a", "x", "iong", "j", "iu", "m", "ian", "x", "iang", "j", "ia", ".", "zh", "e", "sh", "i", "j", "ian", "b", "ian", "d", "e", "sh", "i", "q", "ing", ".", "x", "ia", "w", "u", ",", "q", "ian", "m", "ian", "d", "e", "l", "ian", "sh", "i", "h", "ui", ",", "zh", "uan", "x", "ian", "b", "a", "l", "ei", "j", "ie", "y", "i", "q", "i", ".", "d", "ong", "t", "ian", "l", "ai", "l", "e", ",", "sh", "a", "x", "iong", "y", "ong", "q", "ing", "q", "ian", "d", "e", "h", "ua", "x", "i", "j", "ian", "y", "i", "g", "e", "an", "n", "ing", "d", "e", "j", "ia", "y", "uan", "."];
+//#endregion
+
+export const courseDisplays = [
+ courseDisplay_1_4,
+ courseDisplay_2_5,
+ courseDisplay_3_3,
+ courseDisplay_4_3,
+]
diff --git a/src/utils/keyPosition.ts b/src/utils/keyPosition.ts
new file mode 100644
index 0000000..463c8b2
--- /dev/null
+++ b/src/utils/keyPosition.ts
@@ -0,0 +1,75 @@
+import { courseDisplays, paragraphCourseIndexs } from "./courseConfig.gen";
+import type { ShuangpinConfig } from "./keyboard";
+import type { Phoneme, PhonemeInputStatus } from "./phoneme";
+
+export const resultMap = {
+ curt_0: "finished-wrong",
+ curt_1: "finished-correct",
+ next: "activate",
+} as const satisfies Record
;
+export const punctuationMapper: Record = {
+ ";": ";",
+ "。": ".",
+ ",": ",",
+};
+export const passRequire = 0.9;
+export const perFragmentLength = 16;
+export const currentMenuChangeKeys = ["PageUp", "PageDown"] as const;
+const mainMenuChangeKeys = [
+ "ArrowUp",
+ "ArrowDown",
+ "ArrowLeft",
+ "ArrowRight",
+] as const;
+export const allMenuChangeKeys = [...currentMenuChangeKeys, ...mainMenuChangeKeys];
+
+export type CharModeType = 'leads' | 'follows';
+function getCharMode(isParagraphCourse: boolean, nextLead: boolean, _mode?: CharModeType): CharModeType {
+ if (isParagraphCourse) {
+ return nextLead
+ ? "leads"
+ : "follows";
+ } else {
+ return _mode ?? "follows";
+ }
+}
+
+const vowelKeys = ['a', 'e', 'i', 'o', 'u']
+
+type Params = {
+ isParagraphCourse: boolean;
+ nextLead: { value: boolean };
+ config: ShuangpinConfig;
+ menuIndex: number;
+ _mode?: CharModeType;
+}
+const createPhoneme = ({ isParagraphCourse, nextLead, config, menuIndex, _mode }: Params) => (char: string, i: number): Phoneme | undefined => {
+ const mode = getCharMode(isParagraphCourse, nextLead.value, _mode);
+ const status: PhonemeInputStatus = i === 0 ? "activate" : "unfinished";
+ const phonemeValues = config.groupByKey.get(char as Char)?.[mode];
+ const values = phonemeValues?.length ? phonemeValues : [char];
+
+ if (mode === 'leads' && vowelKeys.includes(char) && !phonemeValues?.[0]) {
+ return;
+ }
+
+ let displayValue: string;
+ if (isParagraphCourse) {
+ if (phonemeValues) {
+ nextLead.value = !nextLead.value;
+ }
+ displayValue = courseDisplays[paragraphCourseIndexs.indexOf(menuIndex)][i]
+ } else {
+ const fragmentIndex = Math.floor(i / perFragmentLength);
+ const charIndex = fragmentIndex % values.length;
+ displayValue = values[charIndex];
+ }
+
+ return { status, displayValue, values, char };
+}
+
+export function createWholeSeq(chars: readonly string[], config: ShuangpinConfig, menuIndex: number, _mode?: 'leads' | 'follows'): Phoneme[] {
+ const isParagraphCourse = paragraphCourseIndexs.includes(menuIndex);
+ const nextLead = { value: true };
+ return chars.map(createPhoneme({ isParagraphCourse, nextLead, config, menuIndex, _mode })).filter((p): p is Phoneme => p !== undefined);
+}
diff --git a/src/utils/keyboard.ts b/src/utils/keyboard.ts
index fb6ef89..8ea9e4c 100644
--- a/src/utils/keyboard.ts
+++ b/src/utils/keyboard.ts
@@ -86,6 +86,7 @@ export class ShuangpinConfig {
}
export const keyboardLayout = ["qwertyuiop", " asdfghjkl;", "zxcvbnm"];
+export const keyboardLayoutWithPunctuation = ["qwertyuiop", " asdfghjkl;", " zxcvbnm,. "];
export function mergeString([a, b]: string[] = []) {
if (!(a && b && a.length > 2 && b.length > 2)) {
@@ -118,8 +119,8 @@ export function mergeString([a, b]: string[] = []) {
return `(${prefix})${suffix}`;
}
-export function mapConfigToLayout(config: ShuangpinMode) {
- return keyboardLayout.map((v) =>
+export function mapConfigToLayout(config: ShuangpinMode, layout = keyboardLayout) {
+ return layout.map((v) =>
v.split("").map((key) => {
const keyConfig = config.groupByKey.get(key as Char) ?? {
main: key,
diff --git a/src/utils/phoneme.ts b/src/utils/phoneme.ts
new file mode 100644
index 0000000..85a13b3
--- /dev/null
+++ b/src/utils/phoneme.ts
@@ -0,0 +1,20 @@
+import type { CharModeType } from "./keyPosition";
+
+export type PhonemeInputStatus =
+ | "activate"
+ | "activate-correct"
+ | "activate-wrong"
+ | "finished-correct"
+ | "finished-wrong"
+ | "unfinished";
+
+export type Phoneme = {
+ values: string[]
+ displayValue: string;
+ char: string;
+ status: PhonemeInputStatus;
+};
+
+export interface KeyPracticeProps {
+ mode?: CharModeType;
+}