当ブログではかねてから,暗記学習に効果的なツールとして,分散学習システム Ankiの使用を推奨している。
Ankiは多機能だが,カウントダウンタイマー機能は用意されていない。
Ankiの典型的な使い道である英単語は,単に覚えているかどうかの問題なので,カウントダウンタイマーの必要性は薄い(集中力を高める効果はあるかもしれないが)。しかし,思考要素のある問題(たとえば,英文法)には,その思考スピードが目標内かを測定するために,カウントダウンタイマーが効果的である。
そこで,自作デッキに対しカウントダウンタイマーを設置する手段を提供するのがこの記事の目的である。単なる数字表示だけではなく,プログレスバーも表示する。
さっそく,サンプルデッキの動作を動画で紹介する。
- デッキを開き,表面を表示したら,すぐにカウントダウンが開始する。
- 「00:15/00:15」のように,"/"の右側に制限時間(分:秒),左側に残り時間(分:秒)を表示する。残り時間は1秒ごとに減る。
- この制限時間はノートごとに個別に設定できる。
- 1秒ごとにプログレスバーが縮む。
- 残り時間「00:00」になると停止する。
- デスクトップ版とAnkiWebでは,自動的に裏面に進む。AnkiMobile(iOS)とAnkiDroid(Android)では,表面のままである[表面最下部の自動タップも,技術的にはおそらくJavaScriptで可能だろうが,今のところ筆者には実現できていない]。
- 裏面では,「Time Limit: 00:15」のように制限時間(分:秒)のみを表示する。
このカウントダウンタイマーを実装したAnkiデッキは,Windows・Mac・AnkiWeb(Safari/Chrome/Firefox/IE 10以降)・AnkiMobile (iOS)・AnkiDroid (Android)での正常動作を確認している(ただし,前述のとおり,AnkiMobileとAnkiDroidは自動めくり非対応)。
Ankiデッキにカウントダウンタイマーを実装するための作業は,おおまかには,以下の4段階で構成される。
(1)フィールドの作成,制限時間(秒)の入力
ノートごとに個別の制限時間を設定できるよう,デッキに{{time_limit}}フィールドを設け,そこに制限時間(秒)を数値で入力する。
(2) 書式(CSS)の設定
作業としては後述の文字列(CSS)を書式の設定に貼り付けるだけである。
(3) JavaScriptの設定
作業としては後述の文字列(JavaScript)をテンプレートの設定に貼り付けるだけである。
(4) HTMLの設定
作業としては後述の文字列(HTML)をテンプレートの設定に貼り付けるだけである。
以下に具体的な設定内容を示す。
ア.フィールドの作成
対象のデッキのフィールド設定画面で {{time_limit}} フィールドを作成する。
▼フィールド設定
フィールドの名前は例のように「time_limit」でなければならない。「_」はアンダーバーである。
イ.制限時間(秒)の数値の入力
各ノートの編集画面の {{time_limit}} フィールドに制限時間(秒)を数値で入力する。たとえば,制限時間20秒なら「20」,1分20秒なら「80」とする。「20秒」「00:20」「80秒」「1分20秒」「01:20」はすべて誤りである。
▼ノート編集
デッキに格納するデータは「秒」の数値であっても,実際にはJavaScriptが計算して「分:秒」のデジタル表示する仕組みである。
テンプレート編集画面の「書式」に,以下の文字列 (CSS) を追加する。
.time {
color: gray;
font-size: 14px;
text-align: right;
float: right; /* 同一行に問題番号を左寄せ表示する場合 */
padding-right: 2px;
}
「float: right;」は,サンプルデッキのように,同一行の左側に問題番号などを表示する場合の記述である。同一行としない場合は削除する。
▼書式
テンプレート編集画面の「表面のテンプレート」「裏面のテンプレート」のそれぞれに以下の文字列を追加する。
▼表面のテンプレート
<script language="javascript">
// AnkiDroid対策
if (window.addEventListener) {
window.addEventListener('load', load);
} else if (window.attachEvent) {
window.attachEvent('onload', load);
}
window.onload = load();
function load() {
val = 100;
remain = {{time_limit}};
min = String(Math.floor(remain / 60) + 100);
sec = String(remain % 60 + 100);
document.getElementById("myProgress").value = 100;
document.getElementById("total").innerText = min.substr(-2, 2) + ":" + sec.substr(-2, 2);
document.getElementById("remain").innerText = min.substr(-2, 2) + ":" + sec.substr(-2, 2);
intervalID = setInterval("updateProgress()", 1000);
}
function updateProgress() {
if (val > 0) {
val -= 100 / {{time_limit}};
document.getElementById("myProgress").value = val;
remain -= 1;
min = String(Math.floor(remain / 60) + 100);
sec = String(remain % 60 + 100);
document.getElementById("remain").innerText = min.substr(-2, 2) + ":" + sec.substr(-2, 2);
} else { // 最大値まで達したら終了
clearInterval(intervalID);
try {
//window.pycmd('ans'); // タイムオーバーで自動めくり (PC) ここを有効にすると,Anki 2.1.46以降では裏面音声がバグる
} catch {
document.getElementById("ansbuta").click(); // タイムオーバーで自動めくり (AnkiWeb)
} finally {
document.getElementById("remain").innerText = "00:00";
}
}
}
</script>
▼裏面のテンプレート
<script language="javascript">
// AnkiDroid対策
if (window.addEventListener) {
window.addEventListener('load', load);
} else
if (window.attachEvent) {
window.attachEvent('onload', load);
}
window.onload = load ();
function load() {
remain = {{time_limit}};
min = String(Math.floor(remain / 60) + 100);
sec = String(remain % 60 + 100);
document.getElementById("total").innerText = min.substr(-2, 2) + ":" + sec.substr(-2, 2);
}
</script>
▼「表面のテンプレート」「裏面のテンプレート」
テンプレート編集画面の「表面のテンプレート」「裏面のテンプレート」のカウントダウンタイマーを設置したい箇所に以下の文字列を追加する。
▼表面のテンプレート
<div class="time"><progress id="myProgress" value="0" max="100">0%</progress> <span id="remain"></span>/<span id="total"></span></div>
▼裏面のテンプレート
<div class="time">Time Limit: <span id="total"></span>
</div>
実際には,同一行において,問題番号を左寄せに,プログレスバーを右寄せに表示するのが洗練する。その場合は以下のようにする(この例では問題番号は{{num}}フィールドである)。
▼表面のテンプレート
<div>{{num}}<div class="time"><progress id="myProgress" value="0" max="100">0%</progress> <span id="remain"></span>/<span id="total"></span></div></div>
▼裏面のテンプレート
<div>{{num}}<div class="time">Time Limit: <span id="total"></span></div></div>
以上で解説した方法により,カウントダウンタイマーを実装したサンプルデッキを提供する(ついでに,裏面で正解選択肢を自動的に赤色で強調するJavaScriptも組み込んである)。
次の書籍のQ1〜Q3を題材とした。問題ごとに「目標解答タイム」が記載され,しかもその秒数が異なっている点で,今回のサンプルとするのに相応しいからである。
サンプルデッキの構造は汎用的(ただし4択問題に最適化している)であり,一般的に必要となりそうなフィールド(音声・解説)も用意済みなので,テンプレートの名前を変更のうえ,お好きなデータを入力して自作デッキとすることも可能である。
■パソコン(Windows・Mac)のAnki・AnkiDroid (Android)の場合
以下からダウンロードしてAnkiに読み込む。
CountDownTimer Sample.apkgを
今すぐダウンロード
■iOSアプリ「AnkiMobile」の場合
- iOS端末(iPhone/iPad/iPodTouchなど)へのAnkiMobleアプリのインストールがまだの場合は,AppStoreで購入してインストールする(¥3,500円)。
- iOS端末でこの記事にアクセスし,以下のダウンロードURLをコピーする。
CountDownTimer Sample.apkghttp://anki.myqnapcloud.com:8080/share.cgi?ssid=1c6444cd10124da99769310b310f5e6e&openfolder=forcedownload&fid=1c6444cd10124da99769310b310f5e6e
- AnkiMobileを起動し,トップ画面左下の「追加/エクスポート」をタップする。
- 「リンクをダウンロード」をタップする。
- 現れた空欄に2.でコピーしたURLをペーストし,「OK」をタップする。
※空欄を長押しすると「ペースト」が選べるようになる。
以上、カウントダウンタイマーの実装方法を紹介した。マニアックなAnkiユーザーに楽しんでいただければ幸いである。
タイムオーバー時の動作として,本来なら裏面への自動めくりを全面的に実現したいのだが(不要な場合はその部分のJavaScriptをコメントアウトすればよい),いまのところ,デスクトップ版とAnkiWeb版での実現にとどまっている(2022年2月追記。Anki 2.1.46以降では,PCで自動めくりすると,高確率で裏面音声が繰り返し再生され続ける不具合が発生する。対処が見つからないかぎり,少なくともPCではこの機能はオフとせざるをえないい)。AnkiMobile (iOS)とAnkiDroid (Android)については今後の課題とする。もし,その部分の自動めくりの実現方法の情報をいただける場合,メッセージをお願いします。
なお,私は,Ankiデッキの出題形式として暗記ペン形式(問題中の一部をマークで隠し,開閉して確認する形式)の実装方法を考案し,以下の記事で紹介している。
また,Ankiデッキ自作のコツをまとめている。
いずれも,興味ある方に参考にしていただきたい。
更新履歴
2021年7月9日
- 初公開。
2022年4月12日
- Anki 2.1.46(PC版)以降で,自動めくりにて,裏面音声が繰り返し再生される不具合が発生していることを注記。