初始化(包含登录模块)

This commit is contained in:
2024-03-29 17:37:48 +08:00
commit 1bcb13ce7a
1306 changed files with 152772 additions and 0 deletions

View File

@@ -0,0 +1,175 @@
class GestureLock {
constructor(containerWidth, cycleRadius) {
this.containerWidth = containerWidth; // 容器宽度
this.cycleRadius = cycleRadius; // 圆的半径
this.circleArray = []; // 全部圆的对象数组
this.checkPoints = []; // 选中的圆的对象数组
this.lineArray = []; // 已激活锁之间的线段数组
this.lastCheckPoint = 0; // 最后一个激活的锁
this.offsetX = 0; // 容器的 X 偏移
this.offsetY = 0; // 容器的 Y 偏移
this.activeLine = {}; // 最后一个激活的锁与当前位置之间的线段
this.windowWidth = wx.getSystemInfoSync().windowWidth; // 窗口大小(用于rpx 和 px 转换)
this.initCircleArray();
}
// 初始化 画布上的 9个圆
initCircleArray() {
const cycleMargin = (this.containerWidth - 6 * this.cycleRadius) / 6;
let count = 0;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
count++;
this.circleArray.push({
count: count,
x: this.rpxTopx((cycleMargin + this.cycleRadius) * (j * 2 + 1)),
y: this.rpxTopx((cycleMargin + this.cycleRadius) * (i * 2 + 1)),
radius: this.rpxTopx(this.cycleRadius),
check: false,
style: {
left: (cycleMargin + this.cycleRadius) * (j * 2 + 1) - this.cycleRadius + 'rpx',
top: (cycleMargin + this.cycleRadius) * (i * 2 + 1) - this.cycleRadius + 'rpx',
width: this.cycleRadius * 2 + 'rpx',
}
});
}
}
}
onTouchStart(e) {
this.setOffset(e);
this.checkTouch({
x: e.touches[0].pageX - this.offsetX,
y: e.touches[0].pageY - this.offsetY
});
}
onTouchMove(e) {
this.moveDraw(e)
}
onTouchEnd(e) {
const checkPoints = this.checkPoints;
this.reset();
return checkPoints;
}
// 初始化 偏移量
setOffset(e) {
this.offsetX = e.currentTarget.offsetLeft;
this.offsetY = e.currentTarget.offsetTop;
}
// 检测当时 触摸位置是否位于 锁上
checkTouch({
x,
y
}) {
for (let i = 0; i < this.circleArray.length; i++) {
let point = this.circleArray[i];
if (this.isPointInCycle(x, y, point.x, point.y, point.radius)) {
if (!point.check) {
this.checkPoints.push(point.count);
if (this.lastCheckPoint != 0) {
// 已激活锁之间的线段
const line = this.drawLine(this.lastCheckPoint, point);
this.lineArray.push(line);
}
this.lastCheckPoint = point;
}
point.check = true;
return;
}
}
}
// 画线 - 返回 样式 对象
drawLine(start, end) {
const width = this.getPointDis(start.x, start.y, end.x, end.y);
const rotate = this.getAngle(start, end);
return {
activeLeft: start.x + 'px',
activeTop: start.y + 'px',
activeWidth: width + 'px',
activeRotate: rotate + 'deg'
}
}
// 获取 画线的 角度
getAngle(start, end) {
var diff_x = end.x - start.x,
diff_y = end.y - start.y;
if (diff_x >= 0) {
return 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
} else {
return 180 + 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
}
}
// 判断 当前点是否位于 锁内
isPointInCycle(x, y, circleX, circleY, radius) {
return (this.getPointDis(x, y, circleX, circleY) < radius) ? true : false;
}
// 获取两点之间距离
getPointDis(ax, ay, bx, by) {
return Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));
}
// 移动 绘制
moveDraw(e) {
// 画经过的圆
const x = e.touches[0].pageX - this.offsetX;
const y = e.touches[0].pageY - this.offsetY;
this.checkTouch({
x,
y
});
// 画 最后一个激活的锁与当前位置之间的线段
this.activeLine = this.drawLine(this.lastCheckPoint, {
x,
y
});
}
// 使 画布 恢复初始状态
reset() {
this.circleArray.forEach((item) => {
item.check = false;
});
this.checkPoints = [];
this.lineArray = [];
this.activeLine = {};
this.lastCheckPoint = 0;
}
// 获取 最后一个激活的锁与当前位置之间的线段
getActiveLine() {
return this.activeLine;
}
// 获取 圆对象数组
getCycleArray() {
return this.circleArray;
}
// 获取 已激活锁之间的线段
getLineArray() {
return this.lineArray;
}
// 将 RPX 转换成 PX
rpxTopx(rpx) {
return rpx / 750 * this.windowWidth;
}
}
export default GestureLock;

