ジグソーパズル
2025年3月25日
みなさんこんにちは。
ケミストのWeb担当みやのです。
ここ最近「スライドパズル」を作っていましたが、今回はいよいよ「ジグソーパズル」に挑戦してみたいと思います。
jigsawとは「糸鋸」という意味です。昔は木の板を糸鋸で切って作られていたのが名前の由来だそうです(Wikipediaより)
snap-puzzle.jsを入手する
今回はjQueryプラグイン「snap-puzzle.js」を使います。
GitHubからjsを入手します。
「jQuery1」「jQuery UI」「jQuery UI Touch Punch」を呼び出し、一番最後にsnap-puzzle.jsを設置します。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
<script src="js/jquery.snap-puzzle.js"></script>
jQuery3では動きませんでした。
HTML
HTMLは以下の通りです。
<div id="puzzle-containment">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
<div>
<img id="source_image" class="pure-img" src="img/hayabusa.jpg" alt="Puzzle Image">
</div>
</div>
<div class="pure-u-1 pure-u-md-1-2">
<div id="pile" class="snappuzzle-pile">
<div id="puzzle_solved">
<h4>完成!</h4>
<button class="restart-puzzle" data-grid="3">リスタート(3×3)</button>
<button class="restart-puzzle" data-grid="4">リスタート(4×4)</button>
<button class="restart-puzzle" data-grid="5">リスタート(5×5)</button>
</div>
</div>
</div>
</div>
</div>
#puzzle-containmentはフィールド全体
#source_imageはお手本画像
#pileはバラバラになったピース置き場
#puzzle_splvedはクリア後に表示されるメッセージとボタン
です。
今回は用意する画像は1枚でよくて、正方形である必要もありません。
CSS
ヘッダー内で「Pure.css」を呼び出しておきます。
<link rel="stylesheet" href="https://cdn.rawgit.com/yahoo/pure-release/v0.6.0/pure-min.css">
<link rel="stylesheet" href="https://cdn.rawgit.com/yahoo/pure-release/v0.6.0/grids-responsive-min.css">
追加のCSSは以下の通りです。
.snappuzzle-wrap {
position: relative;
display: block;
}
.snappuzzle-pile {
position: relative;
}
.snappuzzle-piece {
cursor:-moz-grab;
cursor:-webkit-grab;
cursor: grab;
}
.snappuzzle-piece:active {
cursor:-moz-grabbing;
cursor:-webkit-grabbing;
cursor: grabbing;
}
.snappuzzle-slot {
position: absolute;
background: #fff;
opacity: .8;
}
.snappuzzle-slot-hover {
background: #eee;
}
#puzzle-containment {
background: #fafafa;
padding: 10px;
text-align: center;
}
#pile {
margin: 10px;
}
#puzzle_solved {
display: none;
text-align: center;
position: relative;
top: 25%;
}
cursor:grabとgrabbingって初めて使いました。
JavaScript
スクリプトは以下の通りです。
function start_puzzle(x){
$('#puzzle_solved').hide();
$('#source_image').snapPuzzle({
rows: x,
columns: x,
pile: '#pile',
containment: '#puzzle-containment',
onComplete: function() {
$('#source_image').fadeOut(150).fadeIn();
$('#puzzle_solved').show();
fireworks();
}
});
}
$(function(){
$('#pile').height($('#source_image').height());
start_puzzle(3);
$('.restart-puzzle').click(function() {
stopFireworks();
$('#source_image').snapPuzzle('destroy');
start_puzzle($(this).data('grid'));
});
$(window).resize(function(){
$('#pile').height($('#source_image').height());
$('#source_image').snapPuzzle('refresh');
});
});
どういう原理かわかりませんが、ボタンに設定したdata-gridに応じて、リスタート時のピース数を変更できます。
今後の課題
・本物のジグソーパズルのようにピースの形を凹凸にする
・タイマーを設置し、制限時間を設定する
・ストップウォッチを設置し、クリア後にランク表示
・好きな画像をアップロードしたらそれがパズルになる機能
・パズル開始前に難易度(ピース数やお手本画像のオンオフ)を設定できる機能
いつか挑戦してみたいです!


