---
description: Usando a câmera para detectar código
---

# Barcode Detection API - Parte 2

Desta vez usaremos **TypeScript** e para que isso seja feito sem alertas de erro no código, precisaremos que a API esteja devidamente tipada, porém, não temos disponível no arquivo `lib.dom.ts` do **TypeScript**. Eu mesmo escrevi um seguindo a especificação, vai servir por enquanto.

## barcode.d.ts

Crie um arquivo barcode.d.ts com o conteúdo a seguir.

```typescript
interface BarcodeDetector {
  new (barcodeDetectorOptions?: BarcodeDetectorOptions): BarcodeDetector;

  static getSupportedFormats(): Promise<BarcodeFormat[]>;

  detect(image: ImageBitmapSource): Promise<DetectedBarcode[]>;
}

declare var BarcodeDetector: {
  prototype: BarcodeDetector;
  new (barcodeDetectorOptions?: BarcodeDetectorOptions): BarcodeDetector;
};

interface BarcodeDetectorOptions {
  formats: BarcodeFormat;
}

interface Point2D {
  x: number
  y: number
}

interface DetectedBarcode {
  boundingBox: DOMRectReadOnly;
  rawValue: string;
  format: BarcodeFormat;
  cornerPoints: Point2D[];
}

type BarcodeFormat =
  | "aztec"
  | "code_128"
  | "code_39"
  | "code_93"
  | "codabar"
  | "data_matrix"
  | "ean_13"
  | "ean_8"
  | "itf"
  | "pdf417"
  | "qr_code"
  | "unknown"
  | "upc_a"
  | "upc_e";

```

Agora sim, partimos para implementação.

Basicamente o que precisamos fazer é:

1. Capturar o `stream` de vídeo do dispositivo
2. Desenhar o `video` em um elemento `canvas`
3. Executar o método de detecção no `canvas`
4. Se houver resultados, desenhar no `canvas`

Vamos lá!

## main.ts

```typescript
const stream$ = navigator.mediaDevices.getUserMedia({
  video: {facingMode: 'environment'},
})

const detector = new BarcodeDetector()

const value = new Text()
const h1 = document.createElement('h1')
h1.append(value)

const video = document.createElement('video')
video.autoplay = true

const canvas = document.createElement('canvas')
canvas.width = 640
canvas.height = 480

document.body.append(canvas, h1)

const context = canvas.getContext('2d')
if (!context) throw `context error`
```

Vamos separar a função `draw`

## draw.ts

```typescript
export function draw(
  context: CanvasRenderingContext2D,
  paths: Point2D[],
  color = 'lime',
  width = 3
) {
  const [topLeft, topRight, bottomRight, bottomLeft] = paths
  context.strokeStyle = color
  context.lineWidth = width

  context.beginPath()
  context.moveTo(topLeft.x, topLeft.y)
  context.lineTo(topRight.x, topRight.y)
  context.lineTo(bottomRight.x, bottomRight.y)
  context.lineTo(bottomLeft.x, bottomLeft.y)
  context.closePath()
  context.stroke()
}

```

De volta ao `main.ts`, vamos finalizar!

```typescript
// ...

stream$.then((stream) => {
  video.srcObject = stream
  video.ontimeupdate = async () => {
    context.drawImage(video, 0, 0, 640, 480)

    const result = await detector.detect(canvas)

    if (result.length > 0) {
      for (const detected of result) {
        draw(context, detected.cornerPoints)
        value.textContent = detected.rawValue
      }
    }
  }
})

```

E então, o que achou? Espero que tenha gostado!

Abraço
