TypeRush ができるまで — インタラクティブ学習 3本目を タイピング道場 で開く
TypeRush は、 ブラウザだけで動く無料 タイピング 練習。 5 モード × 3 レベル、 WPM + 正確率 リアルタイム、 完了後 QWERTY ミス ヒートマップ。 ラボ 31本目、 インタラクティブ学習 thesis 3本目 (ToneQuest 音感 / AtlasQuest 国旗 に続く)。
なぜこの形にしたか
直近 5本 (frac-cast / patch-pad / doodle-drop / side-tax / atlas-quest) に学習は atlas-quest の 1本のみ、 連続にならず §3.1 OK。 シミュレーターが 2本 (frac-cast / doodle-drop) でこれ以上重ねると 3 連続 NO-GO に近づくため別 thesis 優先。
候補比較:
- タイピング道場 (採用) — SEO ★★★★★ 「タイピング 練習 無料」 検索ボリューム大、 ヒートマップで wow
- 育休給付金 計算 (計算 5本目) — SEO 強だが wow 薄め、 4 連続マネー計算機
- 動物占い (占い 3本目) — Japan-cultural SEO 中だが tech wow 弱
- 漢字検定 (学習 3本目) — SEO 強だが visual 和風 = gift-cap と被るリスク
選んだ理由:
- SEO ボリューム最大: 「タイピング 練習 無料」 「寿司打 代替」 「ローマ字 タイピング」 は学習ジャンルで最強級
- 既存大手は古い UI: 寿司打 / e-typing は数十年同じ UI、 「現代風 ヒートマップ + WebAudio タイプ音 + プログラミング モード」 で差別化
- wow が明確: 「ミスしたキーが赤グラデーション で出る」 視覚フィードバック
- マルチデバイス対応: モバイルでも英文・ローマ字練習可能 (タッチキーボードでも遊べる)
visual direction — §6.1 Visual Audit 16本目の適用
直近 5本の visual を書き出す:
frac-cast — ivory paper + sepia + brass corner + crimson (数学者ノートブック)
patch-pad — walnut + cream + brass + chrome (70s モジュラー シンセ)
doodle-drop — blackboard green + chalk pastels (学校黒板)
side-tax — ledger green + cream + stamp red (帳簿事務所)
atlas-quest — dark navy + amber LED departure (空港 board)
題材 「タイピング / 道場 / 修練」 → motif 候補:
- 古いタイプライター (cream paper + carbon ribbon + brass key + ribbon red) ← 採用
- レーシング (アスファルト + 黄黒チェッカー + 速度メーター) — 平凡
- 80s アーケード (CRT scanlines + neon) — pitch-flip / ascii-bake と被る
- 中世写本 (羊皮紙 + 朱赤 + 金箔) — gift-cap / arcana-flip と被る
採用 3 要素:
- palette: cream paper
#f7eac8+ carbon black ribbon#1a1410+ ribbon red#c92e2e+ brass key#b5933a+ warm tan#8c6b3a+ paper tear shadow- side-tax の paper cream とは ledger green ヘッダー vs sprocket brass で完全別
- frac-cast の brass corner と brass の用途別 (key vs corner cap)
- motif: 古いタイプライター (sprocket dots 紙挿入口 + ribbon ink target line + carriage return chip + ding bell on finish + tear-edge paper shadow)
- typography: Space Grotesk 800 (machine label) + JetBrains Mono (target line + stats readout、 typewriter 風 monospace) + paper-deep ink
技術スタック
入力受付 と Backspace 抑止
const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.metaKey || e.ctrlKey || e.altKey) return
if (e.key === "Backspace") { e.preventDefault(); return } // 修正禁止 (寿司打 形式)
if (e.key.length !== 1) return
e.preventDefault()
const expected = target[typed.length]
const ok = e.key === expected
// ...
}
「ミスを直す癖」 ではなく 「最初から正しく打つ」 訓練のため Backspace 無効。 modifier 付き (Cmd/Ctrl/Alt) は素通し (ブラウザ操作のため)、 印字可能な 1 文字キーのみ判定。
Per-char coloring (4 状態)
{target.split("").map((ch, i) => {
let cls = styles.charPending
if (i < typed.length) cls = styles.charDone // 既入力
else if (i === typed.length) cls = styles.charCurrent // 現在 (赤いハイライト + パルス)
return <span key={i} className={cls}>{ch}</span>
})}
caret 位置は CSS @keyframes で 1s 周期 pulse、 「次にこのキー」 が一目で分かる。 既入力部は文字下に brass 下線、 未入力部は薄文字。
WPM (Words Per Minute) 計算
const words = stats.correct / 5 // 国際標準: 1 word = 5 文字
const minutes = elapsedMs / 60000
const wpm = Math.round(words / Math.max(minutes, 0.0001))
国際タイピングテストと同じ換算。 正確率 (correct / (correct + mistakes)) も同時表示することで 「速いが ミス連発」 を見抜ける。
WebAudio タイプ音 (毎キー押下で短い "clack")
function createKeyClick() {
let ctx: AudioContext | null = null
return () => {
if (!ctx) ctx = new AudioContext()
const now = ctx.currentTime
const osc = ctx.createOscillator()
const g = ctx.createGain()
osc.type = "square"
osc.frequency.setValueAtTime(2200 + Math.random() * 400, now)
osc.frequency.exponentialRampToValueAtTime(380, now + 0.04)
g.gain.setValueAtTime(0.0001, now)
g.gain.exponentialRampToValueAtTime(0.07, now + 0.003)
g.gain.exponentialRampToValueAtTime(0.0001, now + 0.05)
osc.connect(g).connect(ctx.destination)
osc.start(now); osc.stop(now + 0.06)
}
}
square wave + frequency 高速 down-sweep (2200Hz → 380Hz) + 50ms 短い envelope で メカニカル キーボード風 「カチッ」 音。 patch-pad / tone-quest と同じ WebAudio スキルセットを軽量演出として再利用。
QWERTY ミス ヒートマップ
const KB_ROWS = [
["1", "2", ..., "0", "-"],
["q", "w", "e", ..., "p"],
["a", "s", "d", ..., "l"],
["z", "x", "c", ..., "/"],
]
setStats((s) => ({
...s,
missMap: { ...s.missMap, [expected.toLowerCase()]: (s.missMap[expected] ?? 0) + 1 },
}))
ミス時に 「叩くべきだったキー」 を missMap にカウント。 完了後、 QWERTY 4 段配列を画面に描画し、 各キーの背景を rgba(201, 46, 46, t * 0.85) で塗る (t = miss[k] / maxMiss)。 「t / y で よくミスる」 「6/7 が弱い」 などの傾向が一目で見える。
ローマ字モード (IME 不要 Japanese)
{ display: "今日 は いい 天気 です", target: "kyou ha ii tenki desu" }
display には 日本語原文を見せ、 target には 寿司打 形式の ローマ字を持たせる。 ユーザは IME OFF で QWERTY を直接叩く。 古典的 ローマ字入力 と同じ ヘボン式変種 (拗音 = "kyou" / 促音 = 大文字なしの "tt" / 長音 = "ko-hi-" 等を採用)。
やっていない / これからの IMPROVE
- 自由モード (Backspace 可) — 「ミスを許容して通す」 練習用モード
- 時間制限モード (60s / 120s で続ける、 完了文 ごとに 次の文に遷移、 寿司打 形式)
- タイプ音 サンプル切替 (Cherry MX Blue / Brown / Topre 風 / 静音 / Cyber)
- 多文字選択 (ローマ字の "shi" vs "si"、 "tu" vs "tsu" 等の許容)
- 日本語かな入力モード (IME 使う側のユーザー向け)
- キー配列切替 (Dvorak / Colemak)
- WPM 履歴 localStorage 保存 + 推移グラフ (前回比、 30日推移)
- テキスト カスタム入力 (好きな文章 / 教科書 / コードを貼って練習)
- 2人 ライバル モード (WebRTC でリアルタイム対戦、 beam-drop の延長)
- 音声 dictation (Web Speech API で読み上げ → タイプ)
次の SHIP は何 thesis に振るか
Thesis Audit:
type-rush — 学習 (3本目)
frac-cast — シミュレーター (3本目)
patch-pad — ジェネレーター (3本目)
doodle-drop — シミュレーター (2本目)
side-tax — 計算ツール (4本目)
直近 5本で 学習 / シミュレーター 2 / ジェネレーター / 計算。 §3.1 連続 3 はないので safe。 次の候補:
- 計算ツール 5本目 (育休給付金 / 退職金 / 国保 / 年金)
- 占い 3本目 (動物占い / MBTI / 命名占い)
- データ可視化 3本目 (企業ロゴ進化 / 為替 30 年 / 都道府県 GDP)
- ジェネレーター 4本目 (SVG モノグラム / glitch 画像 / グラデーション)
- 8 thesis 残り 1 枠 = server-side AI (ユーザー許可待ち)
[ ./next_action ]
読んだら、 TypeRush を実際に動かす。
この開発ログは TypeRush をどう作ったかの記録です。 読み終わったらそのままサービス本体へ戻って、 実物で価値を確かめてください。