如何使用JavaScript检测6片自定义拼图是否完成?
6片拼图完成检测逻辑实现方案
核心思路
每个拼图块生成时,记录它对应的原始Canvas区域坐标,检测时对比每个块的当前位置与原始位置是否匹配(允许小范围误差,适配拖拽吸附的精度)。
具体实现步骤
1. 给拼图块绑定原始位置信息
在生成每个拼图块的循环里,给partCanvas添加自定义属性,存储它对应的原始x、y坐标:
// 在循环内,创建partCanvas后添加 partCanvas.dataset.originalX = x; partCanvas.dataset.originalY = y;
2. 实现检测完成的函数
编写一个函数,遍历所有拼图块,对比当前位置和原始位置:
function checkPuzzleComplete() { const pieces = document.querySelectorAll('.sampcanvas'); const tolerance = 5; // 允许的位置误差,可根据需求调整 for (let piece of pieces) { // 获取当前块的位置(转为数值) const currentLeft = parseInt(piece.style.left) || 0; const currentTop = parseInt(piece.style.top) || 0; // 获取原始位置(转为数值) const originalX = parseInt(piece.dataset.originalX); const originalY = parseInt(piece.dataset.originalY); // 对比位置,考虑误差范围 if (Math.abs(currentLeft - originalX) > tolerance || Math.abs(currentTop - originalY) > tolerance) { // 有块没归位,返回未完成 return false; } } // 所有块都匹配,返回完成 return true; }
3. 触发检测的时机
可以选择在每次拖拽结束后自动检测,或者添加按钮手动触发:
- 拖拽结束自动检测:修改拖拽初始化代码
$(".sampcanvas").draggable({ snap: true, stop: function() { if (checkPuzzleComplete()) { alert('拼图完成!'); // 可添加完成后的自定义逻辑,比如解锁内容、重置拼图等 } } });
- 手动触发(添加按钮):
<button onclick="checkAndNotify()">检查拼图</button>
function checkAndNotify() { if (checkPuzzleComplete()) { alert('拼图完成!'); } else { alert('还有拼图块没归位哦'); } }
4. 修改原代码整合逻辑
把上述代码整合到原函数中,完整代码示例:
function approved(){ // Get the canvas and context var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); // Load the image var img = new Image(); img.src = document.getElementById('puzzleprieview').src; img.onload = function() { // Set the canvas size canvas.width = img.width; canvas.height = img.height; // Draw the image on the canvas ctx.drawImage(img, 0, 0); // Split the image into parts var w = img.width / 3; var h = img.height / 2; for (var i = 0; i < 6; i++) { // 修正循环条件,生成6块拼图 var x = (i % 3) * w; var y = Math.floor(i / 3) * h; // Create a new canvas for each part var partCanvas = document.createElement("canvas"); partCanvas.draggable="true"; partCanvas.className="sampcanvas"; // 存储原始位置 partCanvas.dataset.originalX = x; partCanvas.dataset.originalY = y; partCanvas.width = w; partCanvas.height = h; var partCtx = partCanvas.getContext("2d"); // Draw the part of the image on the new canvas partCtx.drawImage(canvas, x, y, w, h, 0, 0, w, h); // 随机定位,用块的实际宽高适配不同尺寸 const getRandom = (min, max) => Math.floor(Math.random()*(max-min+1)+min); partCanvas.style.left= getRandom(0, 300 - w)+'px'; partCanvas.style.top = getRandom(0, 300 - h)+'px'; document.getElementById('pieces').appendChild(partCanvas); } // 初始化拖拽并添加结束检测 $(".sampcanvas").draggable({ snap: true, stop: function() { if (checkPuzzleComplete()) { alert('拼图完成!'); } } }); } } // 检测拼图完成的函数 function checkPuzzleComplete() { const pieces = document.querySelectorAll('.sampcanvas'); if (!pieces.length) return false; const tolerance = 5; // 位置误差阈值 for (let piece of pieces) { const currentLeft = parseInt(piece.style.left) || 0; const currentTop = parseInt(piece.style.top) || 0; const originalX = parseInt(piece.dataset.originalX); const originalY = parseInt(piece.dataset.originalY); if (Math.abs(currentLeft - originalX) > tolerance || Math.abs(currentTop - originalY) > tolerance) { return false; } } return true; }
注意事项
- 原代码中循环条件
i < 7会生成7块拼图,改成i < 6对应6片需求 - 随机定位时用拼图块的实际宽高
w、h代替固定值,避免块超出容器 - 误差阈值
tolerance可以根据拖拽吸附的精度调整,确保检测准确
内容的提问来源于stack exchange,提问作者Aswin
相关产品推荐
相关产品推荐

