You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 04:10:36