学生作业:基于Ionic 2、Angular 2与Firebase的图案锁实现求助
嘿,刚好有过类似的实现经验,结合你用的Ionic 2+Angular 2+Firebase技术栈,给你一步步拆解方案,应该能帮你搞定这个学校作业~
图案锁实现完整指导
1. 创建3×3图案矩阵
首先用Angular的模板语法快速生成3×3网格,每个格子标记唯一位置(1-9),同时预留样式类来反馈选中状态:
<ion-content> <div class="pattern-wrapper"> <div *ngFor="let pos of patternPositions" class="pattern-dot" [data-pos]="pos" (touchstart)="onTouchStart($event)" (touchmove)="onTouchMove($event)" (touchend)="onTouchEnd()" ></div> </div> </ion-content>
在组件TS里定义位置数组,同时添加基础样式:
// 组件.ts文件 patternPositions = [1,2,3,4,5,6,7,8,9]; selectedSequence: number[] = []; isDrawing = false;
/* 组件.scss文件 */ .pattern-wrapper { display: grid; grid-template-columns: repeat(3, 70px); gap: 12px; justify-content: center; margin-top: 60px; } .pattern-dot { width: 70px; height: 70px; border: 2px solid #666; border-radius: 50%; background-color: #fff; transition: all 0.2s; } .pattern-dot.selected { background-color: #2196F3; border-color: #2196F3; transform: scale(1.1); }
2. 绑定触摸事件(替代拖拽事件)
移动端用touch系列事件比drag更靠谱,能避免滚动冲突和兼容性问题。我们需要监听触摸开始、移动、结束三个阶段,来追踪用户的图案序列:
// 组件.ts文件 onTouchStart(event: TouchEvent) { const dot = event.target as HTMLElement; const pos = parseInt(dot.dataset.pos!, 10); if (!this.isDrawing) { this.isDrawing = true; this.selectedSequence = [pos]; dot.classList.add('selected'); } } onTouchMove(event: TouchEvent) { if (!this.isDrawing) return; // 阻止页面滚动,避免干扰图案绘制 event.preventDefault(); const touch = event.touches[0]; // 获取当前触摸到的格子元素 const target = document.elementFromPoint(touch.clientX, touch.clientY) as HTMLElement; if (target?.classList.contains('pattern-dot')) { const pos = parseInt(target.dataset.pos!, 10); // 避免重复选中同一个格子 if (!this.selectedSequence.includes(pos)) { this.selectedSequence.push(pos); target.classList.add('selected'); } } } onTouchEnd() { this.isDrawing = false; // 输出最终序列,后续可用于Firebase存储/验证 console.log('用户绘制的图案序列:', this.selectedSequence.join('')); // 重置选中状态,方便下次输入 document.querySelectorAll('.pattern-dot').forEach(dot => dot.classList.remove('selected')); }
3. 完善序列追踪细节
可以额外加两个优化点提升体验:
- 如果用户触摸到矩阵外,自动结束绘制
- 限制最短序列长度(比如至少4个点),避免无效输入
// 在onTouchMove里补充 if (!target || !target.classList.contains('pattern-dot')) { this.onTouchEnd(); return; } // 在onTouchEnd里补充验证 if (this.selectedSequence.length < 4) { alert('请绘制至少4个点的图案'); this.selectedSequence = []; }
4. Firebase 集成:存储与验证图案
假设你已经完成了Firebase在Ionic项目中的初始化(引入angularfire2模块并配置App),接下来实现图案的存储和验证:
存储注册图案(用户首次设置时)
import { AngularFireDatabase } from 'angularfire2/database'; import { AngularFireAuth } from 'angularfire2/auth'; constructor( private db: AngularFireDatabase, private auth: AngularFireAuth ) {} // 保存用户图案到Firebase async saveUserPattern() { const user = await this.auth.currentUser; if (!user) return; const patternStr = this.selectedSequence.join(''); // 存储到users节点下,以用户uid为键 await this.db.object(`users/${user.uid}/loginPattern`).set(patternStr); alert('图案设置成功!'); }
验证登录图案
// 验证输入的图案是否匹配 async verifyLoginPattern(): Promise<boolean> { const user = await this.auth.currentUser; if (!user) return false; const inputPattern = this.selectedSequence.join(''); // 从Firebase获取用户存储的图案 const patternSnapshot = await this.db.object(`users/${user.uid}/loginPattern`) .valueChanges() .pipe(take(1)) .toPromise(); return inputPattern === patternSnapshot; } // 登录按钮/结束绘制时调用 async onPatternLogin() { const isMatch = await this.verifyLoginPattern(); if (isMatch) { // 登录成功,跳转首页 this.navCtrl.push('HomePage'); } else { alert('图案错误,请重新绘制'); this.selectedSequence = []; } }
小提示:如果是生产环境,建议对图案序列进行哈希加密后再存储,避免明文泄露风险,学校作业可以暂时忽略这一步。
内容的提问来源于stack exchange,提问作者user9160303
相关产品推荐
相关产品推荐

