前端滑块验证码

1.随机滑块位置
2.绘制背景,随机位置扣滑块
3.绘制滑块
4.事件处理

示例:
在这里插入图片描述

1.html代码

<!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>Document</title>
    <link rel="stylesheet" href="./005.css">
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        body,
        html {
            /* background: #000; */
            height: 100%;
            width: 100%;
        }

        .box {
            width: 800px;
            height: 500px;
            position: relative;
        }
       
    </style>
</head>

<body>
    <div class="box">
    </div>
    <button id="btn" >shuaxin </button>
</body>
<script src="./005.js"></script>
<script>
    let box = document.querySelector(".box");
    let successCallback=()=>{
        alert("success");
        init.handleinit()
    }
    let errorCallback=()=>{
        alert("error");
        init.handleinit()
    }
    let imgs=["../img/lyf.webp"]
    let init=new Init(box,successCallback,errorCallback,imgs);
    console.log(init)
    document.getElementById("btn").onclick=()=>{
        init.handleinit()
    }
</script>

</html>

2.js代码

//props  
// element:Element  
// successCallback:Function  
// errorCallback:Function   
// imgs:Arroy
function Init(element, successCallback, errorCallback, imgs) {
    //容器宽度大于200高度大于100

    let boxW = element.offsetWidth, boxH = element.offsetHeight;
    let bigw = boxW, bigh = boxH - 60;
    let smallw = 70, smallh = boxH - 60;
    let errorValue = 5;
    let x = 200, y = 200;

    // 创建canvas背景
    let canvasbg = document.createElement("canvas");
    canvasbg.setAttribute("id", "canvasbg")
    canvasbg.setAttribute("width", bigw)
    canvasbg.setAttribute("height", bigh)
    box.appendChild(canvasbg)
    // 创建canvas滑块
    let canvas = document.createElement("canvas");
    canvas.setAttribute("id", "canvas")
    canvas.setAttribute("width", smallw)
    canvas.setAttribute("height", smallh)
    box.appendChild(canvas)
    // 创建下方滑块轨迹
    let codecanvas = document.createElement("canvas");
    codecanvas.setAttribute("id", "codecanvas")
    codecanvas.setAttribute("width", "50")
    codecanvas.setAttribute("height", "50")
    box.appendChild(codecanvas);
    let code = document.createElement("div");
    code.setAttribute("class", "code");
    code.appendChild(codecanvas)
    let codebox = document.createElement("div");
    codebox.setAttribute("class", "codebox")
    codebox.appendChild(code)
    let bottomcode = document.createElement("div");
    bottomcode.setAttribute("class", "bottomcode")
    bottomcode.appendChild(codebox);
    box.appendChild(bottomcode)
    let imgsrc = ""
    // 处理图片问题
    function handleImgs() {
        if (imgs && imgs.length > 0) {
            let index = handleRandom(0, imgs.length - 1);
            console.log(index)
            imgsrc = imgs[index]
        } else {
            // 默认图片源自己搞定
            imgsrc = ""
        }
    }


    // 处理canvas背景
    // let canvasbg = document.getElementById("canvasbg");
    let ctxbg = canvasbg.getContext("2d");

    function drawBg() {
        ctxbg.save()
        let imgbg = new Image();
        imgbg.src = imgsrc;
        imgbg.onload = () => {
            ctxbg.drawImage(imgbg, 0, 0, bigw, bigh);
            // 拼图形状
            ctxbg.beginPath();
            ctxbg.moveTo(x, y);
            ctxbg.lineTo(x + 15, y);
            ctxbg.arc(x + 25, y, 10, Math.PI, 2 * Math.PI, false);
            ctxbg.lineTo(x + 50, y);
            ctxbg.lineTo(x + 50, y + 15);
            ctxbg.arc(x + 50, y + 25, 10, Math.PI * 3 / 2, Math.PI / 2, false);
            ctxbg.lineTo(x + 50, y + 50);
            ctxbg.lineTo(x, y + 50);
            ctxbg.lineTo(x, y + 50 - 15);
            ctxbg.arc(x, y + 25, 10, Math.PI / 2, Math.PI * 3 / 2, true);
            ctxbg.lineTo(x, y);
            ctxbg.fillStyle = "rgba(255,255,255,0.8)"
            ctxbg.fill()
        }
    }

    //处理canvas滑块
    // let canvas = document.getElementById("canvas");
    let ctx = canvas.getContext("2d")
  
    // 拼图形状

    function drawCode() {
        console.log(y)
        ctx.save()
      
        let heart = new Path2D()
        heart.moveTo(0, y);
        heart.lineTo(0 + 15, y);
        heart.arc(0 + 25, y, 10, Math.PI, 2 * Math.PI, false);
        heart.lineTo(0 + 50, y);
        heart.lineTo(0 + 50, y + 15);
        heart.arc(0 + 50, y + 25, 10, Math.PI * 3 / 2, Math.PI / 2, false);
        heart.lineTo(0 + 50, y + 50);
        heart.lineTo(0, y + 50);
        heart.lineTo(0, y + 50 - 15);
        heart.arc(0, y + 25, 10, Math.PI / 2, Math.PI * 3 / 2, true);
        heart.lineTo(0, y);
        ctx.clip(heart)
        let img = new Image();
        img.src = imgsrc;
        img.onload = () => {
            // ctx.drawImage(img, x, y, 50, 50, 0, y, 50, 50);
            let imgw = img.width;
            let imgh = img.height;
            ctx.drawImage(img, x / bigw * imgw, 0, smallw / bigw * imgw, smallh / bigh * imgh, 0, 0, smallw, smallh);
            ctx.strokeStyle = 'rgba(255,255,255,0.8)';
            ctx.lineWidth = 2;
            ctx.stroke(heart);
        }
    }

    // 处理滑块鼠标事件
    let flag = false;
    canvas.onmousedown = (e) => {
        flag = true;
    }
    let body = document.getElementsByTagName("body")[0]
    body.onmouseup = () => {
        if (flag) {
            flag = false;
            if (canvas.offsetLeft > x - errorValue && canvas.offsetLeft < x + errorValue) {
                if (successCallback) {
                    successCallback()
                } else {
                    fixCodeBox("success")
                    wait(() => { fixCanvasCoordinate(0) }, 1000)
                }


            } else {
                if (errorCallback) {
                    errorCallback()
                } else {
                    fixCodeBox("error")
                    wait(() => { fixCanvasCoordinate(0) }, 1000)
                }

            }
        }

    }
    body.onmousemove = (e) => {
        if (flag) {
            let left = e.clientX - canvasbg.getBoundingClientRect().left;

            if (left > bigw - smallw / 2) {
                return false
            }
            if (left < smallw / 2) {
                return false
            }
            fixCanvasCoordinate(left - smallw / 2)
        }
    }
    // 处理下方滑块鼠标事件
    let codeBox = document.querySelector(".codebox");
    let codeBoxWidth = codeBox.offsetWidth;
    // let code = document.querySelector(".code");
    code.onmousedown = (e) => {
        flag = true;
    }
    // 修改下方滑块轨迹颜色
    function fixCodeBox(type) {
        if (type == "success") {
            codeBox.style.background = "rgb(63, 247, 78)"
        } else if (type == "error") {
            codeBox.style.background = "rgb(223, 86, 161)"
        } else {
            codeBox.style.background = "rgb(0,150,200)"
        }
    }
    // 修改canvas位置
    fixCanvasCoordinate = (num = 0) => {
        canvas.style.left = num + "px"
        codeBox.style.width = (codeBoxWidth + num) + "px"
    }
    function wait(func, time) {
        let timer = setTimeout(() => {
            func();
            fixCodeBox()
            clearTimeout(timer)
        }, time)
    }
    // 随机整数,最小值和范围
    function handleRandom(min, range) {
        return Math.floor(Math.random() * (range + 1) + min)
    }
    //绘制箭头
    // let codecanvas = document.getElementById("codecanvas");
    let codecanvastx = codecanvas.getContext("2d");
    function drawArrow() {
        codecanvastx.moveTo(10, 23);
        codecanvastx.lineTo(30, 23);
        codecanvastx.lineTo(30, 18);
        codecanvastx.lineTo(40, 25.5);
        codecanvastx.lineTo(30, 33);
        codecanvastx.lineTo(30, 28);
        codecanvastx.lineTo(10, 28);
        codecanvastx.lineTo(10, 23);
        codecanvastx.fillStyle = "rgba(0,0,0,0.8)"
        codecanvastx.fill();
    }
    this.handleinit = () => {
        fixCanvasCoordinate(0)
        // 初始化
        ctx.restore()
        ctxbg.restore()
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        ctxbg.clearRect(0, 0, canvasbg.width, canvasbg.height)
        x = handleRandom(100, bigw - 100 - smallw);
        y = handleRandom(70, bigh - 70 - smallw);
        handleImgs();
        drawArrow();
        drawBg();
        drawCode();
    }

    x = handleRandom(100, bigw - 100 - smallw);
    y = handleRandom(70, bigh - 70 - smallw);
    handleImgs();
    drawArrow();
    drawBg();
    drawCode();

}

3.css

#canvasbg{
    position: absolute;
    left: 0px;
    top: 0px;
}
#canvas {
    position: absolute;
    left: 0px;
    top: 0px;
    
}

.bottomcode {
    width: 100%;
    height: 55px;
    box-sizing: border-box;
    border: 1px solid #ddd;
    border-radius: 3px;
    background-color: #fff;
    position: absolute;
    left: 0px;
    bottom:0px;

}

.codebox {
    width: 52px;
    height: 54px;
    position: relative;
    box-sizing: border-box;
    border: 1px solid #ddd;
    background: rgb(0, 150, 200);
    border-radius: 3px;
}

.code {
    width: 50px;
    height: 52px;
    line-height: 52px;
    text-align: center;
    /* border: 1px solid #000; */
    border-radius: 3px;
    box-sizing: border-box;
    cursor: pointer;
    position: absolute;
    right: 0;
    background: #fff;

}```

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值