使用HTML5实现手势密码 - 让您的移动设备更安全

107 min read

实现手势密码可以使用HTML5的canvas和JavaScript实现。以下是一个简单的例子:

HTML:

<canvas id="canvas" width="300" height="300"></canvas>

JS:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;

//设置手势密码点的坐标数组
var points = [
  {x: width/4, y: height/4},
  {x: width/2, y: height/4},
  {x: width*3/4, y: height/4},
  {x: width/4, y: height/2},
  {x: width/2, y: height/2},
  {x: width*3/4, y: height/2},
  {x: width/4, y: height*3/4},
  {x: width/2, y: height*3/4},
  {x: width*3/4, y: height*3/4}
];

//初始化手势密码点
for(var i=0; i<points.length; i++){
  var point = points[i];
  context.beginPath();
  context.arc(point.x, point.y, 20, 0, 2*Math.PI);
  context.strokeStyle = "#09F";
  context.lineWidth = 5;
  context.stroke();
}

//鼠标事件
var isDown = false;
var selectedPoints = [];
canvas.addEventListener("mousedown", function(event){
  var x = event.pageX - canvas.offsetLeft;
  var y = event.pageY - canvas.offsetTop;
  for(var i=0; i<points.length; i++){
    var point = points[i];
    if(Math.abs(x-point.x) < 20 && Math.abs(y-point.y) < 20){
      isDown = true;
      context.beginPath();
      context.arc(point.x, point.y, 25, 0, 2*Math.PI);
      context.strokeStyle = "#09F";
      context.lineWidth = 8;
      context.stroke();
      selectedPoints.push(point);
      break;
    }
  }
});

canvas.addEventListener("mousemove", function(event){
  if(isDown){
    var x = event.pageX - canvas.offsetLeft;
    var y = event.pageY - canvas.offsetTop;
    context.lineTo(x, y);
    context.strokeStyle = "#09F";
    context.lineWidth = 5;
    context.stroke();
    for(var i=0; i<points.length; i++){
      var point = points[i];
      if(Math.abs(x-point.x) < 20 && Math.abs(y-point.y) < 20 && !selectedPoints.includes(point)){
        context.beginPath();
        context.arc(point.x, point.y, 25, 0, 2*Math.PI);
        context.strokeStyle = "#09F";
        context.lineWidth = 8;
        context.stroke();
        selectedPoints.push(point);
        break;
      }
    }
  }
});

canvas.addEventListener("mouseup", function(event){
  isDown = false;
  //检查手势是否正确
  if(selectedPoints.length === 3){
    var p1 = selectedPoints[0];
    var p2 = selectedPoints[1];
    var p3 = selectedPoints[2];
    if(Math.abs(p1.x-p2.x) < 30 && Math.abs(p1.y-p2.y) < 30 && Math.abs(p2.x-p3.x) < 30 && Math.abs(p2.y-p3.y) < 30){
      context.clearRect(0, 0, width, height);
      alert("手势正确!");
    }else{
      context.clearRect(0, 0, width, height);
      alert("手势错误,请重试!");
    }
  }else{
    context.clearRect(0, 0, width, height);
    alert("手势错误,请重试!");
  }
  //重置手势密码点
  for(var i=0; i<points.length; i++){
    var point = points[i];
    context.beginPath();
    context.arc(point.x, point.y, 20, 0, 2*Math.PI);
    context.strokeStyle = "#09F";
    context.lineWidth = 5;
    context.stroke();
  }
  selectedPoints = [];
});

在这个例子里,手势密码点的坐标数组被初始化为一个3x3的数组。当拖拽鼠标选择一个密码点时,将该点加入selectedPoints数组中,并在该点画一个大圆表示该点已被选择。在移动鼠标时,检查是否有其他密码点被拖拽选择,并在该密码点画一个大圆表示该点已被选择。在放开鼠标后,检查selectedPoints数组是否符合要求,若符合则弹出提示框并清空canvas,否则弹出错误提示框和清空canvas。