猫の手ツール

Algorithm & Visual Engineering

CSS背景制御と配列操作による
非破壊的パズルエンジンの実装

「スワップパズル・チェンジ」は、アップロードされた画像を実際に分割して保存するプロセスを一切行いません。CSSの描画特性とJavaScriptの配列操作を組み合わせ、ブラウザ内で動くパズル体験を実現しています。

このツールの入力から出力まで

現行コードの確認日:

入力
写真と分割数を選び、交換する2枚を順にタップします。
処理
画像を切り出したファイルへ分けず、内側要素のleftとtopでピースを表示し、選んだ2つのIDを交換します。
出力
入力は長辺 1000px 以下、盤面は正方形表示、記録は 800×1000px の JPEG(品質指定 0.9)です。

まず確認する点:隣同士の制約や空白はありません。ランダムsortの並びは均等確率を保証せず、盤面の難易度の測定値でもありません。

仕上がりの例

猫の写真から作った入れ替えパズルのプレイ画面です。

元画像・プレイ画面
左は愛猫2匹が並ぶ写真。右は写真を分割してピースを入れ替えたパズル画面。

元画像・プレイ画面

左は愛猫2匹が並ぶ写真。右は写真を分割してピースを入れ替えたパズル画面。

掲載画像はサイトにある既存の公開作例です。保存済みの資料では運営者の愛猫の写真を使用しています。今回の確認日が、この作例を実行した日を表すわけではありません。

保存済み検証記録の条件を見る

資料の種類は「ツールのプレビュー・結果画面を保存した記録」です。公開作例と保存済み記録で素材や色などが異なる場合があるため、下の数値は保存済み検証記録の条件として読んでください。

記録の入力画像
800×667px (JPEG)
記録の画面キャプチャ
441×441px (PNG)
保存済み記録の主な操作・出力条件
画面の項目記録の値現行コードの初期値・範囲
記録の盤面3×3—

資料ファイルの作成日は実行日として扱っていません。個別端末の処理速度や、ほかの写真に対する検出・加工の精度を測定した資料でもありません。

実装の確認箇所:src/pages/game/puzzle/swap/index.astro。以下のコード抜粋と出力条件は、この本番実装に基づいて説明します。

仕組みを読み進めるときは、DOM操作の基礎(要素の生成と表示状態の更新)、イベントリスナーの基礎(タップやドラッグから描画へつなぐ流れ)が参考になります。

1. 内側要素の left / top による仮想スライス

このツールの最大の特徴は、画像をN個のファイルに「切り刻んでいない」ことです。単一の画像URLを使い、グリッド内の各ピース(div)に対して、背景を持つ内側要素のサイズと left / top の位置を計算する手法を採用しています。

メリット: Canvasで画像を切り出し、複数のBlobやデータURLを生成するメモリ負荷の高い処理をスキップできます。これにより、5x5(25ピース)といった高密度な分割でも、読み込みと縮小が終わると同じ画像から盤面を作れます。

配列内の2ピースを交換し、ID と位置がすべて一致するかを調べる例です。

function swapPieces(pieces, first, second) {
  [pieces[first], pieces[second]] = [pieces[second], pieces[first]];
  return pieces.every((piece, index) => piece.id === index);
}

2. 配列の分割代入を用いた2要素のスワップ処理

ユーザーが2つのピースを選択した際の入れ替え処理は、DOMを直接操作するのではなく、データモデル(pieces配列)の操作を起点にしています。JavaScriptの「分割代入(Destructuring Assignment)」を活用することで、一時変数を必要としないクリーンな実装を行っています。

メリット: ステート(状態)の更新が直感的でバグが入りにくくなります。また、クリア判定においても Array.prototype.every を用いて、配列のインデックスとピースのIDを比較するだけの宣言的なコードで完結しています。

3. Canvas API による動的スタンプ合成

クリア時に生成される記録画像は、Canvas APIを使用してブラウザ上で動的にレンダリングされます。元の画像をベースに、ブランドカラーのオーバーレイ、角丸クリッピング、そしてタイムやスワップ回数のテキストをレイヤー状に重ねて合成します。

メリット: サーバーサイドにデータを送信せずにSNSシェア用の高品質画像を生成できるため、ユーザーの写真の合成を端末内で行い、ゲームとしての達成感を視覚的に提供できます。

出力の仕様と確認する点

1枚目を選んでから別のピースをタップすると交換します。同じピースを再度タップすると選択解除。隣同士でなくても交換できるため、スライダーパズルの空白や隣接制限はありません。

シャッフルはランダムな比較関数で sort する実装で、全ての並びが同じ確率で出る保証はありません。交換操作で任意の並びを戻せますが、盤面の難易度や最短手数を調整する処理ではありません。

入力は長辺 1000px 以下、盤面は正方形表示、記録は 800×1000px の JPEG(品質指定 0.9)です。正方形以外の写真は盤面で引き伸ばされる場合があります。タイマーは1秒ごとの加算で、休止中の実時間を正確に測る機能ではありません。