原生js自己做的滑动拼图解锁

当然,里面一些效果还是要根据自己所需要的来修改,大体功能完善了而已。

拼图也可以进行随机,多准备几张图,设置img src随机数组

代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>简易滑动拼图解锁</title>
    <style>
        * {
            margin: 0px;
            padding: 0px;
        }
        
        img,
        canvas {
            width: 300px;
            height: 200px;
        }
        
        img {
            display: none;
        }
        
        #myCanvas {
            position: absolute;
            float: left;
        }
        
        .verify {
            position: relative;
            width: 300px;
            height: 50px;
            background-color: pink;
            line-height: 50px;
            text-align: center;
            color: #fff;
        }
        
        .verify .slide {
            position: absolute;
            width: 55px;
            height: 50px;
            background-color: skyblue;
        }
        /* position:relative 移动端左移会滑动 */
        /* position:fixed 解决左移滑动问题*/
        
        .lockBox {
            position: fixed;
        }
        
        .bigBox {
            width: 300px;
            margin: 10px auto;
        }
    </style>
</head>

<body>
    <div class="bigBox">
        <!-- 图片 -->
        <div class="lockBox">
            <div class="topCanvas">
                <img src="../beauty.png" alt="随机拼图">
                <canvas id="myCanvas"></canvas>
                <canvas id="block"></canvas>
            </div>
            <!-- 滑块 -->
            <div class="verify">
                <!-- 滑块 -->
                <div class="slide">
                </div>
            </div>
        </div>
    </div>
    <script>
        const w = 300 // canvas宽度
        const h = 200 // canvas高度
        const l = 55 // 滑块边长
        const r = 9 // 滑块半径
        const PI = Math.PI
        const L = l + r * 2 + 3 // 滑块实际边长

        // 拼图滑块
        var c = document.querySelector("#myCanvas");
        var ctx = c.getContext("2d");

        // 拼图背景图
        var c2 = document.querySelector("#block");
        var ctx2 = c2.getContext("2d");
        var img = document.querySelector("img");

        // 绘制拼图背景
        function drawImage() {
            ctx.drawImage(img, 0, 0, 300, 200);
            ctx2.drawImage(img, 0, 0, 300, 200);
        }

        img.onload = function() {
            // 初始化拼图
            drawImage();
        }

        // 拼图滑块挖掘
        function drawPath(ctx, x, y, operation) {
            ctx.beginPath()
            ctx.moveTo(x, y)
            ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
            ctx.lineTo(x + l, y)
            ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
            ctx.lineTo(x + l, y + l)
            ctx.lineTo(x, y + l)
            ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
            ctx.lineTo(x, y)
            ctx.lineWidth = 2
            ctx.fillStyle = 'rgba(255, 255, 255, 0.7)'
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)'
            ctx.stroke()
            ctx.globalCompositeOperation = 'destination-over'; //重要
            operation === 'fill' ? ctx.fill() : ctx.clip()
        }

        // 随机位置但是要同高度
        function randomNum(start, end) {
            return Math.floor(Math.random() * (end - start) + start);
        }

        // 随机位置创建拼图
        let x = randomNum(L + 10, w - L - 20);
        let y = randomNum(10 + 2 * r, h - L - 20);

        // 不动的挖空
        drawPath(ctx2, x, y, 'fill');
        // 滑块切割,
        drawPath(ctx, x, y, 'clip');
        // 控制同等高度,定位在左边
        document.querySelector("#myCanvas").style.left = -x + 'px';
        // 网页端滑动解锁 事件
        // 监听滑块事件
        document.querySelector(".slide").onmousedown = function(e) {
                document.onmousemove = function(e2) {
                    // 最大滑动距离为下方盒子长-滑块长
                    //范围内拖动
                    if (e2.clientX > e.clientX && e2.clientX - e.clientX <= w - L + 10) {
                        // 使得滑块和拼图一起动
                        document.querySelector(".slide").style.left = e2.clientX - e.clientX + 'px';
                        document.querySelector("#myCanvas").style.left = -x + e2.clientX - e.clientX + 'px';
                    }
                    document.onmouseup = function() {
                        // 判断拼图位置是否正确,拖拉距离是否是随机生成的拼图x
                        let result = false;
                        // 正确提示正确,误差为10以内为正确
                        if (e2.clientX - e.clientX - 10 <= x && x <= e2.clientX - e.clientX + 10) {
                            result = true;
                            // alert("验证成功!");
                            // 滑块消失
                            document.querySelector(".slide").style.display = "none";
                            document.querySelector(".verify").innerHTML = "解锁成功!";
                        } else {
                            // 不正确提示不正确,且返回原点
                            alert("验证失败");
                            // 滑块消失
                            // 重新刷新
                            location.reload();
                        }
                        // 解除以下事件
                        document.onmousemove = null;
                        document.onmouseup = null;
                    }
                }
            }
            // 移动端
        document.querySelector(".slide").ontouchstart = function(e) {
            let touch = e.targetTouches[0];
            document.ontouchmove = function(e2) {
                let touch2 = e2.targetTouches[0];
                // 最大滑动距离为下方盒子长-滑块长
                //范围内拖动
                if (touch2.pageX > touch.pageX && touch2.pageX - touch.pageX <= w - L + 10) {
                    // 使得滑块和拼图一起动
                    document.querySelector(".slide").style.left = touch2.pageX - touch.pageX + 'px';
                    document.querySelector("#myCanvas").style.left = -x + touch2.pageX - touch.pageX + 'px';

                }
                document.ontouchend = function() {
                    // 判断拼图位置是否正确,拖拉距离是否是随机生成的拼图x
                    let result = false;
                    // 正确提示正确,误差为10以内为正确
                    if (touch2.pageX - touch.pageX - 10 <= x && x <= touch2.pageX - touch.pageX + 10) {
                        result = true;
                        // 滑块消失
                        document.querySelector(".slide").style.display = "none";
                        document.querySelector(".verify").innerHTML = "解锁成功!";
                    } else {
                        // 重新刷新
                        location.reload();
                    }

                    // 解除以下事件            
                    document.ontouchmove = null;
                    document.ontouchend = null;
                }
            }
        }
    </script>
</body>

</html>

上效果图:

滑动前:

 (拖蓝色滑块便可以进行滑动)

滑动成功:

滑动失败:(目前设置了直接刷新,可以根据自己实际情况修改)

猜你喜欢

转载自blog.csdn.net/enhenglhm/article/details/123291331