mobileoa-common-modules
Version:
移动办公平台前端公共功能模块
225 lines (204 loc) • 7.05 kB
JavaScript
'use strict';
var angular = require('angular');
require('../modules');
require('./GestureScreenLayout');
var module = angular.module('gesturepassword.services');
module.factory('GestureScreenContext', function(GestureScreenLayout, $rootScope) {
function GestureScreenContext(width, height, validator, setpassword, ctx) {
this.setpassword = setpassword;
this.ctx = ctx;
this.firstpassword = '';
this.width = width;
this.height = height;
this.validator = validator || function() {return true;};
this.layout = new GestureScreenLayout(width, height).calc();
this.contentWidth = this.layout.content.width;
this.contentHeight = this.layout.content.height;
this.pointers = GestureScreenContext.generatePoints(this.layout.content);
this.selectors = [];
this.sceneState = GestureScreenContext.STATE_PRIMITIVE;
this.addedSelectors = [];
}
GestureScreenContext.POINTER_NUMBER = 9;
GestureScreenContext.STATE_PRIMITIVE = 0;
GestureScreenContext.STATE_MOVING = 1;
GestureScreenContext.STATE_OK = 2;
GestureScreenContext.STATE_NO = 3;
GestureScreenContext.POINTER_STATE_PRIMITIVE = 0;
GestureScreenContext.POINTER_STATE_SELECTED = 1;
GestureScreenContext.POINTER_STATE_OK = 2;
GestureScreenContext.POINTER_STATE_NO = 3;
/**
* 产生九个点。
*
* @param {ContentLayout} 内容区域布局对象
* @return {Array} 返回九个点。
*/
GestureScreenContext.generatePoints = function(contentLayout) {
var startX = contentLayout.gap,
startY = contentLayout.topWhite,
radius = contentLayout.radius,
gap = contentLayout.gap,
pointers = [];
for (var i = 0; i < GestureScreenContext.POINTER_NUMBER; i++) {
var relativeX = i % 3,
relativeY = Math.floor(i / 3);
pointers.push({
y: (startY + (2 * relativeY + 1) * radius + relativeY * gap + 0.5) | 0,
x: (startX + (2 * relativeX + 1) * radius + relativeX * gap + 0.5) | 0,
radius: radius,
state: GestureScreenContext.STATE_PRIMITIVE
});
}
return pointers;
};
GestureScreenContext.pointerInCircle = function(circle, pointer) {
return Math.pow((circle.x - pointer.x), 2) +
Math.pow(circle.y - pointer.y, 2) <= Math.pow(circle.radius, 2);
};
/**
* 矫正两点之间的两线,若之间还有点,应该连上
* @param {[Array]} selectors 已选择的点
* @param {[int]} selector 当前选择的点
* @return {[int]} 返回中间点索引
*/
GestureScreenContext.makeLineCorrect = function(selectors, selector) {
if (selectors.length <= 0) { return; }
var array = [
'0,8,4','8,0,4','2,6,4','6,2,4','0,6,3','6,0,3','1,7,4','7,1,4',
'2,8,5','8,2,5','0,2,1','2,0,1','3,5,4','5,3,4','6,8,7','8,6,7'
],
linkSelector = selectors[selectors.length - 1] + ',' + selector,
i;
for (i = 0; i < array.length; i ++) {
var currentGroup = array[i];
if (currentGroup.substring(0, 3) === linkSelector) {
return parseInt(currentGroup.charAt(currentGroup.length - 1));
}
}
};
GestureScreenContext.prototype = {
/**
* 开始移动
*
* @param {Number} x
* @param {Number} y
*/
startMove: function() {
if (this.sceneState === GestureScreenContext.STATE_PRIMITIVE) {
this.setState(GestureScreenContext.STATE_MOVING);
} else if (this.sceneState === GestureScreenContext.STATE_NO) {
this.setState(GestureScreenContext.STATE_PRIMITIVE);
this.setState(GestureScreenContext.STATE_MOVING);
}
},
/**
* 移动中
*
* @param {Number} x
* @param {Number} y
*/
move: function(x, y) {
if (this.sceneState === GestureScreenContext.STATE_MOVING) {
this.movingPointer = {
x: (x - this.layout.content.startX + 0.5) | 0,
y: (y - this.layout.content.startY + 0.5) | 0
};
this.checkSelectors();
}
},
/**
* 移动结束
*
* @return
*/
endMove: function() {
var result = this.validate(),
toState = result? GestureScreenContext.STATE_OK : GestureScreenContext.STATE_NO;
delete this.movingPointer;
this.setState(toState);
return result;
},
setState: function(state) {
var stateChanged = this.sceneState !== state;
this.sceneState = state;
switch(state) {
case GestureScreenContext.STATE_PRIMITIVE:
this.reset();
break;
case GestureScreenContext.STATE_MOVING:
break;
case GestureScreenContext.STATE_OK:
this.changeSelectorPointersState(GestureScreenContext.POINTER_STATE_OK);
break;
case GestureScreenContext.STATE_NO:
this.changeSelectorPointersState(GestureScreenContext.POINTER_STATE_NO);
break;
}
if (stateChanged) {
$rootScope.$broadcast('gesturepassword.statechange', this, state);
$rootScope.$emit('gesturepassword.statechange', this, state);
}
},
changeSelectorPointersState: function(state) {
var i, index, pointer;
for (i = this.selectors.length; i--;) {
index = this.selectors[i];
pointer = this.pointers[index];
pointer.state = state;
}
},
reset: function() {
this.selectors = [];
_.forEach(this.pointers, function(pointer) {
pointer.state = GestureScreenContext.POINTER_STATE_PRIMITIVE;
});
delete this.movingPointer;
},
/**
*
*/
checkSelectors: function () {
var i, pointer, pointerMiddle;
for (i = this.pointers.length; i--;) {
pointer = this.pointers[i];
if (GestureScreenContext.pointerInCircle(pointer, this.movingPointer)) {
if (pointer.state !== GestureScreenContext.POINTER_STATE_SELECTED) {
pointer.state = GestureScreenContext.POINTER_STATE_SELECTED;
var j = GestureScreenContext.makeLineCorrect(this.selectors, i);
if(j >= 0) {
pointerMiddle = this.pointers[j];
if (pointerMiddle.state !== GestureScreenContext.POINTER_STATE_SELECTED) {
pointerMiddle.state = GestureScreenContext.POINTER_STATE_SELECTED;
this.selectors.push(j);
this.addedSelectors.push(j);
}
}
this.selectors.push(i);
this.addedSelectors.push(i);
}
return;
}
}
},
/**
* 移动结束后验证正确与否
*/
validate: function() {
return this.validator(this.selectors);
},
/**
* 传入第一次设置的密码,是缩略图在第一次成功设置密码时,把密码传入
*/
setFirspassword: function(firstpassword) {
this.firstpassword = firstpassword;
},
destroy: function() {
delete this.layout;
delete this.ctx;
delete this.validator;
delete this.pointers;
}
};
return GestureScreenContext;
});