View File

@@ -0,0 +1,138 @@
<template>
<view class="gesture-lock" :class="{error:error}" :style="{width: containerWidth +'rpx', height:containerWidth +'rpx'}"
@touchstart.stop="onTouchStart" @touchmove.stop="onTouchMove" @touchend.stop="onTouchEnd">
<!-- 同级 v-for key 重复会有问题需要套一层 -->
<!-- 9 个圆 -->
<view>
<view v-for="(item,i) in circleArray" :key="i" class="cycle" :class="{check:item.check}" :style="{left:item.style.left,top:item.style.top,width:item.style.width,height:item.style.width}">
</view>
</view>
<view>
<!-- 已激活锁之间的线段 -->
<view v-for="(item,i) in lineArray" :key="i" class="line" :style="{left:item.activeLeft,top:item.activeTop,width:item.activeWidth,'-webkit-transform':'rotate('+item.activeRotate+')',transform:'rotate('+item.activeRotate+')'}">
</view>
</view>
<!-- 最后一个激活的锁与当前位置之间的线段 -->
<view class="line" :style="{left:activeLine.activeLeft,top:activeLine.activeTop,width:activeLine.activeWidth,'-webkit-transform':'rotate('+activeLine.activeRotate+')',transform:'rotate('+activeLine.activeRotate+')'}">
</view>
</view>
</template>
<script>
import GestureLock from './gestureLock';
export default {
name: 'index',
props: {
/**
* 容器宽度
*/
containerWidth: {
type: [Number, String],
default: 0
},
/**
* 圆的半径
*/
cycleRadius: {
type: [Number, String],
default: 0
},
/**
* 已设定的密码
*/
password: {
type: Array,
default () {
return []
}
},
},
data() {
return {
gestureLock: {}, // 锁对象
circleArray: [], // 圆对象数组
lineArray: [], // 已激活锁之间的线段
activeLine: {}, // 最后一个激活的锁与当前位置之间的线段
error: false
}
},
methods: {
onTouchStart(e) {
this.gestureLock.onTouchStart(e);
this.refesh();
},
onTouchMove(e) {
this.gestureLock.onTouchMove(e);
this.refesh();
},
onTouchEnd(e) {
const checkPoints = this.gestureLock.onTouchEnd(e);
if (!this.password.length || checkPoints.join('') == this.password.join('')) {
this.refesh();
this.$emit('end', checkPoints);
} else {
this.error = true;
setTimeout(() => {
this.refesh();
this.$emit('end', checkPoints);
}, 800);
}
},
refesh() {
this.error = false;
this.circleArray = this.gestureLock.getCycleArray();
this.lineArray = this.gestureLock.getLineArray();
this.activeLine = this.gestureLock.getActiveLine();
}
},
mounted() {
this.gestureLock = new GestureLock(this.containerWidth, this.cycleRadius);
this.refesh();
}
}
</script>
<style scoped>
.gesture-lock {
margin: 0 auto;
position: relative;
box-sizing: border-box;
overflow: auto;
}
.gesture-lock .cycle {
box-sizing: border-box;
position: absolute;
border: 2px solid #66aaff;
border-radius: 50%;
}
.gesture-lock .cycle.check:after {
content: "";
display: block;
position: absolute;
width: 32%;
height: 32%;
border: 2px solid #66aaff;
border-radius: 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.gesture-lock .line {
height: 0;
border-top: 2px solid #66aaff;
position: absolute;
transform-origin: left center;
}
.gesture-lock.error .cycle.check,
.gesture-lock.error .cycle.check:after,
.gesture-lock.error .line {
border-color: #ffa197;
}
</style>