canvas实现滑块验证码,无需任何插件

无需插件,简简单单几行代码实现滑块验证码

话不多说,老规矩,先上Demo,预览地址:blogai.cn

再放几张预览图:
在这里插入图片描述
在这里插入图片描述


该功能的实现大概有以下几步:

  1. canvas 创建两个一样的画布,储存验证图
  2. 相同坐标通过fill,clip截取两个验证块
  3. 监听鼠标按下事件,记录初始X坐标
  4. 监听鼠标移动事件,记录下移动坐标,验证块随着移动
  5. 监听鼠标松开事件,记录结束X坐标
  6. 对比移动距离和裁剪时的x坐标
  7. 判断差值是否可忽略
  • canvas 创建两个一样的画布,储存验证图

const canvas = document.getElementById('canvas'),
            block = document.getElementById('block');

        let ctx_c = canvas.getContext('2d'),
            ctx_b = block.getContext('2d'),
            img = document.createElement('img');
        img.src = 'car.jpg';
        img.onload = function () {
            ctx_c.drawImage(img, 0, 0, canvas.width, canvas.height);
            ctx_b.drawImage(img, 0, 0, canvas.width, canvas.height);

  • 相同坐标通过fill,clip裁剪两块画布

 let l = 40, //拼接块边长
            x = 150 + Math.random() * (canvas.width - 150 - l), //裁剪横坐标,这样可以保证裁剪的拼接块横坐标在150以后,保证充分拖动距离
            y = 10 + Math.random() * (canvas.height - l - 10);  // y轴坐标
        //裁剪拼接块
        function cut_i(ctx) {
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x, y + l);
            ctx.lineTo(x + l, y + l);
            ctx.lineTo(x + l, y);
            ctx.clip()
        }
        //裁剪主画布
        function fill_i(ctx) {
            // ctx.fillStyle = '#fff';
            ctx.beginPath();
            ctx.moveTo(x, y);
            ctx.lineTo(x, y + l);
            ctx.lineTo(x + l, y + l);
            ctx.lineTo(x + l, y);
            ctx.fillStyle = '#306e7c';  //这里无所谓,随便填
            ctx.globalCompositeOperation = 'xor'; //使裁剪区域透明
            ctx.fill()
        }

        cut_i(ctx_b);
        fill_i(ctx_c);
  • 监听鼠标按下事件,记录初始X坐标

let mousemove = false, 
            starX = 0;
        move_block.addEventListener('mousedown', function (e) { //监听鼠标按下
            e.preventDefault();
            mousemove = true;
            starX = e.clientX   //记录开始时的坐标

        });
  • 监听鼠标移动事件,记录下移动坐标,验证块随着移动

move_block.addEventListener('mousemove', function (e) {//监听鼠标移动
            if (mousemove) {
                let move_x = e.clientX - starX;  //移动距离
                if (move_x > canvas.width - l) {
                    move_x = canvas.width - l;
                } else if (move_x < 0) {
                    move_x = 0;
                }

                block.style.left = move_x + 'px';
                move.style.left = move_x + 'px';
                background_.style.left = (move_x - 400) + 'px'; //overflow:hidden 藏在外面的绿色背景
  • 监听鼠标松开事件,记录结束X坐标,判断

move_block.addEventListener('mouseup', function (res) {//鼠标松开
                    if (Math.abs(move_x - x) < 2) {//可接受差错值:大于小于2
                        mousemove = false;
                        background_.style.left = 0;
                        success.style.zIndex = 1;
                    } else {
                        move_x = 0;
                        mousemove = false;
                        block.style.left = 0;
                        move.style.left = 0;
                        background_.style.left = '-400px';
                    }
                })

完整代码在:github.

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值