功能
点击一个按弹出一个框可以点击拍照生成Base64图片
效果图
上代码
import React, { PureComponent, Fragment } from 'react';
import { Button, Row, Col } from 'antd'
// import avatar from './avatar.png' // 背景图
//视频流
let trackStrem
/**
* 参数
* @param {getCameraRef} function 获取子类ref
* @param {onChange} function 传递图片数据
* @param {image} base64 图片数据
*/
export default class Camera extends PureComponent {
state = {
camState: 1
}
componentDidMount() {
// 如果没有对子类属性控制的需求可以直接注释这个回调函数 getCameraRef
const { image, getCameraRef } = this.props;
getCameraRef(this)
if (image) {
this.changeState(1)
} else {
this.changeState(2)
}
}
componentWillUnmount() {
this.closeCamera()
}
// 状态切换
changeState = (state) => {
switch (state) {
case 1:
this.setState({ camState: 1 })
break;
case 2:
this.setState({ camState: 2 })
this.openCamera()
break;
case 3:
this.setState({ camState: 3 })
this.catchPhoto()
this.closeCamera()
break;
}
}
// 打开摄像头
openCamera = () => {
console.log(`open camera...`)
const video = this.refs.video
const videoObj = {
video: {
width: 320,
height: 240
}
}
const errBack = function (error) {
console.log(error.message);
console.log("Video capture error: ", error.message + " " + error.code);
}
// 判断媒体对象是否有权限
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
navigator.mediaDevices.getUserMedia(videoObj).then(function (stream) {
console.log(`video`, video)
video.srcObject = trackStrem = stream
video.play()
}).catch(function (err) {
errBack(err)
})
}
else window.alert('打开摄像头失败')
}
// 关闭摄像头
closeCamera = () => {
console.log(`close camera...`)
if (this.refs.video) this.refs.video.pause();
if (trackStrem) trackStrem.getTracks()[0].stop();
}
// 保存图片
catchPhoto = () => {
const { onChange } = this.props;
const canvas = this.refs.canvas
const video = this.refs.video
let context = canvas.getContext("2d")
context.drawImage(video, 0, 0, 320, 240);
// 从画布上获取照片数据
let imgData = canvas.toDataURL(`image/jpeg`);
// 对外派发图片数据
if (onChange) onChange(imgData)
}
render() {
const { camState } = this.state
const { image } = this.props;
console.log(`camState`, camState)
return (
<Row>
<Col span={24} style={{ padding: 12, textAlign: 'center' }}>
<img style={{ width: 320, height: 240, display: camState === 1 ? 'block' : 'none' }} src={image} />
{/* <img alt="avatar" src={avatar} style={{ zIndex: 100, position: 'absolute', x: 0, y: 0, display: camState === 1 ? 'none' : 'block' }} /> */}
<video ref="video" width="320" height="240" autoPlay style={{ display: camState === 1 ? 'none' : 'block' }}></video>
<canvas ref="canvas" width="320" height="240" style={{ display: 'none' }}></canvas>
</Col>
<Col span={24} style={{ padding: 12, textAlign: 'center' }}>
{camState === 2 ? <Button onClick={() => this.changeState(3)} type="primary">保存快照</Button> : <Button onClick={() => this.changeState(2)} type="primary">重新拍照</Button>}
</Col>
</Row>
);
}
}