serratus/quaggaJS

Draw a target line across the screen

afriedma opened this issue · 4 comments

Hi,

Thank you for an amazing library. I have a pwa app, and it works great. The issue I currently have is that after making the canvas responsive by setting

#barcode-scanner video, canvas {
width: 100%;
height: auto;
}

my screen height is longer then my width, I lost the barcode canvas shape, and its confusing to users.

I saw people mentioning but there is no concrete example on how to draw a target line across the screen to make it more intuitive for the user. Is it possible? I installed version 0.12.1 from npm.

Can someone please advise?

Thank you in advance for your help.

@ericblade, is my question doesn’t makes sense? Can you clarify?

You could just place an HTML element over the top of the canvas, I think? Or you could draw something using the canvas, as many of the examples do with barcode detection lines.

@ericblade thank you for your help.

I ended up, absolute positioning the line over the canvas.
For those who may find it useful, solution I came up with below

----- CSS

#barcode-scanner video, canvas {
  width: 100%;
  height: auto;
}

#barcode-scanner video.drawingBuffer, canvas.drawingBuffer {
  display: none;
}

.line{
  width: var(--scan-width);
  height: var(--scan-height);
  border-bottom: 10px double lime;
  position: absolute;
}

---HTML

<div id="barcode-scanner">
    <video src=""></video>
    <canvas class="drawingBuffer"></canvas>
</div>
<div #drawLine [style.visibility]="show ? 'visible' : 'hidden'" class="line" style="position: absolute;
top: var(--scan-top);
left: var(--scan-left);"></div>

--Typescript

var loc = this.elService.getOffset(document.getElementById('barcode-scanner'));
var width = this.elService.elementWidth(document.getElementById('barcode-scanner'));
var height = this.elService.elementHeight(document.getElementById('barcode-scanner'));

@ViewChild('drawLine') container: ElementRef;

this.container.nativeElement.style.setProperty('--scan-top', (loc.top+width/8) + "px")
this.container.nativeElement.style.setProperty('--scan-left', loc.left + "px")
this.container.nativeElement.style.setProperty('--scan-width', width - 50 + "px")
this.container.nativeElement.style.setProperty('--scan-height', height  / 12 + "px")

-- Service

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class ElementService {

  constructor() { }

  elementHeight(el) {
    var w = window,
      d = document,
      e = d.documentElement,
      g = el[0],
      y = w.innerHeight || e.clientHeight || g.clientHeight;
    return y;
  }

  elementWidth(el) {
    var w = window,
      d = document,
      e = d.documentElement,
      g = el[0],
      x = w.innerWidth || e.clientWidth || g.clientWidth;
    return x;
  }

  getOffset(el) {
    var _x = 0;
    var _y = 0;
    while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) {
      _x += el.offsetLeft - el.scrollLeft;
      _y += el.offsetTop - el.scrollTop;
      el = el.offsetParent;
    }
    return { top: _y, left: _x };
  }

  vhTOpx(value) {
    var w = window,
      d = document,
      e = d.documentElement,
      g = d.getElementsByTagName('body')[0],
      x = w.innerWidth || e.clientWidth || g.clientWidth,
      y = w.innerHeight || e.clientHeight || g.clientHeight;

    var result = (y * value) / 100;
    return result;
  }

  bodyHeight() {
    var w = window,
      d = document,
      e = d.documentElement,
      g = d.getElementsByTagName('body')[0],
      y = w.innerHeight || e.clientHeight || g.clientHeight;
    return y;
  }

  bodyWidth() {
    var w = window,
      d = document,
      e = d.documentElement,
      g = d.getElementsByTagName('body')[0],
      x = w.innerWidth || e.clientWidth || g.clientWidth;
    return x;
  }
}