Skip to content
This repository has been archived by the owner on Oct 10, 2020. It is now read-only.

Commit

Permalink
Web support
Browse files Browse the repository at this point in the history
  • Loading branch information
fercarcedo committed Mar 17, 2020
1 parent a4a010c commit 460b2a1
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 2 deletions.
235 changes: 235 additions & 0 deletions flutter_barcode_reader_web/lib/barcode_web.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
@JS()
library jsqrscanner;

import 'dart:async';
import 'dart:html';

import 'package:flutter/services.dart';
import 'package:js/js.dart';
import 'package:js/js_util.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';

class BarcodeScanPlugin {
Completer<String> _completer;

static void registerWith(Registrar registrar) {
final MethodChannel channel = MethodChannel(
'de.mintware.barcode_scan',
const StandardMethodCodec(),
registrar.messenger
);
final BarcodeScanPlugin instance = new BarcodeScanPlugin();
channel.setMethodCallHandler(instance.handleMethodCall);
}

Future<String> handleMethodCall(MethodCall call) async {
_createCSS();
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
document.querySelector('head').append(script);
script.setAttribute('src', 'https://cdn.jsdelivr.net/gh/jbialobr/JsQRScanner@master/war/js/jsqrscanner.nocache.js');
_createHTML();
document.querySelector('#toolbar p').addEventListener('click', (event) => close());
setProperty(window, 'JsQRScannerReady', allowInterop(this.scannerReady));
_completer = new Completer<String>();
return _completer.future;
}

void _createCSS() {
var style = document.createElement('style');
style.appendText('''
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
#container {
position: fixed;
width: 100%;
height: 100%;
background-color: #2F2F2F;
}
video {
position: relative;
top: 0;
left: 0;
height: 100vh;
width: 100vw;
object-fit: cover;
}
#cover {
position: absolute;
top: 50%;
left: 50%;
width: 70vmin;
height: 70vmin;
transform: translateX(-50%) translateY(-50%);
text-align: center;
}
#cover:after {
content:'';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
box-shadow: 0 0 0 999px rgba(0, 0, 0, 0.4);
}
#cover img {
width: 100%;
height: 100%;
}
#cover > div {
background-color: #BFE47B;
}
#topleft, #lefttop {
position: absolute;
top: 0;
left: 0;
}
#topleft {
width: 8vmin;
height: 2vmin;
}
#lefttop {
width: 2vmin;
height: 8vmin;
}
#topright, #righttop {
position: absolute;
top: 0;
right: 0;
}
#topright {
width: 8vmin;
height: 2vmin;
}
#righttop {
width: 2vmin;
height: 8vmin;
}
#bottomleft, #leftbottom {
position: absolute;
bottom: 0;
left: 0;
}
#bottomleft {
width: 8vmin;
height: 2vmin;
}
#leftbottom {
width: 2vmin;
height: 8vmin;
}
#bottomright, #rightbottom {
position: absolute;
bottom: 0;
right: 0;
}
#bottomright {
width: 8vmin;
height: 2vmin;
}
#rightbottom {
width: 2vmin;
height: 8vmin;
}
#toolbar {
background-color: #2F2F2F;
}
#toolbar p {
float: left;
font-size: 24px;
color: white;
margin-left: 16px;
padding: 16px;
}
#clear {
clear: both;
}
''');
document.querySelector('head').append(style);
}

void _createHTML() {
var containerDiv = document.createElement('div');
containerDiv.id = 'container';
containerDiv.innerHtml = '''
<div id="toolbar">
<p>X</p>
<div id="clear"></div>
</div>
<div id="scanner"></div>
<div id="cover">
<div id="topleft"></div>
<div id="lefttop"></div>
<div id="topright"></div>
<div id="righttop"></div>
<div id="bottomleft"></div>
<div id="leftbottom"></div>
<div id="bottomright"></div>
<div id="rightbottom"></div>
</div>
''';
document.body.append(containerDiv);
}

void onQRCodeScanned(String scannedText) {
_completer.complete(scannedText);
_close();
}

void _close() {
document.getElementById('container').remove();
}

void scannerReady() {
var scanner = JsQRScanner(onQRCodeScanned, provideVideo);
scanner.setSnapImageMaxSize(300);
var scannerParentElement = document.getElementById('scanner');
scanner.appendTo(scannerParentElement);
}

Promise<MediaStream> provideVideo() {
return new Promise<MediaStream>(allowInterop((resolve, reject) {
window.navigator.getUserMedia(video: true).then(resolve, onError: reject);
}));
}
}

@JS()
class JsQRScanner {
external factory JsQRScanner(Function onQRCodeScanned, Function provideVideo);
external setSnapImageMaxSize(int maxSize);
external appendTo(Element element);
}

@JS()
class Promise<T> {
external Promise(void executor(void resolve(T result), Function reject));
external Promise then(void onFulfilled(T result), [Function onRejected]);
}
22 changes: 22 additions & 0 deletions flutter_barcode_reader_web/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: barcode_scan_web
description: A flutter plugin for scanning 2D barcodes and QRCodes via camera.
version: 2.0.1
homepage: https://github.com/mintware-de/flutter_barcode_reader

dependencies:
flutter:
sdk: flutter
flutter_web_plugins:
sdk: flutter
js: ^0.6.0

environment:
sdk: ">=2.0.0-dev.58.0 <3.0.0"
flutter: ^1.10.0

flutter:
plugin:
platforms:
web:
pluginClass: BarcodeScanPlugin
fileName: barcode_web.dart
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ dependencies:
flutter:
sdk: flutter

environment:
sdk: ">=2.0.0-dev.58.0 <3.0.0"
environment:
sdk: ">=2.0.0-dev.58.0 <3.0.0"

flutter:
plugin:
Expand Down

0 comments on commit 460b2a1

Please sign in to comment.