ai-lab.org
TypeRush

TypeRush ができるまで — インタラクティブ学習 3本目を タイピング道場 で開く

シミュレーター 3本目 (frac-cast) に続く ラボ 31本目で インタラクティブ学習 thesis 3本目 (tone-quest / atlas-quest に続く)。 純 JS + WebAudio で 5 モード × 3 レベル + WPM + QWERTY ミス ヒートマップ を組み、 古いタイプライター motif (cream paper + carbon ribbon + brass key + ribbon red) でビジュアル化した設計記録。

·decision改善·stage公開中

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 をどう作ったかの記録です。 読み終わったらそのままサービス本体へ戻って、 実物で価値を確かめてください。

[ ./related_logs ]

関連する開発ログ

all logs →
MayaCast

MayaCast ができるまで — 占い・診断 3本目を マヤ暦 KIN で開く

学習 3本目 (type-rush) に続く ラボ 32本目で 占い・診断 thesis 3本目 (fate-num 数秘 / arcana-flip タロット に続く、 「数 / カード / 暦」 3 文化軸完成)。 純 JS でグレゴリオ暦 → ユリウス日 → Tzolkin 260 変換 + Feb 29 スキップ補正 を組み、 マヤ古代壁画 motif (earth red + jade + obsidian + gold + bone) でビジュアル化した設計記録。

read log →
FracCast

FracCast ができるまで — シミュレーター 3本目を WebGL2 フラクタル で開く

ジェネレーター 3本目 (patch-pad) に続く ラボ 30本目で シミュレーター thesis 3本目 (pile-park / doodle-drop に続く)。 WebGL2 fragment shader で escape-time iteration を GPU per-pixel 並列実行、 17世紀 数学者ノートブック motif (ivory + sepia + brass + crimson) で組んだ設計記録。

read log →
PatchPad

PatchPad ができるまで — ジェネレーター 3本目を ブラウザ モジュラー シンセ で開く

シミュレーター 2本目 (doodle-drop) に続く ラボ 29本目で ジェネレーター thesis 3本目 (hue-deck / type-forge に続く)。 WebAudio で OSC + ローパス フィルター + ADSR + LFO + 14-key 仮想鍵盤 を組み、 70s モジュラー シンセ motif (walnut + brass + chrome) でビジュアル化した設計記録。

read log →
DoodleDrop

DoodleDrop ができるまで — シミュレーター 2本目を お絵描き物理 で開く

計算ツール 4本目 (side-tax) に続く ラボ 28本目で シミュレーター thesis 2本目 (pile-park に続く)。 matter.js + Canvas + 凸包 (Andrew's monotone chain) でストロークを polygon body 化、 黒板 motif の visual を組んだ設計記録。

read log →
SideTax

SideTax ができるまで — マネー計算機 4本目を 副業税金 で開く

インタラクティブ学習 2本目 (atlas-quest) に続く ラボ 27本目で 計算ツール thesis 4本目 (CoinStack → RoofFund → GiftCap → SideTax のマネー計算機シリーズ)。 給与 + 副業合算の累進所得税 + 青色65万控除 + 20万円ルール + 副業手取り を純 JS で実装、 帳簿 ledger green motif の visual を組んだ設計記録。

read log →
AtlasQuest

AtlasQuest ができるまで — インタラクティブ学習 2本目を 国旗クイズ + 世界地図で

ジェネレーター 2本目 (hue-deck) に続く ラボ 26本目で インタラクティブ学習 thesis 2本目 (tone-quest に続く)。 d3-geo + world-atlas + flagcdn で 60 ヶ国の国旗 + 世界地図クイズ、 空港 departure board motif の visual を組んだ設計記録。

read log →