// CaptchaComponent.ets - 自定义验证码组件@Componentstruct CaptchaComponent { private controller: CaptchaController = new CaptchaController() @State blockPosition: number = 0 @State isVerified: boolean = false @Link onVerify: (result: VerifyResult) => void
build() { Column() { // 拼图区域 Stack() { Image($r('app.media.verify_bg')) // 背景图 .aspectRatio(1.78) // 16:9比例 // 拼图缺口 Canvas({ context: this.controller.canvasContext }) .onReady(() => this.drawBlockShape()) .width(this.controller.blockSize) .height(this.controller.blockSize) .position({ x: this.blockPosition }) } .height(300) .clip(new Rect({ width: '100%', height: '100%' })) // 滑块控件 Slider({ min: 0, max: 100, value: this.blockPosition, style: SliderStyle.OutSet }) .blockShade($r('app.graphic.thumb')) .onChange(value => { this.handleSliderMove(value) }) } }
private drawBlockShape() { const ctx = this.controller.canvasContext ctx.beginPath() // 绘制拼图形状(示例使用圆角矩形) ctx.arc(40, 40, 35, 0, Math.PI * 2) ctx.fillStyle = 'rgba(0,0,0,0.5)' ctx.fill() }
private handleSliderMove(value: number) { if (this.isVerified) return; this.blockPosition = value // 验证逻辑 if (Math.abs(value - this.controller.correctPosition) < 5) { this.isVerified = true this.onVerify({ success: true, time: new Date().getTime() }) } else if (value >= 95) { this.onVerify({ success: false, retry: true }) } }}
// 使用示例@Entry@Componentstruct VerifyPage { @State verifyResult: string = '' private maxRetries: number = 3 @State retryCount: number = 0
build() { Column() { Text(this.verifyResult) .fontSize(20) .margin(20) CaptchaComponent({ onVerify: (result) => this.handleVerify(result) }) Button('重新验证') .onClick(() => this.resetVerification()) } }
private handleVerify(result: VerifyResult) { if (result.success) { this.verifyResult = `验证成功 ${result.time}ms` } else { this.retryCount++ if (this.retryCount >= this.maxRetries) { this.verifyResult = '超过重试次数' } else { this.verifyResult = `验证失败,剩余次数 ${this.maxRetries - this.retryCount}` } } }
private resetVerification() { this.retryCount = 0 this.verifyResult = '' }}
// 控制器类class CaptchaController { canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D() blockSize: number = 80 correctPosition: number = Math.random() * 250 + 50}
// 类型定义interface VerifyResult { success: boolean time?: number retry?: boolean}
评论