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

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

  DOM结构如下:

     <div class="verification">
<div class="verPicture">
<!-- 图片未加载时显示提示 -->
<div class="verLoading">正在加载 ...</div>
<!-- 刷新按钮 -->
<div class="verRefresh" title="刷新"></div>
<!-- 存放图片元素 -->
<canvas id="verCanvas" width="285" height="145"></canvas>
</div>
<div class="verSlider">
<p>向右滑动滑块填充拼图</p>
<!-- 滑块 -->
<div class="verSliderBlock"></div>
</div>
</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);
}

  

canvas验证码 - 滑块拼图的更多相关文章

  1. python3 使用OpenCV计算滑块拼图验证码缺口位置

    前言 滑块拼图验证码的失败难度在于每次图片上缺口位置不一样,需识别图片上拼图的缺口位置,使用python的OpenCV库来识别到 环境准备 pip 安装 opencv-python pip insta ...

  2. iOS 滑块拼图游戏(Puzzle8)

    代码地址如下:http://www.demodashi.com/demo/11505.html 一.准备工作 先了解一个定义和定理 定义:在一个1,2,...,n的排列中,如果一对数的前后位置与大小顺 ...

  3. 原生js+canvas实现滑动拼图验证码

    上图为网易云盾的滑动拼图验证码,其应该有一个专门的图片库,裁剪的位置是固定的.我的想法是,随机生成图片,随机生成位置,再用canvas裁剪出滑块和背景图.下面介绍具体步骤. 首先随便找一张图片渲染到c ...

  4. 原生javascript 制作canvas 验证码

    <canvas id="></canvas> <a href="#" id="changeImg">看不清,换一张 ...

  5. Javascript Canvas验证码

    用Canvas画的验证码,效果图如下 1.验证码的JS代码,保存到一个名称是validatedCode.js的文件内,代码如下: (function(window,document){ functio ...

  6. 用Canvas做视频拼图

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 几天前同事给我看了一个特效,是一个拼图游戏,不同的是,拼图里的是动画.他让我看下做个DEMO,于是就自己整了一会,也确实不难.用canva ...

  7. canvas验证码 - 随机字母数字

    基于canvas制作随机生成数字英文组合验证码效果,点击或刷新会自动重组.输入验证码提交验证效果代码. <div class="verification"> <i ...

  8. canvas验证码实现

    1 <!DOCTYPE html> <html> <!-- head --> <head> <meta charset="utf-8&q ...

  9. 【vue】canvas验证码组件--数字/数字加字母

    基于canvas的数字/数字+字符验证码   SIdentify.vue 组件 <!-- 基于canvas的数字/数字+字符验证码 --> <!-- 调用格式 <s-ident ...

随机推荐

  1. subscripts(下标)

    /* subscripts(下标): 访问对象中数据的快捷方式 所谓下标脚本语法就是能够通过, 实例[索引值]来访问实例中的数据 类似于以前我们访问数字和字典, 其实Swift中的数组和字典就是一个结 ...

  2. JVM调优一些相关内容

    JVM调优工具 Jconsole,jProfile,VisualVM Jconsole : jdk自带,功能简单,但是可以在系统有一定负荷的情况下使用.对垃圾回收算法有很详细的跟踪.详细说明参考这里 ...

  3. Android RecyclerView的使用

    RecyclerView是什么? RecyclerView是一种新的视图组件,目标是为任何基于适配器的视图提供相似的渲染方式.它被作为ListView和GridView控件的继承者,在最新的suppo ...

  4. Javac语法糖之增强for循环

    加强的for循环有两种,遍历数组和实现了Iterable接口的容器.javac通过visitForeachLoop()方法来实现解语法糖,代码如下: /** Translate away the fo ...

  5. Python -- Gui编程 -- Qt库的使用 -- 配置资源文件

    1.源文件(qtRes.py) import sys from PyQt4 import QtCore, QtGui, uic class MyDialog(QtGui.QDialog): def _ ...

  6. Mac在终端用命令装载dmg文件

    今天碰到个问题,下载了一个dmg文件,然后双击/右键安装,一点反应都没有.一开始以为是电脑的缘故,重启,依旧没有反应,然后想到用终端装载试试. 打开终端,输入命令: hdiutil attach we ...

  7. JQCloud: 一个前端生成美化标签云的简单JQuery插件

    本文原文地址:https://jiang-hao.com/articles/2018/blog-JQCloud.html 因为博客需要,发现了一个生成美化简约风格的标签云的JQuery插件. 官网地址 ...

  8. 消除ADB错误“more than one device and emulator”的方法(转)

    当我连着手机充电的时候,启动模拟器调试,执行ADB指令时,报错.C:\Users\gaojs>adb shellerror: more than one device and emulatorC ...

  9. [codeup] 1128 出租车费

    题目描述 某市出租车计价规则如下:起步4公里10元,即使你的行程没超过4公里:接下来的4公里,每公里2元:之后每公里2.4元.行程的最后一段即使不到1公里,也当作1公里计费. 一个乘客可以根据行程公里 ...

  10. [九省联考 2018]秘密袭击coat

    Description 题库链接 给出一棵 \(n\) 个点的树,每个点有点权.求所有联通块的权值 \(k\) 大和,对 \(64123\) 取模. \(1\leq n,k\leq 1666\) So ...