I'm working on implementing a QR reader in a web based app that uses the PC's webcam. This is currently working correct.
The framework that I use (barcode.js) has a function render(element).
I have 2 different files, ScannerView.html and ScannerView.js. See their code below:
ScannerView.html
<!-- Content Header (Page header) -->
<section class="content-header has-background-image">
<div class="background">
<img src="/assets/temp/header.png" />
</div>
<h1><div class="icon"><i class="fa fa-wrench"></i></div> <%=name%></h1>
</section>
<section class="content">
// Withing the following div, the canvas element should be placed
<div id="scanner"></div>
</section>
ScannerView.js
var YookrApp = require("../../setup");
var scanner = null;
var ScannerView = Backbone.Marionette.CompositeView.extend({
template: require("./ScannerView.html"),
className: "scannerView",
ui: {
scannerDiv: "#scanner"
},
name: "Yookr Code Scanner",
initialize: function(options) {
},
onRender: function() {
w69b.qr.decoding.setWorkerUrl("assets/w69b.qrcode.decodeworker.js");
scanner = new w69b.qr.ui.ContinuousScanner();
// Called when a qr code has been decoded.
scanner.setDecodedCallback(function(result) {
console.log("Decoded qr code:", result);
});
scanner.setStopped(false);
// Render component in element with id "scanner".
console.log("Start rendering");
scanner.render(this.ui.scannerDiv);
console.log("Rendering done");
},
close: function() {
// We have to dispose the scanner object.
// If we don"t do this, the webcam will
// always be enabled
scanner.dispose();
}
});
module.exports = ScannerView;
When I run my app, the scanner.render()
function should add a <canvas>
element inside <div id="scanner"></div>
in ScannerView.html
Problem
I'm not able to render the canvas using scanner.render()
properly withing the <div id="scanner"></div>
that is located in my html file. I tried to use document.getElementById and this.ui.scannerDiv with different, but not correct result.
Because I defined an UI element in the ScannerView.js file, I should be able to call scanner.render(this.ui.scannerDiv);
This should use the div with id scanner in my html view, but instead the canvas is not rendered at all. In my console, I can see the following warnings:
[.Offscreen-For-WebGL-0000020AB57365B0]GL ERROR :GL_INVALID_FRAMEBUFFER_OPERATION : glDrawArrays: framebuffer incomplete
and
[.Offscreen-For-WebGL-0000020AB57365B0]RENDER WARNING: texture bound to texture unit 2 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.
When I use scanner.render(document.getElementById("scanner"));
, I can see that the canvas is rendered, but not in the correct location. Please see my added screenshot for the result:
At this point I'm stuck. I dont know how I can achieve that the canvas is rendered in the correct div.
After searching Google for a while longer, I found a solution.
The onRender: function() { }
"gets triggered when the View's DOM subtree is prepared for insertion into the DOM but before those elements are viewable", according to this webiste.
after changing onRender
to onShow
in my javascript file, the canvas element is rendered in the correct location.