01. Web開発における「ライブラリ肥大化」への抵抗:線を1本引くのに数百KBも必要か?
最近のWeb開発における「とりあえずフルセットのライブラリを入れる」という風潮には、少し違和感を感じています。
「ちょっとしたお絵描き機能を作りたい」と思ってコミュニティを覗くと、決まって PixiJS や Three.js、Fabric.js が推奨されます。もちろん、それらは素晴らしいライブラリですが、単に線を引くだけのために数百KB、時には数MBものJSパッケージを読み込む必要があるのでしょうか?単純なインタラクションのために重厚なエンジンを導入するのは、エンジニアリングとしては少し「怠慢」ではないかとさえ思ってしまいます。
開発者の真の力は、「どれだけAPIを叩けるか」ではなく、**「生のCanvas(Vanilla JS)でどれだけエッジの効いた実装ができるか」**にあるはずです。
最近見つけた WigglyPaint の実装は、まさにその「引き算の美学」を体現していました。初期の Decker にインスパイアされた極限までシンプルなロジック。これこそが、ネイティブなWeb技術だけでパフォーマンスと表現力を両立できることの証明です。
02. 低レイヤーの設計:なぜ [{x,y}] という書き方をやめるべきなのか?
Canvasで秒間60フレームのリアルタイムレンダリングを実現したいなら、まずデータ構造から見直すべきです。
平面配列 vs オブジェクト配列
多くの人は [{x:1, y:1}, {x:2, y:2}] のようなオブジェクトの配列を使いがちです。直感的ではありますが、数万個の点を扱う場合、これは GC(ガベージコレクション) の悪夢を招きます。ブラウザが小さなオブジェクトの生成と破棄を繰り返すことで、メインスレッドにラグが発生する原因になります。
WigglyPaintの設計はもっと硬派です。Lil言語の考え方を取り入れ、ベクトル的な思考を採用しています。つまり、座標をすべて1つの連続した配列としてフラットに保持するのです:[x1, y1, x2, y2, x3, y3...]。
なぜこれが圧倒的に速いのか?
-
GCフレンドリー: 1つの大きな
Float32Arrayは、数万個の小さなオブジェクトよりもメモリ上で安定しており、バタつき(ジッター)がほぼ発生しません。 - キャッシュフレンドリー(Cache-friendliness): CPUは連続したメモリを読み込む際、参照を飛び回るよりも遥かに高速に処理できます。百万単位の点計算を行う場合、この低レイヤーの最適化がもたらすパフォーマンスの差は圧倒的です。
03. アルゴリズムの核心:サイン波で線に「魂」を吹き込む
「どうしてあんなに自然に線がうねるのか?」と不思議に思うかもしれません。その数学的ロジックは非常に純粋です。
線は「乱れている」のではなく「オフセット」している
Math.random() で動かしてしまうと、線は古いテレビの砂嵐のようにチカチカするだけです。WigglyPaintの核心は、時間に依存した**サイン波による揺らぎ(擾乱)**です。
コードレベルのロジックは、各座標点にオフセット値を加えるだけです:
$$newX = x + \sin(time \times frequency + offset) \times amplitude$$
ここに3つの重要な変数があります:
- 周波数 (Frequency): 線が「震える」速度を決めます。ゆっくりとしたうねりか、高速な震えかは、このパラメータ次第です。
- 振幅 (Amplitude): 線が動く物理的な距離を決めます。振幅が大きいほど、うねりはダイナミックになります。
-
位相差 (Phase Shift): これが最も重要です。すべての線に同じ
timeを与えると、ラジオ体操のように全員が同じ動きをしてしまい、非常に不自然です。WigglyPaintは各線に異なる初期位相を与えることで、動きに先後関係を持たせ、生物のような「生きた動き」を生み出しています。
このアルゴリズムの素晴らしい点は、極めて小さな計算コストで、極めて複雑な視覚的フィードバックを得られることです。これこそがハードコアな技術者が追求すべきエレガンスです。
04. パフォーマンスの極限:Webで60FPSを維持するための「ハック」
無駄な全量再描画を避ける
毎フレーム clearRect ですべてを消して描き直すのは、点が増えた瞬間にCPUを死滅させます。WigglyPaintでは、描画レイヤーを分離したり、更新が必要なパスだけを再計算したりすることで、計算負荷を極限まで削っています。
OffscreenCanvas による次元の違うアプローチ
さらに追求するなら OffscreenCanvas です。レンダリングタスクをメインスレッドから切り離し、Web Workerで実行します。これにより、重い計算中もページのスクロールやクリックが一切カクつかず、滑らかな操作感を維持できます。
05. クロスプラットフォーム:iPadを真の「クリエイティブ端末」にする
Webでのお絵描きツールがネイティブアプリに劣ると言われるのは、多くの開発者がいまだに mousedown や touchstart を使っているからです。
Pointer Events API:魂をキャッチする
Apple Pencilの感触を再現するには、 Pointer Events API が不可欠です。単なるクリックだけでなく、 pressure(筆圧)や tilt(傾き)をリアルタイムで取得します。
WigglyPaintは、この筆圧データをサイン波のパラメータにダイレクトにマッピングしています。筆を強く押し込めばうねりが激しくなり、軽く流せば繊細に震える。「自分の筆圧に線が応えてくれる」という感覚が、没入感を生むのです。
06. 結論:Webエンジニアリングにおける「引き算の芸術」
結局のところ、**「強力な機能に、巨大なサイズは必ずしも必要ない」**ということです。
肥大化したJSパッケージが当たり前になった現代において、WigglyPaintは爽快なまでの「技術的な回帰」を示してくれました。Canvasを理解し、数学に立ち返れば、外部フレームワークに頼らなくても最高に面白い体験は作れます。
余計なものを削ぎ落とした先にある美しさ。それを体験しに、ぜひ WigglyPaint.com を覗いてみてください。そして、そのオープンソースの思想に触れてみてください。
