// CaptchaComponent.ets - 自定义验证码组件
@Component
struct 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
@Component
struct 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
}
评论