|
1 | 1 | <script lang="ts">
|
2 |
| - import { onDestroy } from 'svelte' |
3 |
| - import { Camera, CloseIcon, IconButton } from '$lib' |
4 |
| - import { browser } from '$app/environment' |
5 |
| -
|
6 |
| - let streamInterval: number |
7 |
| -
|
8 |
| - async function onVideoStream(e: CustomEvent<HTMLVideoElement>) { |
9 |
| - const stream = e.detail |
10 |
| - const canvasEl = document.createElement('canvas') |
11 |
| - const canvas = canvasEl.getContext('2d') |
12 |
| -
|
13 |
| - // Maybe use requestAnimationFrame here instead of interval |
14 |
| - streamInterval = window.setInterval(async () => { |
15 |
| - // if (qrCode) return |
16 |
| - if (stream.readyState !== stream.HAVE_ENOUGH_DATA) return |
17 |
| - const { videoWidth: width, videoHeight: height } = stream |
18 |
| - console.log(stream) |
19 |
| - canvasEl.height = height |
20 |
| - canvasEl.width = width |
21 |
| - if (!canvas) return |
22 |
| -
|
23 |
| - canvas.drawImage(stream, 0, 0, width, height) |
24 |
| - // Might need to make these dimensions smaller for performance |
25 |
| - const imageData = canvas.getImageData(0, 0, width, height) |
26 |
| - console.log(imageData) |
27 |
| - // const code = QR(imageData.data, imageData.width, imageData.height, { |
28 |
| - // inversionAttempts: 'dontInvert' |
29 |
| - // }) |
30 |
| - // if (code) { |
31 |
| - // clearInterval(streamInterval) |
32 |
| - // qrCode = code |
33 |
| - // } |
34 |
| - }, 500) |
| 2 | + import { onMount } from 'svelte' |
| 3 | + import { Html5Qrcode, type Html5QrcodeResult } from 'html5-qrcode' |
| 4 | + import { CloseIcon, IconButton } from '$lib' |
| 5 | +
|
| 6 | + function getScanBox(width: number, height: number) { |
| 7 | + const constraint = Math.min(width, height) |
| 8 | + const size = Math.min(constraint - 48, 512) |
| 9 | + return { width: size, height: size } |
| 10 | + } |
| 11 | +
|
| 12 | + async function onScan(data: string, _result: Html5QrcodeResult) { |
| 13 | + console.log(data, _result) |
35 | 14 | }
|
36 | 15 |
|
37 |
| - onDestroy(() => { |
38 |
| - clearInterval(streamInterval) |
| 16 | + onMount(() => { |
| 17 | + const scanner = new Html5Qrcode('camera', { formatsToSupport: [0], verbose: false }) |
| 18 | +
|
| 19 | + scanner.start( |
| 20 | + { facingMode: 'environment' }, |
| 21 | + { fps: 10, qrbox: getScanBox, aspectRatio: 0.5625 }, |
| 22 | + onScan, |
| 23 | + () => {} |
| 24 | + ) |
| 25 | +
|
| 26 | + return () => scanner.stop() |
39 | 27 | })
|
| 28 | +
|
| 29 | + // async function handleQr(qrData: string | null) { |
| 30 | + // if (!qrData) return |
| 31 | +
|
| 32 | + // const url = new URL(qrData) |
| 33 | +
|
| 34 | + // replace(url.hash.replace('#', '')) |
| 35 | + // } |
| 36 | +
|
| 37 | + // $: handleQr(qrCode?.data) |
| 38 | +
|
| 39 | + // async function onVideoStream(e: CustomEvent<HTMLVideoElement>) { |
| 40 | + // // TODO: Look into Screen Wake Lock API |
| 41 | + // // https://developer.mozilla.org/en-US/docs/Web/API/Screen_Wake_Lock_API |
| 42 | + // const stream = e.detail |
| 43 | + // const canvasEl = document.createElement('canvas') |
| 44 | + // const canvas = canvasEl.getContext('2d') |
| 45 | +
|
| 46 | + // // Maybe use requestAnimationFrame here instead of interval |
| 47 | + // streamInterval = window.setInterval(async () => { |
| 48 | + // if (qrCode) return |
| 49 | + // if (stream.readyState !== stream.HAVE_ENOUGH_DATA) return |
| 50 | + // const { videoWidth: width, videoHeight: height } = stream |
| 51 | + // canvasEl.height = height |
| 52 | + // canvasEl.width = width |
| 53 | + // if (!canvas) return |
| 54 | +
|
| 55 | + // canvas.drawImage(stream, 0, 0, width, height) |
| 56 | + // // Might need to make these dimensions smaller for performance |
| 57 | + // const imageData = canvas.getImageData(0, 0, width, height) |
| 58 | + // const code = QR(imageData.data, imageData.width, imageData.height, { |
| 59 | + // inversionAttempts: 'dontInvert' |
| 60 | + // }) |
| 61 | + // if (code) { |
| 62 | + // clearInterval(streamInterval) |
| 63 | + // qrCode = code |
| 64 | + // } |
| 65 | + // }, 500) |
| 66 | + // } |
40 | 67 | </script>
|
41 | 68 |
|
42 |
| -<main |
43 |
| - class="h-full w-full bg-zinc-800 rounded-t-3xl rounded-b-3xl flex-1 flex flex-col justify-center items-center" |
44 |
| -> |
45 |
| - {#if browser} |
46 |
| - <Camera hideControls on:stream={onVideoStream} /> |
47 |
| - {/if} |
| 69 | +<main class="relative h-full w-full bg-zinc-800 flex-1 flex flex-col justify-center items-center"> |
| 70 | + <div id="camera" class="w-full top-0 left-0" /> |
48 | 71 |
|
49 | 72 | <div class="absolute bottom-0 z-10 flex items-center justify-center w-full p-4">
|
50 | 73 | <IconButton Icon={CloseIcon} />
|
51 | 74 | </div>
|
52 | 75 |
|
53 |
| - <div |
| 76 | + <!-- <div |
54 | 77 | class="border-4 border-brand-primary bg-transparent w-5/6 h-1/2 z-10 rounded-2xl flex justify-center items-center"
|
55 |
| - /> |
| 78 | + /> --> |
56 | 79 | </main>
|
0 commit comments