TA的每日心情 | 慵懒 2021-9-1 08:46 |
|---|
签到天数: 61 天 [LV.6]常住居民II
|
本帖最后由 zhangchaont 于 2021-2-20 10:53 编辑
# O& g. ~' T/ K2 M
) {/ ]7 v4 ^7 l- ]! s! b; G+ U8 m) @为了给孩子学习英语,我把单词做成了卡片放在Anki里,但是课文却一直没有什么好的方法,在电脑上用一个复读机软件给孩子们练习,但是Mac上没有什么好用的复读机软件,所以学来学去还在最开始的几课里面打转。我本来想自己写一个复读机APP的,但是考虑到水平有限,估计得花很多时间,而且最大的问题不能利用Anki里schedule安排学习。& I) O3 W/ T* Y
7 h2 {4 r6 k5 d9 v
春节在家,我突然灵光一闪,Anki是基于PyQt5开发,而这个模块是支持一部分html、css和javascript的,如果用javascript读取字幕里面的时间戳,然后根据时间段来播放MP3,不就实现了一个简单的复读机了嘛。说干就干,因为没有javascript语言基础,都是需要什么就搜索,一步步的拼凑起来的,目前已经基本能用,成品在iOS上显示如下:: p% _3 |3 l8 W# u9 D2 K# o' [
/ a3 o( e0 R3 mmacOS上的效果" M. m: G8 j+ E, @$ X
9 p$ |9 d4 L1 `1 P" J+ i8 f& E7 W
js代码如下:: R7 A, W/ a- M
- const lesson = document.getElementsByClassName("items")[0].innerText;+ w0 |) |1 L0 `2 G$ B! s
- const button_next = document.createElement("button");
$ W+ \, ?# c, w6 i5 x) w - button_next.innerHTML = '下一句';, u" w) m( y1 K/ q5 ~
- button_next.setAttribute('row_count', "4");
1 I4 A' Z+ j# T, v3 Y - let section = document.getElementsByClassName("section")[0];
$ Q0 O( T) P4 o& U, b5 t8 o - 3 u- t3 V6 \( Z+ Z. U: c
- const button_repeat = document.createElement("button");+ L3 y# W/ m) {1 Y
- button_repeat.innerHTML = '重复此句';
- a I2 K0 M& C& U2 i ^ - 1 c ?1 D: o. x/ Y E, k
- const button_previous = document.createElement("button");6 `7 _; t" F* B2 z# l- n6 B E
- button_previous.innerHTML = '上一句';& \$ A! y+ V4 C0 I1 g
- ( d: g3 ^: M6 W0 s) E
- Q7 B- k3 r9 U
- let div = document.createElement('div');+ B1 v& a6 E/ x4 j
- div.setAttribute('class', 'text');
' R. |; Z2 i1 ^# }+ ~, o E p7 o - section.appendChild(div);, c; W8 h8 X! B; v! P8 C% S8 A
- let p = document.createElement('p');- c* T: m+ @: a: N& B( w" v
- div.appendChild(p);
0 l/ Y7 n+ L* [& Z/ C - $ z. I+ E' m3 t! ~
- buttons_div = document.createElement('div');
) m4 g% Q1 U: T [5 O - buttons_div.setAttribute('class', 'buttons');
6 M5 s7 A% Q& G4 U0 N - 7 i2 G: e$ I% G) O
- section.appendChild(buttons_div);* }/ P- e# m6 n. `
- ) i; P7 \+ |) l
- buttons_div.appendChild(button_previous);
& q9 O0 K/ E$ j+ D - buttons_div.appendChild(button_repeat);0 L7 v+ j3 W/ p6 ?* X% i
- buttons_div.appendChild(button_next);3 J: D+ U% ~& K0 ]& D w3 y/ G
1 O, n7 u3 q( _0 t7 B4 e8 K% S- r
" r: B) l' U3 C/ [" ~: t4 ^; K- button_next.onclick = next;+ a) }6 Y d# k) I4 }1 O
- button_repeat.onclick = repeat;
, i6 k U2 k. w2 T - button_previous.onclick = previous;7 @( m: V' W/ u5 z0 j
- section.onload = play;. s" I! }6 Y3 |" u" Z' [
$ Z+ {& t7 j. h9 e. b! v3 c- function next() {- R; I' ^, N+ E& u7 F
- let index = parseInt(button_next.getAttribute('row_count'));7 z: g' u2 M* r5 F# G- t* K2 Y
- index += 1;
" b9 U C5 b2 x% p% y" L - button_next.setAttribute('row_count', index.toString())
) t5 S" d; j1 ~% u' H$ I5 U# F4 R8 y - play().then(r => '');
/ h. C7 R) b; o - }; {( J. |/ f7 W8 r: X
- & U% @- U- \. o7 S# O4 S
- function previous() {
7 o- w L- ^' v$ p! P: \ - let index = parseInt(button_next.getAttribute('row_count'));9 A$ [0 m/ X6 J
- index -= 1;( u5 ^$ Z9 C5 e* [
- button_next.setAttribute('row_count', index.toString())
! Z' d3 \$ ?* V7 B7 v& s* } - play().then(r => ''); z& E* d- b( R7 D. C. }
- }& J0 o d" `0 }, O
7 [0 l9 [" X3 d0 e& m; O3 p- ?- function repeat() {
- n! d( I" l* h# l8 [ - play().then(r => '');' ^& K/ g U- j) L0 k
- }/ u* t& V0 J) f$ y0 }$ N" q
$ G/ @% @3 T+ s0 I; B- async function play() {1 H3 o$ B) z' l6 @2 H6 L
- const file = "NCE1-" + lesson + ".lrc";" @0 [- t0 S) E$ E) Q
- let myObject = await fetch(file);
3 y6 c3 P$ |, w: w" F - let myText = (await myObject.text()).trim();
! y- ^, p( a: @# s8 o - let lines = myText.split('\n');
% @8 y# n9 d7 R - let index = parseInt(button_next.getAttribute('row_count'));
. q; T- @3 @+ |0 j6 b
, l: y# I4 q5 w ~- P6 d- if (index < 4) {
5 ~$ \7 Y4 R9 Q - index = lines.length - 1;8 @1 B0 G1 P7 i2 S! Q" r- v4 U
- button_next.setAttribute('row_count', index.toString());
5 a5 \3 V/ o. W$ d1 B; E. m9 t - }
1 o- r2 i3 P5 M* t& v7 U9 Q - if (index > lines.length - 1) {, `) N4 b' p5 H& Q: p+ U3 M2 O! \
- index = 4;! R, R6 e" C3 F: @
- button_next.setAttribute('row_count', index.toString());* c. O0 q7 ^1 O) j% E4 w
- }
5 F7 ?6 m( t6 _: n - let current_line = lines[index];, p$ [7 b3 {4 C1 ]5 A3 J
- let text = current_line.slice(10, current_line.length - 1);
$ U1 f3 b% Q- ~6 v1 r - p.innerText = text;+ m6 E8 o# F: F2 o
- if (index < (lines.length - 1)) {" G9 [! Y5 [& h: ^! N
- let next_index = index + 1;: q/ J. f& F# _. E+ q
- let next_line = lines[next_index];5 B" \4 c! T4 v+ Z0 Q
- let current_time = current_line.slice(1, 9);2 m" X; \4 h6 v
- let current_time_min_sec = current_time.split(':');0 d3 y u) t4 X4 K! ~: E
- let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);; m; p n+ a0 j! z: I6 Z
- let next_time = next_line.slice(1, 9);2 j. \# z( w! h$ u( T) m
- let next_time_min_sec = next_time.split(':');" H. Y9 @/ E. p6 p: O! f" k
- let end = parseFloat(next_time_min_sec[0]) * 60 + parseFloat(next_time_min_sec[1]) - 0.25;
4 H k9 y( ]' u8 O; K - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start + "," + end);0 ^/ \: A: y/ }$ b6 K
- const play1 = audio.play();* X+ M# v* Q) B4 L5 i: Q/ K
- } else {" \$ S% X& d6 g$ ^, B( K |# |
- let current_time = current_line.slice(1, 9);$ E: M, N: _0 m* R0 P
- let current_time_min_sec = current_time.split(':');
; Z# J9 d Q2 W5 `8 }8 o - let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);
; {' p0 J' Z5 W5 R# t9 h+ W - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start);3 b$ A0 z3 T- E) P# r. o
- const play2 = audio.play();4 L( _6 O& t" U; [' y
- } K9 @+ W- E& [6 X1 x
- }
复制代码 6 _; N c% J, N: }
- |5 ~# o& w" g8 ?/ V8 o: Z* O2 t8 X使用的时候,把下面网盘链接里面的Anki卡片导入,然后把新概念的音频和字幕文件拷贝到Anki的collection.media文件夹里面,如果不知道media文件夹的位置在网上搜索一下。$ B5 o% z) ~" C% D. O
: |/ ]( [3 G7 ^- /*区块全局样式*/
5 d* m% u, {4 E7 | - .section {
* i4 W" _; N8 W! K7 y+ j% u - background-color : #f6f6f6; /*背景颜色-#f6f6f6*/1 S" d4 { y5 k5 m f# H
- border : 2px solid #3f3f41; /*边缘样式-实线2px*/
9 [3 Q7 p3 N+ T% A - border-radius : 3px; /*圆角幅度-3px*/2 f9 S" j5 A& Q9 U, V# e4 {( q" {
- margin : 8px 8px; /*上下间隔-8px*/
$ b, P: k. V3 C. t( }1 p1 D& s - display : flex;( i6 l: j) l6 c B: `
- flex-direction : column;& y' q: S1 T0 D7 u# S7 m4 m
- height: 95vh;
) z1 H- Q) V- v. l% A8 b2 _ - }4 d0 o1 O* V7 ?8 M
h7 T5 C9 ^$ w; s. |1 V% s- /*区块全局样式*/. n9 @" v& @) k
- .mobile .section {
6 g; d: N, Y8 n, g& L - background-color : #f6f6f6; /*背景颜色-#f6f6f6*/
; Q! d/ k5 G- i5 U9 ~3 U$ O$ x - border : 2px solid #3f3f41; /*边缘样式-实线2px*/8 j1 h+ @- F" H+ @+ `3 R
- border-radius : 3px; /*圆角幅度-3px*/5 _( i+ F) I) i6 D% b9 s7 `, e
- margin : 8px 8px; /*上下间隔-8px*/
& O$ x6 `) o* f& I1 k - display : flex;- w* `' ~/ `3 [* y& a+ p+ N
- flex-direction : column;; d) ?* `8 T# G- |3 r7 \" l
- height: 77vh;
, y% A+ U+ C4 R; o- d - }
复制代码
, t3 n7 L( G9 l! t Z在模板里面的css部分,可以调节整个区块的大小,修改height后面的数值来调节。前面有.mobile的是对移动设备的设置。) D6 h# n5 k" t/ ]" M$ K, u
7 j. Z8 g7 U5 [/ ?( g! v
你也可以把这个模板稍加修改就可以添加新概念后面的几本书。7 Y) W& x. c: P- F6 @
6 C; t4 \6 p/ [( L: R6 [
/ w4 j3 J( w9 ]2 q0 O
& v! G4 R8 M& t7 ~注意,因为iOS版本的Anki不会自动重新加载js,所以到第二张卡片的时候就会按钮显示不出来,退到deck界面再进去就可以了。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?免费注册
x
评分
-
2
查看全部评分
-
|