(width, height)
| 216 | } |
| 217 | |
| 218 | drawFlashMode(width, height) { |
| 219 | const ctx = this.ctx; |
| 220 | |
| 221 | if (this.data.flash && this.data.flash.mask_contour) { |
| 222 | const progress = this.data.flash.progress || 0; |
| 223 | const alpha = 0.3 + 0.4 * (0.5 * (1 + Math.sin(progress * 2 * Math.PI - Math.PI/2))); |
| 224 | |
| 225 | // 绘制闪烁轮廓 |
| 226 | ctx.beginPath(); |
| 227 | ctx.strokeStyle = this.colors.accent; |
| 228 | ctx.lineWidth = 4; |
| 229 | ctx.globalAlpha = alpha; |
| 230 | |
| 231 | const points = this.scalePoints(this.data.flash.mask_contour, width, height); |
| 232 | ctx.moveTo(points[0][0], points[0][1]); |
| 233 | points.forEach(p => ctx.lineTo(p[0], p[1])); |
| 234 | ctx.closePath(); |
| 235 | |
| 236 | // 填充 |
| 237 | ctx.fillStyle = this.colors.accent + '33'; |
| 238 | ctx.fill(); |
| 239 | ctx.stroke(); |
| 240 | |
| 241 | ctx.globalAlpha = 1; |
| 242 | |
| 243 | // 绘制锁定动画 |
| 244 | const center = this.getContourCenter(points); |
| 245 | this.drawLockAnimation(center[0], center[1], progress); |
| 246 | } |
| 247 | |
| 248 | this.drawStatusText( |
| 249 | '正在锁定目标 Locking Target', |
| 250 | '准备追踪 Preparing to track', |
| 251 | width / 2, |
| 252 | 100, |
| 253 | this.colors.accent |
| 254 | ); |
| 255 | } |
| 256 | |
| 257 | drawTrackMode(width, height) { |
| 258 | const ctx = this.ctx; |
no test coverage detected