You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

学生作业:基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:48:37