突然ですが、皆さん疲れていませんか?
複雑な要件定義、終わらないデバッグ、迫りくる納期...
そんな現代社会に必要なのは、「知性」を捨てて「本能」に還ることだと思いました。
そこで、入力された言葉をすべて「ワン!」に変換するだけのアプリを、モダンなWeb標準技術をフル活用して作りました。
その名も「犬語変換アプリ」です。
この記事では、このアプリの裏側にある技術スタックを紹介します。
デモサイト
🐕 作ったもの
犬語変換アプリ
人間の言葉を入力すると、AI(という名のランダム関数)が感情豊かに「ワン!」に翻訳してくれます。
主な機能
- 翻訳機能: どんな名文も「ワン!」になります。
- 履歴機能: 過去の遠吠えをIndexedDBに保存します。
- シェア機能: 翻訳結果をXやLINEで拡散できます。
- PWA対応: インストールしてオフラインでも吠えられます。
技術スタック
フレームワーク全盛の時代ですが、今回はあえてVanilla JS (標準機能) の限界に挑みました。
「jQueryもReactもVueも使わない。信じられるのはブラウザ標準APIだけ」という縛りプレイです。
| カテゴリ | 技術 | 用途 |
|---|---|---|
| Component | Web Components | 変換ボタンの完全なカプセル化 |
| Thread | Web Worker | 翻訳処理(文字列置換)の非同期実行 |
| Storage | IndexedDB | 翻訳履歴の永続化 |
| Graphics | Canvas API | 背景の肉球パーティクル物理演算 |
| App | PWA | オフライン動作・インストール対応 |
こだわりの実装ポイント
1. Web Worker で「重い翻訳処理」を非同期化
「テキストを『ワン』に置換するだけなら一瞬では?」
その通りです。
しかし、将来的に「100万文字の小説を一気に犬語にしたい」というニーズがあるかもしれません(ない)。
メインスレッドをブロックしてUIを固まらせないよう、翻訳ロジックは Web Worker に逃がしました。
// script.js (抜粋)
const workerCode = `
self.onmessage = function(e) {
const { text, dogWords } = e.data;
// ... 複雑な(ランダムな)翻訳アルゴリズム ...
self.postMessage({ result: result.join(' ') });
};
`;
const blob = new Blob([workerCode], { type: "application/javascript" });
const worker = new Worker(URL.createObjectURL(blob));
Blob URLを使ってインラインでWorkerを生成する変態実装です。ファイル管理が楽になります。
2. Web Components (Shadow DOM) でボタンを隔離
変換ボタン <dog-button> は Web Components で実装しました。
Shadow DOM を使うことで、外部のCSSの影響を完全に遮断しています。
class DogButton extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
// ...
}
customElements.define('dog-button', DogButton);
これで、どんなに汚いCSS環境に放り込まれても、このボタンだけは高潔な犬としての尊厳(スタイル)を保ち続けます。
3. IndexedDB で「遠吠え履歴」を管理
たかが履歴、されど履歴。
localStorage でも十分ですが、あえて非同期NoSQLデータベースである IndexedDB を採用しました。
class HistoryDB {
constructor() {
this.dbName = 'DogConverterDB';
this.storeName = 'history';
}
// ... PromiseでラップしたCRUD処理 ...
}
「過去に自分が何を吠えたか」を数万件保存してもパフォーマンスが落ちません。誰が得するのかは不明です。
4. Canvas API による物理演算背景
背景でふわふわ浮いている肉球やパーティクル。
これはCSSアニメーションではなく、Canvas API で描画し、JavaScriptで物理演算しています。
さらに、「肉球をクリックすると破裂する」 という無駄なインタラクションも実装しました。
背景のCanvasは pointer-events: none でクリックを透過させていますが、JavaScript側で座標計算を行い、当たり判定を自前で実装しています。
// script.js (抜粋)
checkClick(x, y) {
// 全パーティクルとの距離を計算して当たり判定
for (let i = this.particles.length - 1; i >= 0; i--) {
const p = this.particles[i];
const dist = Math.sqrt((x - p.x)**2 + (y - p.y)**2);
if (dist < p.size * 1.5) {
this.explode(p.x, p.y, p.color); // 爆発エフェクト
this.particles.splice(i, 1);
return true;
}
}
}
無駄に requestAnimationFrame を回して、CPUリソースを消費して「癒やし」を提供します。
まとめ
「ネタアプリこそ、本気で作る」
これが今回のテーマでした。
普段の業務ではライブラリに頼りがちな部分を、あえて標準APIだけで実装してみると、ブラウザの進化や基礎技術の重要性に改めて気づかされます。
このアプリが、皆さんの殺伐としたタイムラインに一瞬の「ワン!」をもたらすことを願っています。
もし気に入ったらいいねとストック、フォローをお願いしますワン!
