2019-02-14 13:26:56 540浏览
今天扣丁学堂HTML5+web前端培训老师给大家介绍一下关于HTML5使用canvas画布实现手势解锁的源码详解,首先老师正好最近做的一个app项目使用的apicloud来实现跨平台开发,现在需要为这个app添加手势(九宫格)解锁的功能,apicloud已经有一些第三方的原生实现的手势解锁插件,因为是原生的性能也比较好,调用也比较方便,但是都不能对它们的样式做修改,所以就打算自己来实现这个功能。这篇文章将实现过程整理分享出来,希望有需要的可以了解。分享出来的代码只实现了最基本的设置密码功能、解锁功能、比较密码的功能等,一些高级功能例如:不能限制一个点最多经过多少次、限制用户设置密码的长度。
原理分析
var width = $(document).width();
var height = $(document).height() - 40; //减去手机状态栏的高度
//九宫格其实就是九个点,9个点的坐标对象
var lockCicle = {
x: 0, //x坐标
y: 0, //y坐标
color: "#999999",
state: "1" //状态当前点是否已经被链接过
};
var offset = (width - height) / 2; //计算偏移量
var arr = []; //九个点的坐标数组
//计算九个点坐标的方法
for (var i = 1; i <= 3; i++) {
//每一行
for (var j = 1; j <= 3; j++) {
//每一行的每一个
var lockCicle = {};
//横屏
if (offset > 0) {
lockCicle.x = (height / 4) * j + Math.abs(offset);
lockCicle.y = (height / 4) * i;
lockCicle.state = 0;
//竖屏
} else {
lockCicle.x = (width / 4) * j;
lockCicle.y = (width / 4) * i + Math.abs(offset);
lockCicle.state = 0;
}
arr.push(lockCicle);
}
}
//初始化界面的方法
function init() {
ctx.clearRect(0, 0, width, height); //清空画布
pointerArr = []; //清楚绘制路径
for (var i = 0; i < arr.length; i++) {
arr[i].state = 0; //清除绘制状态
drawPointer(i);
}
}
//绘制九宫格解锁界面
function drawPointer(i) {
ctx.save();
var radius = 0;
if (hastouch) {
radius = width / 12;
} else {
radius = 24;
}
var _fillStyle = "#dd514c";
var _strokeStyle = "#dd514c";
//不同状态显示不同颜色
if (arr[i].state == 1) {
_strokeStyle = "#1bd6c5";
}
//绘制原点
ctx.beginPath();
ctx.fillStyle = _fillStyle;
ctx.arc(arr[i].x, arr[i].y, 6, 0, Math.PI * 2, false);
ctx.fill();
ctx.closePath();
//绘制圆圈
ctx.beginPath();
ctx.strokeStyle = _strokeStyle;
ctx.lineWidth = 0.3;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.arc(arr[i].x, arr[i].y, radius, 0, Math.PI * 2, false);
ctx.stroke();
ctx.closePath();
ctx.restore();
}
//初始化界面
init();
var pointerArr = []; //连接线点的坐标数组
var startX, startY; //线条起始点
var puts = []; //经过的九个点的数组
var currentPointer; //当前点是否已经连接
var pwd = []; //密码
var confirmPwd = []; //确认密码
var unlockFlag = false; //是否解锁的标志
/**
** 绘制链接线的方法,将坐标数组中的点绘制在canvas画布中
**/
function drawLinePointer(x, y, flag) {
ctx.clearRect(0, 0, width, height);
ctx.save();
ctx.beginPath();
ctx.strokeStyle = "#1bd6c5";
ctx.lineWidth = 5;
ctx.lineCap = "round";
ctx.lineJoin = "round";
for (var i = 0; i < pointerArr.length; i++) {
if (i == 0) {
ctx.moveTo(pointerArr[i].x, pointerArr[i].y);
} else {
ctx.lineTo(pointerArr[i].x, pointerArr[i].y);
}
}
ctx.stroke();
ctx.closePath();
ctx.restore();
for (var i = 0; i < arr.length; i++) {
drawPointer(i); //绘制圆圈和原点
if (ctx.isPointInPath(x, y) && currentPointer != i) {
//判断鼠标点击是否在圆中
pointerArr.push({
x: arr[i].x,
y: arr[i].y
});
currentPointer = i;
puts.push(i + 1);
startX = arr[i].x;
startY = arr[i].y;
arr[i].state = 1;
}
}
if (flag) {
ctx.save();
ctx.beginPath();
ctx.globalCompositeOperation = "destination-over";
ctx.strokeStyle = "#e2e0e0";
ctx.lineWidth = 5;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.moveTo(startX, startY);
ctx.lineTo(x, y);
ctx.stroke();
ctx.beginPath();
ctx.restore();
}
}
//兼容移动触摸的事件写法
var hastouch = "ontouchstart" in window ? true : false,
tapstart = hastouch ? "touchstart" : "mousedown",
tapmove = hastouch ? "touchmove" : "mousemove",
tapend = hastouch ? "touchend" : "mouseup";
//绑定按下事件
lockCnavs.addEventListener(tapstart, function(e) {
isMouseDown = true;
var x1 = hastouch
? e.targetTouches[0].pageX
: e.clientX - canvas.offsetLeft;
var y1 = hastouch ? e.targetTouches[0].pageY : e.clientY - canvas.offsetTop;
drawLinePointer(x1, y1, true);
});
//移动时候,将经过的坐标点全部保存起来
lockCnavs.addEventListener(tapmove, function(e) {
if (isMouseDown) {
var x1 = hastouch
? e.targetTouches[0].pageX
: e.clientX - canvas.offsetLeft;
var y1 = hastouch
? e.targetTouches[0].pageY
: e.clientY - canvas.offsetTop;
drawLinePointer(x1, y1, true);
}
});
//取消
lockCnavs.addEventListener(tapend, function(e) {
drawLinePointer(0, 0, false);
isMouseDown = false;
pointerArr = [];
if (puts.length >= 6) {
alert("你的图案密码是: [ " + puts.join(" > ") + " ]");
if (unlockFlag) {
//解锁
unlock();
} else {
//设置解锁密码
settingUnlockPwd();
}
} else {
if (puts.length >= 1) {
alert("你的图案密码太简单了~~~");
init();
}
}
puts = [];
});
//设置解锁密码和解锁测试
function settingUnlockPwd() {
if (pwd.length <= 0) {
pwd = puts;
init();
$("header").text("再次绘制解锁图案");
} else if (confirmPwd.length <= 0) {
confirmPwd = puts;
}
console.log(pwd + " " + confirmPwd);
//笔记两次密码是否正确
if (pwd.length > 0 && confirmPwd.length > 0) {
if (compareArr(pwd, confirmPwd)) {
$("header").text("解锁图案绘制成功");
init();
} else {
$("header").text("两次绘制的解锁图案不一致");
init();
confirmPwd = [];
}
}
}
//解锁
function unlock() {
console.log("解锁密码:" + puts + " " + confirmPwd);
if (compareArr(puts, confirmPwd)) {
$("header").text("解锁成功!页面跳转中......");
} else {
$("header").text("解锁图案不正确!!!");
init();
}
}
$("footer").click(function() {
if ($(this).text() === "解锁") {
unlockFlag = true;
init();
$("header").text("绘制解锁图案");
}
});
//比较两个数组(Number)是否相等
function compareArr(arr1, arr2) {
return arr1.toString() === arr2.toString();
}
以上就是关于扣丁学堂HTML5培训之使用canvas画布实现手势解锁的全部内容,希望对大家的学习有所帮助,最后扣丁学堂html5培训官网、微信等平台,扣丁学堂IT职业在线学习教育平台为您提供权威的html5视频教程供学员学习,扣丁学堂老师精心推出的html5视频直播课定能让你快速掌握html5从入门到精通开发实战技能。扣丁学堂H5技术交流群:673883249。
【关注微信公众号获取更多学习资料】