1. 最终效果

2.滑块验证码思路

大概思路:设置两个画布,一个为显示图像的canvas画布,一个为拼图的block画布,block画布拼图内容从图像画布中的一部分裁剪得到(使用clip()),通过绑定鼠标拖动事件,滑动滑块得到block最终的落点坐标,如果坐标落点与原剪切点坐标偏差在设置范围内,显示成功,否则显示失败。

3.绘制拼图

所需要绘制的拼图图形:

首先进行几何分析,主要由1个正方形+两块突出的部分圆+凹陷的圆

明确需要使用到的绘制方法有基本的lineTo绘制线段路径,arc绘制圆形,和globalCompositeOperation异或混合处理图形

为方便演示,单独创建画布进行每一步的操作演示:

  const x = 30;//起始点x坐标
const y = 30;//起始点y坐标
const l = 42;//正方形边长
const r = 10;//圆的半径
const PI = Math.PI;
  1. 拼图左上角开始绘制和第一个圆形部分
ctx.moveTo(x, y);
ctx.lineTo(x + l / 2, y);//绘制边
ctx.arc(x + l / 2, y - r + 2, r, 0, 2 * PI);//绘制上圆
ctx.lineTo(x + l / 2, y);//返回到边的结束点

圆心y轴左边为(y - r + 2)中的+2是因为拼图不是完整外凸的圆形,需要一定的纵坐标偏移;

为什么需要第三步ctx.lineTo(x + l / 2, y);

是因为根据arc的定义:

arc(圆心x坐标, 圆心y坐标, 圆的半径r , 开始角度, 结束角度)

开始角度和结束角度定义如下:

因此需要从圆点对应的0度开始绘制到结束的同一个点,而下一次绘制需要回到第一条线段的结束点。

  1. 绘制第二个圆

      ctx.lineTo(x + l, y);
    ctx.lineTo(x + l, y + l / 2);
    ctx.arc(x + l + r - 2, y + l / 2, r, 0, 2 * PI);
    ctx.lineTo(x + l, y + l / 2);

思路同绘制第一个圆相同。

  1. 绘制完剩下的正方形

      ctx.lineTo(x + l, y + l);
    ctx.lineTo(x, y + l);
    ctx.lineTo(x, y);

  1. 通过异或混合处理剩下的缺口
  ctx.fill();//填充上述正方形
ctx.beginPath();//开始新的绘制
ctx.arc(x, y + l / 2, r, 1.5 * PI, 0.5 * PI);
ctx.globalCompositeOperation = "xor";//异或处理
ctx.fill();//

xor:使用异或操作,对源图像与目标图像进行结合处理效果如下

4.随机图片和拼图随机起始位置

随机图片由该网站获取:http://picsum.photos

通过基本的随机数字函数调用:

 function getRandomNumberByRange(start, end) {
return Math.round(Math.random() * (end - start) + start);
}
function getRandomImgSrc() {
return (
"http://picsum.photos/300/150/?image=" + getRandomNumberByRange(0, 100)
);
}

拼图随机位置也是通过随机函数限定边界在画布内随机出现

      draw() {
this.x = getRandomNumberByRange(ll + 10, w - (ll + 10));//10为设定的最小空隙,ll是保证滑块到最终位置和初始位置至少不会重叠
this.y = getRandomNumberByRange(10 + r * 2, h - (ll + 10));
draw(this.canvasCtx, "fill", this.x, this.y);
draw(this.blockCtx, "clip", this.x, this.y);
}

最新文章

  1. Partition1:新建分区表
  2. Struts2入门(三)——数据类型转换
  3. 【C语言】C语言标识符
  4. poj2387 spfa求最短路
  5. 机器学习中的算法——决策树模型组合之随机森林与GBDT
  6. iOS时间那点事儿–NSTimeZone
  7. EF中限制字段显示长度
  8. 织梦CMS站点favicon.ico图标的放置
  9. ffmpeg 音频转码
  10. ComboBox绑定Dictionary做为数据源
  11. 解决Fiddler出现无线弹框 "creation of the root certificate was not successful”的问题
  12. JavaSE笔记-异常
  13. Android源码浅析(二)——Ubuntu Root,Git,VMware Tools,安装输入法,主题美化,Dock,安装JDK和配置环境
  14. 【interview——Ali】project interview_18 summer
  15. spring MVC 使用 hibernate validator验证框架,国际化配置
  16. [ZJOI2007]矩阵游戏——非常漂亮的二分图转化
  17. vscode下Python设置参考
  18. form中的fieldset标签应用
  19. 随手记录-linux-常用命令
  20. nova-compute源码分析

热门文章

  1. MySQL进阶实战1,数据类型与三范式
  2. 在Cloudreve网盘系统中集成kkFileView在线预览(暂时)
  3. 【开发必备】单点登录,清除了cookie,页面还保持登录状态?
  4. 兼容IE全版本及所有市面浏览器的网页变黑白处理方式
  5. 【Shell案例】【wc、awk、cat、管道】1、统计文件的行数
  6. SVNAdmin2 - 基于web的SVN管理系统
  7. ArcObjects SDK开发 013 MapFrame
  8. 计算存储分离在京东云消息中间件JCQ上的应用
  9. ConditionAlOnProperties实现可插拔?
  10. Python实验报告(第7章)