mirror of
https://github.com/VinceG/vue-web-cam.git
synced 2025-12-19 11:29:36 -06:00
first commit
This commit is contained in:
5
.babelrc
Normal file
5
.babelrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"presets": ["es2015", "stage-2"],
|
||||
"plugins": ["transform-runtime"],
|
||||
"comments": false
|
||||
}
|
||||
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
npm-debug.log
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Vincent Gabriel
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# vue-web-cam
|
||||
|
||||
> Webcam component for Vuejs applications
|
||||
40
build/utils.js
Normal file
40
build/utils.js
Normal file
@@ -0,0 +1,40 @@
|
||||
var path = require('path')
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
|
||||
exports.assetsPath = function (_path) {
|
||||
var assetsSubDirectory = process.env.NODE_ENV === 'production'
|
||||
? config.build.assetsSubDirectory
|
||||
: config.dev.assetsSubDirectory
|
||||
return path.posix.join(assetsSubDirectory, _path)
|
||||
}
|
||||
|
||||
exports.cssLoaders = function (options) {
|
||||
options = options || {}
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loaders) {
|
||||
var sourceLoader = loaders.map(function (loader) {
|
||||
var extraParamChar
|
||||
if (/\?/.test(loader)) {
|
||||
loader = loader.replace(/\?/, '-loader?')
|
||||
extraParamChar = '&'
|
||||
} else {
|
||||
loader = loader + '-loader'
|
||||
extraParamChar = '?'
|
||||
}
|
||||
return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
|
||||
}).join('!')
|
||||
|
||||
// Extract CSS when that option is specified
|
||||
// (which is the case during production build)
|
||||
if (options.extract) {
|
||||
return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
|
||||
} else {
|
||||
return ['vue-style-loader', sourceLoader].join('!')
|
||||
}
|
||||
}
|
||||
|
||||
// http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
|
||||
return {
|
||||
css: generateLoaders(['css'])
|
||||
}
|
||||
}
|
||||
34
build/webpack.base.conf.js
Normal file
34
build/webpack.base.conf.js
Normal file
@@ -0,0 +1,34 @@
|
||||
var path = require('path');
|
||||
var projectRoot = path.resolve(__dirname, '../');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
app: './src/index.js'
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
publicPath: '/',
|
||||
filename: '[name].js'
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['', '.js', '.vue'],
|
||||
fallback: [path.join(__dirname, '../node_modules')],
|
||||
alias: {
|
||||
'src': path.resolve(__dirname, '../src')
|
||||
}
|
||||
},
|
||||
resolveLoader: {
|
||||
fallback: [path.join(__dirname, '../node_modules')]
|
||||
},
|
||||
module: {
|
||||
loaders: [{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue'
|
||||
}, {
|
||||
test: /\.js$/,
|
||||
loader: 'babel',
|
||||
include: projectRoot,
|
||||
exclude: /node_modules/
|
||||
}]
|
||||
}
|
||||
}
|
||||
30
build/webpack.dev.conf.js
Normal file
30
build/webpack.dev.conf.js
Normal file
@@ -0,0 +1,30 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
var merge = require('webpack-merge');
|
||||
var baseWebpackConfig = require('./webpack.base.conf');
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
// add hot-reload related code to entry chunks
|
||||
Object.keys(baseWebpackConfig.entry).forEach(function (name) {
|
||||
baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name]);
|
||||
})
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
entry: {
|
||||
app: './src/dev.js'
|
||||
},
|
||||
devtool: '#eval-source-map',
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': "'development'"
|
||||
}),
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
new webpack.NoErrorsPlugin(),
|
||||
new HtmlWebpackPlugin({
|
||||
filename: 'index.html',
|
||||
template: 'index.html',
|
||||
inject: true
|
||||
})
|
||||
]
|
||||
});
|
||||
39
build/webpack.prod.conf.js
Normal file
39
build/webpack.prod.conf.js
Normal file
@@ -0,0 +1,39 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
var merge = require('webpack-merge');
|
||||
var baseWebpackConfig = require('./webpack.base.conf');
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
var HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
var utils = require('./utils');
|
||||
|
||||
var distDir = path.resolve(__dirname, '../dist');
|
||||
|
||||
var webpackConfig = merge(baseWebpackConfig, {
|
||||
devtool: '#source-map',
|
||||
output: {
|
||||
filename: 'js/[name].[chunkhash].js',
|
||||
chunkFilename: 'js/[id].[chunkhash].js'
|
||||
},
|
||||
vue: {
|
||||
loaders: utils.cssLoaders({
|
||||
sourceMap: true,
|
||||
extract: true
|
||||
})
|
||||
},
|
||||
plugins: [
|
||||
// http://vuejs.github.io/vue-loader/en/workflow/production.html
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': "'production'"
|
||||
}),
|
||||
new webpack.optimize.UglifyJsPlugin({
|
||||
compress: {
|
||||
warnings: false
|
||||
}
|
||||
}),
|
||||
new webpack.optimize.OccurenceOrderPlugin(),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin('css/[name].[contenthash].css')
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = webpackConfig;
|
||||
11
index.html
Normal file
11
index.html
Normal file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>vue-web-cam</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
50
package.json
Normal file
50
package.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "vue-web-cam",
|
||||
"version": "1.0.0",
|
||||
"description": "Webcam component for Vuejs applications",
|
||||
"author": {
|
||||
"name": "Mohammad Shoriful Islam Ronju",
|
||||
"email": "smronju@gmail.com",
|
||||
"url": "https://github.com/smronju"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Vincent Gabriel",
|
||||
"email": "vadimg88@gmail.com",
|
||||
"url": "https://github.com/vinceg"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"build": "webpack -p --config build/webpack.prod.conf.js",
|
||||
"dev": "webpack-dev-server --inline --hot --config build/webpack.dev.conf.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^2.0.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vinceg/vue-web-cam"
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-loader": "^6.0.0",
|
||||
"babel-plugin-transform-runtime": "^6.0.0",
|
||||
"babel-preset-es2015": "^6.0.0",
|
||||
"babel-preset-stage-2": "^6.0.0",
|
||||
"babel-register": "^6.0.0",
|
||||
"babel-runtime": "^6.0.0",
|
||||
"css-loader": "^0.25.0",
|
||||
"extract-text-webpack-plugin": "^1.0.1",
|
||||
"function-bind": "^1.0.2",
|
||||
"html-webpack-plugin": "^2.8.1",
|
||||
"vue-loader": "^9.4.0",
|
||||
"vue-style-loader": "^1.0.0",
|
||||
"webpack": "^1.13.2",
|
||||
"webpack-dev-server": "^1.16.2",
|
||||
"webpack-merge": "^0.14.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
}
|
||||
7
src/dev.js
Normal file
7
src/dev.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import Main from './main'
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
...Main
|
||||
})
|
||||
10
src/index.js
Normal file
10
src/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
import Main from './main'
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
window.Main = Main
|
||||
}
|
||||
|
||||
export {
|
||||
Main
|
||||
}
|
||||
28
src/main.vue
Normal file
28
src/main.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<div id="app" class="component">
|
||||
<webcam ref="webcam"></webcam>
|
||||
<img :src="this.img" style="width:500px;height:500px;" />
|
||||
<button type="button" @click="photo">Capture Photo</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Webcam from './Webcam'
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
data() {
|
||||
return {
|
||||
img: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
photo() {
|
||||
this.img = this.$refs.webcam.capture();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Webcam
|
||||
}
|
||||
}
|
||||
</script>
|
||||
85
src/webcam.vue
Normal file
85
src/webcam.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<video ref="video" :width="this.width" :height="this.height" :src="this.source" :autoplay="this.true"></video>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
stream: '',
|
||||
source: '',
|
||||
canvas: null
|
||||
};
|
||||
},
|
||||
props: {
|
||||
width: {
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 500
|
||||
},
|
||||
autoplay: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
screenshotFormat: {
|
||||
type: String,
|
||||
default: 'image/jpeg'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (!this.hasMedia()) {
|
||||
this.$emit('notsupported');
|
||||
return;
|
||||
}
|
||||
|
||||
this.requestMedia();
|
||||
|
||||
if (navigator.getUserMedia) {
|
||||
navigator.getUserMedia({ video: true }, stream => {
|
||||
this.source = window.URL.createObjectURL(stream);
|
||||
this.stream = stream;
|
||||
this.$emit('started', stream);
|
||||
}, error => {
|
||||
this.$emit('error', error);
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hasMedia() {
|
||||
return !!this.getMedia();
|
||||
},
|
||||
getMedia() {
|
||||
return (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia);
|
||||
},
|
||||
requestMedia() {
|
||||
navigator.getUserMedia = this.getMedia();
|
||||
},
|
||||
capture() {
|
||||
if (!this.hasMedia()) {
|
||||
this.$emit('notsupported');
|
||||
return null;
|
||||
}
|
||||
return this.getCanvas().toDataURL(this.screenshotFormat);
|
||||
},
|
||||
getCanvas() {
|
||||
let video = this.$refs.video;
|
||||
if (!this.ctx) {
|
||||
let canvas = document.createElement('canvas');
|
||||
canvas.height = video.clientHeight;
|
||||
canvas.width = video.clientWidth;
|
||||
this.canvas = canvas;
|
||||
|
||||
this.ctx = canvas.getContext('2d');
|
||||
}
|
||||
|
||||
const { ctx, canvas } = this;
|
||||
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
|
||||
return canvas;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user