| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 | 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;
 |