Algorithm & UI/UX
Canvas座標変換と動的スケーリングによる「自由なレイアウト合成」の実装
本ツールでは、静的な画像合成ではなく、ユーザーがマウスやタップで「値札の位置を自由に動かせる」インタラクティブな体験を重視しています。デバイスを問わず、高画質な合成結果を得るためのスケーリング手法について技術的な裏側を解説します。
1. 解像度に依存しない「相対スケーリング」エンジンの構築
ユーザーが読み込む画像の解像度は、数百ピクセルから数千ピクセルまで幅があります。固定のピクセル値で値札を描画すると、高解像度画像では値札が豆粒のように小さくなってしまいます。
本実装では、描画領域の横幅を基準とした scale 変数を算出し、すべての描画(矩形のサイズ、角丸の半径、フォントサイズ、オフセット)にこの係数を掛けることで、どんな解像度の画像でも「見た目の比率」を一定に保つ設計にしています。
// 描画時のスケーリング算出のコンセプト
function renderTag(ctx, canvasWidth, userScaleInput) {
// Canvasの横幅に基づいた基準スケールの算出
const baseScale = (canvasWidth / // 基準となる解像度定数) * userScaleInput;
// すべてのサイズ計算にこのスケールを適用
const tagWidth = // 基準幅 * baseScale;
const tagHeight = // 基準高さ * baseScale;
const cornerRadius = // 基準角丸 * baseScale;
// 描画実行(疑似コード)
// ここに roundRect や fillText などの描画処理が入ります
}
2. タッチ/マウス共通の正規化座標変換
Canvas上の「ドラッグ操作」を実現するには、画面上のタッチ座標をCanvas内の内部座標系に正確に変換する必要があります。特に、ブラウザがCanvasをCSSで伸縮させて表示している場合(w-fullなど)、単純な座標取得ではズレが生じます。
本ツールでは getBoundingClientRect で取得した実際の表示サイズと、Canvasが持つ internal width/height の比率を用いて、入力座標を正規化しています。これにより、PCでもスマホでも、指で触れた場所にピタリと値札が吸い付く操作感を実現しました。
// 表示領域と内部解像度の差を補正する座標取得
function getNormalizedCoords(event, canvas) {
const rect = canvas.getBoundingClientRect();
const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;
const clientY = 'touches' in event ? event.touches[0].clientY : event.clientY;
return {
// 表示上の位置(%)を内部のピクセル座標に変換
x: (clientX - rect.left) * (canvas.width / rect.width),
y: (clientY - rect.top) * (canvas.height / rect.height)
};
}
3. dynamic import による HEIC 変換の最適化
iPhoneで撮影された写真(HEIC形式)はブラウザ標準では表示できませんが、変換ライブラリを常に読み込むと、不要なユーザー(Android/PC)に対しても数MBの通信が発生してしまいます。
本実装では import('heic2any') による動的インポートを採用し、ユーザーがアップロードしたファイルの拡張子が HEIC であることを検知した瞬間にのみライブラリをロードします。これにより、初期ロード速度の向上と、Appleデバイスへの完全対応を両立させています。
// 必要時のみライブラリをロードする戦略
async function processInputFile(file) {
if (file.name.toLowerCase().match(/\.(heic|heif)$/)) {
// 重い変換ライブラリを非同期でロード
const heicConverter = await import('heic2any');
// 独自の変換パラメータでブラウザ内処理
// ここに blob への変換ロジックが入ります
}
// ...
}
Developer's Note
ハンドメイド作家の方々がSNSで作品を投稿する際、「ブランドの世界観を守りつつ、情報をスマートに伝える」ことを助けたいという思いからこのツールを作りました。
こだわりは、あえて「固定位置」にせずドラッグ可能にした点です。写真の主役(被写体)は作品ごとに位置が異なります。それを邪魔せず、かつ一番オシャレに見える場所に値札を置ける自由度こそが、このツールの本質だと考えています。また、すべてをブラウザ内で完結させることで、未発表の新作写真をサーバーに送ることなく安心して加工できるプライバシー性も死守しました。