• canvas验证码


      滑块拼图型的验证方式已经流行起来,多数的实现方式是直接加载两张分割好的图片。现在用canvas去自动修剪图片,节省修图工作量和http请求:

    • 加载一张整图,用canvas切割缺口,缺口位置在固定范围内随机
    • 点击刷新按钮重新加载和切割
    • 滑块响应拖动,实时更新缺口位置
    • 拖动结束时计算位置是否匹配,允许一定误差

       DOM结构如下:

     1     <div class="verification">
     2         <div class="verPicture">
     3             <!-- 图片未加载时显示提示 -->
     4             <div class="verLoading">正在加载 ...</div>
     5             <!-- 刷新按钮 -->
     6             <div class="verRefresh" title="刷新"></div>
     7             <!-- 存放图片元素 -->
     8             <canvas id="verCanvas" width="285" height="145"></canvas>
     9         </div>
    10         <div class="verSlider">
    11             <p>向右滑动滑块填充拼图</p>
    12             <!-- 滑块 -->
    13             <div class="verSliderBlock"></div>
    14         </div>
    15     </div>

      图片和canvas大一统一,此例以285*145为准,缺口切成正方形:

        var imgs = ["verify.png", "verify1.png", "verify2.png", "verify3.png", "verify4.png"] // 备用的验证图片
        var imgSrc = imgs[parseInt(Math.random() * 5)]; //随机一个图片地址
        var slider = $(".verSliderBlock")[0];
        var canvas = $("#verCanvas")[0];
        var context = canvas.getContext("2d");
        var img = document.createElement('img');
        var rightDistance; //记录正确的移动距离
        var topDistance; //记录缺口离顶部的距离
        var slideFlag = false; //标记滑块是否处于移动状态
        var origin = 0; //标记移动起始位置的x坐标
        
        // distance标记移动的距离,值改变时触发滑块移动和canvas重绘
        Object.defineProperty(window, "distance", {
            set: function(distance) {
                this.value = distance;
                if (distance > 0 && distance < 246) {
                    $(slider).css("left", distance);
                    draw(distance);
                } else if (distance <= 0) {
                    $(slider).css("left", 0);
                    draw(0);
                } else {
                    $(slider).css("left", 247);
                    draw(247);
                }
            },
            get: function() {
                return this.value;
            }
        });
        initCanvas(imgSrc);
    
        // 刷新事件
        function verRefresh() {
            unbindSlide();
            imgSrc = imgs[parseInt(Math.random() * 5)];
            slideFlag = false;
            distance = 0;
            origin = 0;
            $(".verSlider p").html("向右滑动滑块填充拼图").removeClass();
            initCanvas(imgSrc);
        }
        $(".verRefresh").click(verRefresh);
    
        // 判断位置是否正确,用于滑动结束时
        function judgeDistance() {
            if (distance > rightDistance - 3 && distance < rightDistance + 3) {
                $(slider).css("left", 247);
                $(".verSlider p").html("验证成功").removeClass("hide").addClass("success");
                setTimeout(function() {
                    console.log("success")
                }, 1000)
            } else {
                distance = 0;
                $(".verSlider p").html("验证失败").removeClass("hide").addClass("fail");
                setTimeout(verRefresh, 1000)
            }
        }
    
        /**** 滑动监听 ****/
    
        function onmousedown(e) {
            slideFlag = true;
            $(slider).addClass("active");
            origin = e.x;
        }
    
        function onmousemove(e) {
            if (slideFlag) {
                // 隐藏滑动提示文字
                $(".verSlider p").addClass("hide");
                //计算位置
                distance = e.x - origin;
            }
        }
    
        function onmouseup(e) {
            if (slideFlag) {
                slideFlag = false;
                distance = e.x - origin;
                $(slider).removeClass("active");
                judgeDistance()
            }
        }
    
        function bindSlide() {
            slider.addEventListener("mousedown", onmousedown);
            document.addEventListener("mousemove", onmousemove, true);
            document.addEventListener("mouseup", onmouseup, true);
        }
    
        function unbindSlide() {
            slider.removeEventListener("mousedown", onmousedown);
            document.removeEventListener("mousemove", onmousemove, true);
            document.removeEventListener("mouseup", onmouseup, true);
        }
    
        /**** canvas对象 ****/
        function initCanvas(img_src) {
            $(".verLoading").show();
            img.src = img_src;
            img.onload = function() {
                $(".verLoading").hide();
                bindSlide(slider);
                // 获取随机位置
                rightDistance = parseInt(Math.random() * 100 + 145);
                topDistance = parseInt(Math.random() * 80 + 10);
                draw();
            };
        }
    
        function draw(left) {
            context.clearRect(0, 0, canvas.width, canvas.height)
            // 绘制整图和半透明缺口
            context.drawImage(img, 0, 0, canvas.width, canvas.height);
            context.globalAlpha = 0.9;
            context.fillStyle = "#fff";
            context.fillRect(rightDistance, topDistance, 35, 35);
            context.globalAlpha = 0.5;
            context.strokeStyle = "#000";
            context.lineWidth = 1;
            context.strokeRect(rightDistance, topDistance, 35, 35);
            // 绘制脱离的缺口
            context.globalAlpha = 1;
            context.shadowBlur = 10;
            context.shadowColor = "#fff";
            context.strokeStyle = "#fff";
            context.strokeRect(left || 2, topDistance, 35, 35);
            context.drawImage(img, rightDistance, topDistance, 35, 35, left || 2, topDistance, 35, 35);
        }
    

      

  • 相关阅读:
    xamarin 安卓输出中文错误 乱码解决
    xamarin自定义 application 无法调试
    Xamarin中 ios 修改Assets.xcassets 文件后 无法调试和编译
    xamarin 编译出现Xamarin.Build.Forms.Tasks.GetTaskAbi 无法加载的错误解决方法
    13、最新安卓Xamarin绑定相关填坑之旅
    12、xamarin form中实现H5 网页唤醒微信支付的方法
    11、使用xamarin实现全屏播放rtmp之类的直播视频
    8.在XamarinAndroid上进一步控制包的大小
    Xamarin.Forms 中iOS通过URL Scheme判断应用是否安装
    Xamarin.Android 使用PopupMenu遇到的问题
  • 原文地址:https://www.cnblogs.com/yangshifu/p/9293587.html
Copyright © 2020-2023  润新知