function Gesture(width, height) {
this.width = width;
this.height = height;
this.r = width * 0.8 / 14;
}
Gesture.prototype.init = function() {
var container = document.createElement('div');
container.innerHTML = '<header><div class="circle"></div><div class="circle"></div><div class="circle"></div><div class="circle"></div><div class="circle"></div><div id="chinaMobile">中国移动</div><div id="time">1</div></header><nav>手势密码</nav><article><canvas id="canvas" width="' + this.width * 0.8 + '" height="' + this.width * 0.8 + '">浏览器不支持canvas元素</canvas></article><section>请输入手势密码</section><aside><input type="radio" name="password" value="setPassword" checked><span>设置密码</span><br><input type="radio" name="password" value="validatePassword"><span>验证密码</span></aside>';
document.getElementsByTagName("body")[0].appendChild(container);
var date = new Date();
var hour = date.getHours();
var minute = date.getMinutes();
if (hour == 12 && minute == 0)
document.getElementById("time").innerText = "12:00 AM";
else if (hour < 12)
minute >= 10 ? document.getElementById("time").innerText = hour + ":" + minute + " AM" : document.getElementById("time").innerText = hour + ":0" + minute + " AM";
else if (hour == 12)
minute >= 10 ? document.getElementById("time").innerText = "12:" + minute + " PM" : document.getElementById("time").innerText = "12:0" + minute + " PM";
else
minute >= 10 ? document.getElementById("time").innerText = hour % 12 + ":" + minute + " PM" : document.getElementById("time").innerText = hour % 12 + ":0" + minute + " PM";
this.canvas = document.getElementById('canvas');
this.context = this.canvas.getContext('2d');
this.state = 0;
this.radio = 0;
this.selectPoints = [];
this.ninePoints = [];
this.marginX = this.canvas.offsetLeft;
this.marginY = this.canvas.offsetTop;
this.caculateLocation();
for (var i = 0; i < this.ninePoints.length; i++) {
this.strokeCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#cccccc", 10);
this.fillCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#ffffff");
}
this.eventHandler();
}
Gesture.prototype.caculateLocation = function() {
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
var point = {
x: 4 * this.r * j + 3 * this.r,
y: 4 * this.r * i + 3 * this.r
};
this.ninePoints.push(point);
}
}
};
Gesture.prototype.strokeCircle = function(x, y, r, color, lineWidth) {
this.context.lineWidth = lineWidth;
this.context.strokeStyle = color;
this.context.beginPath();
this.context.arc(x, y, r, 0, Math.PI * 2, true);
this.context.stroke();
this.context.closePath();
}
Gesture.prototype.fillCircle = function(x, y, r, color) {
this.context.fillStyle = color;
this.context.beginPath();
this.context.arc(x, y, r, 0, Math.PI * 2, true);
this.context.fill();
this.context.closePath();
}
Gesture.prototype.drawLine = function(touchPoint, color, lineWidth) {
this.context.beginPath();
this.context.strokeStyle = color;
this.context.lineWidth = lineWidth;
this.context.moveTo(this.ninePoints[this.selectPoints[0]].x, this.ninePoints[this.selectPoints[0]].y);
for (var i = 1; i < this.selectPoints.length; i++)
this.context.lineTo(this.ninePoints[this.selectPoints[i]].x, this.ninePoints[this.selectPoints[i]].y);
this.context.lineTo(touchPoint.x, touchPoint.y);
this.context.stroke();
this.context.closePath();
}
Gesture.prototype.draw = function(touchPoint) {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
for (var i = 0; i < this.ninePoints.length; i++) {
if (this.selectPoints.indexOf(i) == -1) {
this.strokeCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#cccccc", 10);
this.fillCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#ffffff");
}
else {
this.strokeCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#ff5511", 10);
this.fillCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#ff8800");
}
}
this.drawLine(touchPoint, "red", 8);
};
Gesture.prototype.selectPoint = function(touchPoint) {
var touchX = touchPoint.pageX - this.marginX;
var touchY = touchPoint.pageY - this.marginY;
for (var i = 0; i < this.ninePoints.length; i++) {
if (this.selectPoints.indexOf(i) == -1) {
var point = this.ninePoints[i];
var diffX = Math.abs(point.x - touchX);
var diffY = Math.abs(point.y - touchY);
var distance = Math.sqrt(diffX * diffX + diffY * diffY);
if (distance < this.r) {
this.selectPoints.push(i);
this.strokeCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#ff5511", 10);
this.fillCircle(this.ninePoints[i].x, this.ninePoints[i].y, this.r, "#ff8800");
break;
}
}
}
};
Gesture.prototype.eventHandler = function() {
var that = this;
this.canvas.addEventListener("touchstart", function(event) {
that.selectPoint(event.touches[0]);
}, false);
this.canvas.addEventListener("touchmove", function(event) {
event.preventDefault();
that.selectPoint(event.touches[0]);
that.draw({x: event.touches[0].pageX - that.marginX, y: event.touches[0].pageY - that.marginY});
}, false);
this.canvas.addEventListener("touchend", function() {
that.storage();
that.selectPoints = [];
setTimeout(function() {
that.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
for (var i = 0; i < that.ninePoints.length; i++) {
that.strokeCircle(that.ninePoints[i].x, that.ninePoints[i].y, that.r, "#cccccc", 10);
that.fillCircle(that.ninePoints[i].x, that.ninePoints[i].y, that.r, "#ffffff");
}
}, 500);
}, false);
var radios = document.getElementsByName("password");
for (var i = 0; i < radios.length; i++) {
radios[i].addEventListener("change", function() {
if (this.value == "setPassword") {
that.radio = 0;
that.state = 0;
}
else {
if (JSON.parse(window.localStorage.getItem('password')) != null) {
that.radio = 1;
that.state = 2;
}
else {
alert("请先设置密码");
radios[0].checked = "checked";
that.state = 0;
}
}
document.getElementsByTagName('section')[0].innerHTML = '请输入手势密码';
}, false);
}
};
Gesture.prototype.storage = function() {
var section = document.getElementsByTagName('section')[0];
var radios = document.getElementsByName("password");
switch(this.state) {
case 0:
if (this.radio == 0 && this.selectPoints.length < 5)
section.innerHTML = '密码太短,至少需要5个点';
else {
section.innerHTML = '请再次输入手势密码';
this.password = this.selectPoints.slice(0);
this.state = 1;
}
break;
case 1:
if (!this.check(this.password, this.selectPoints)) {
section.innerHTML = '两次输入的不一致';
delete this.password;
this.state = 0;
}
else {
section.innerHTML = '密码设置成功';
window.localStorage.setItem('password', JSON.stringify(this.password));
radios[1].checked = "checked";
this.state = 2;
}
break;
case 2:
if (!this.check(JSON.parse(window.localStorage.getItem('password')), this.selectPoints))
section.innerHTML = '输入的密码不正确';
else
section.innerHTML = '密码正确!';
break;
}
}
Gesture.prototype.check = function(prePassword, curPassword) {
var preLen = prePassword.length;
var curLen =curPassword.length;
if (preLen != curLen)
return false;
for (var i = 0; i < preLen; i++) {
if (prePassword[i] != curPassword[i])
return false;
}
return true;
}
浅谈移动设备手势密码组件的canvas实现
最新推荐文章于 2023-12-11 21:46:39 发布