scanDocument method

  1. @override
Future<String?> scanDocument()
override

Returns a String containing the version of the platform.

Implementation

@override
Future<String?> scanDocument() async {
  final completer = Completer<String?>();

  // I tried to add some styling, but finished with this
  final html.DivElement modal = html.DivElement()
    ..style.position = 'fixed'
    ..style.left = '0'
    ..style.top = '0'
    ..style.width = '100%'
    ..style.height = '100%'
    ..style.backgroundColor = 'rgba(0, 0, 0, 0.8)'
    ..style.zIndex = '9999'
    ..style.display = 'flex'
    ..style.flexDirection = 'column'
    ..style.alignItems = 'center'
    ..style.justifyContent = 'center';

  final html.VideoElement videoElement = html.VideoElement()
    ..autoplay = true
    ..style.borderRadius = '10px';

  videoElement.onLoadedMetadata.listen((_) {
    // It was too big :/
    // videoElement.width = videoElement.videoWidth;
    // videoElement.height = videoElement.videoHeight;
    videoElement.width = 640;
    videoElement.height = 480;
  });

  final html.MediaStream stream =
      await html.window.navigator.getUserMedia(video: true);
  videoElement.srcObject = stream;

  final html.ButtonElement captureButton = html.ButtonElement()
    ..innerText = 'Capture'
    ..style.marginTop = '20px'
    ..style.padding = '10px 20px'
    ..style.fontSize = '16px'
    ..style.borderRadius = '5px'
    ..onClick.listen((_) async {
      final html.CanvasElement canvas = html.CanvasElement();
      final html.MediaStreamTrack track = stream.getVideoTracks()[0];
      final html.ImageCapture imageCapture = html.ImageCapture(track);
      final html.ImageBitmap image = await imageCapture.grabFrame();
      final ratio = image.width! / 640;
      canvas.width = 640;
      // Scale the height of canvas according to the ratio
      canvas.height = (image.height! / ratio).toInt();

      final html.CanvasRenderingContext2D context =
          canvas.getContext('2d') as html.CanvasRenderingContext2D;
      context.drawImageScaled(
          videoElement, 0, 0, canvas.width!, canvas.height!);
      final base64Image = canvas.toDataUrl().split(',').last;
      stream.getTracks().forEach((track) => track.stop());
      modal.remove();
      completer.complete(base64Image);
    });

  final html.ButtonElement cancelButton = html.ButtonElement()
    ..innerText = 'Cancel'
    ..style.marginTop = '10px'
    ..style.padding = '10px 20px'
    ..style.fontSize = '16px'
    ..style.borderRadius = '5px'
    ..onClick.listen((_) {
      stream.getTracks().forEach((track) => track.stop());
      modal.remove();
      completer.complete(null);
    });

  modal.append(videoElement);
  modal.append(captureButton);
  modal.append(cancelButton);
  html.document.body?.append(modal);

  return completer.future;
}