import qrcode from './vendor/qrcode.mjs' export function drawQr(canvas, text) { const qr = qrcode(0, 'M'); qr.addData(text); qr.make() const count = qr.getModuleCount(), scale = 5, margin = 4 canvas.width = canvas.height = (count + margin * 2) * scale const ctx = canvas.getContext('2d'); ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, canvas.width, canvas.height) ctx.fillStyle = '#000' for (let y = 0; y < count; y++) for (let x = 0; x < count; x++) if (qr.isDark(y, x)) ctx.fillRect((x + margin) * scale, (y + margin) * scale, scale, scale) } export class InviteScanner { constructor(video, onCode) { this.video = video; this.onCode = onCode; this.epoch = 0; this.canvas = document.createElement('canvas') } decode(source, width, height) { if (!width || !height) return null const scale = Math.min(1, 1280 / Math.max(width, height)) this.canvas.width = Math.round(width * scale); this.canvas.height = Math.round(height * scale) const ctx = this.canvas.getContext('2d', { willReadFrequently: true }) ctx.drawImage(source, 0, 0, this.canvas.width, this.canvas.height) const pixels = ctx.getImageData(0, 0, this.canvas.width, this.canvas.height) return globalThis.jsQR(pixels.data, pixels.width, pixels.height)?.data } async image(file) { this.stop(); const epoch = this.epoch if (!file || file.size > 8 * 1024 * 1024) throw new Error('QR resmi en fazla 8 MB olabilir.') const bitmap = await createImageBitmap(file) let result try { result = this.decode(bitmap, bitmap.width, bitmap.height) } finally { bitmap.close() } if (epoch !== this.epoch) return if (!result) throw new Error('Resimde QR okunamadı; daha net bir görüntü deneyin.') await this.onCode(result) } async start() { this.stop(); const epoch = this.epoch const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' }, audio: false }) if (epoch !== this.epoch) { stream.getTracks().forEach(t => t.stop()); return } this.stream = stream; this.video.srcObject = stream; this.video.hidden = false try { await this.video.play() if (epoch !== this.epoch) return this.timer = setInterval(() => { const result = this.decode(this.video, this.video.videoWidth, this.video.videoHeight) if (result) { this.stop(); void this.onCode(result).catch(error => this.onError?.(error)) } }, 250) this.limit = setTimeout(() => this.stop(), 60000) } catch (error) { this.stop(); throw error } } stop() { this.epoch++; clearInterval(this.timer); clearTimeout(this.limit); this.stream?.getTracks().forEach(t => t.stop()); this.stream = null; this.video.srcObject = null; this.video.hidden = true } }