[PWA] Access the Camera in a PWA built with React

It‘s possible to access some,but not all,of the native device features from a PWA. One that we canaccess,is the camera and camera roll. We‘ll use two different methods to allow users to upload images to our application.

First,we‘ll add a file input that accepts images. We can specify a capture param,which will tell PWAs on mobile devices to prompt the user to take a picture with their camera.

Next,we‘ll access the camera feed directly by rendering a video tag,and accessing navigator.mediaDevices.getUserMedia directly - which will allow us to show a live video feed from the camera. Then,we can use a canvas tag to grab a frame from that video,and render the image.

 

class Profile extends Component {

  state = {
    image: null,supportsCamera: ‘mediaDevices‘ in navigator
  }

  changeImage = (e) => {
    this.setState({
      image: URL.createObjectURL(e.target.files[0])
    })
  }

  startChangeImage = () => {
    this.setState({ enableCamera: !this.state.enableCamera })
  }

  takeImage = () => {
    this._canvas.width = this._video.videoWidth
    this._canvas.height = this._video.videoHeight

    this._canvas.getContext(‘2d‘).drawImage(
      this._video,this._video.videoWidth,this._video.videoHeight
    )

    this._video.srcObject.getVideoTracks().forEach(track => {
      track.stop()
    })

    this.setState({
      image: this._canvas.toDataURL(),enableCamera: false
    })
  }

  render() {
    return (
      <div>
        <nav className="navbar navbar-light bg-light">
            <span className="navbar-brand mb-0 h1">
              <Link to="/">
                <img src={Back} alt="logo" style={{ height: 30 }} />
              </Link>
              Profile
            </span>
        </nav>

        <div style={{ textAlign: ‘center‘ }}>
          <img 
            src={this.state.image || GreyProfile} alt="profile" 
            style={{ height: 200,marginTop: 50 }} 
          />
          <p style={{ color: ‘#888‘,fontSize: 20 }}>username</p>

          {
            this.state.enableCamera &&
            <div>
              <video 
                ref={c => {
                  this._video = c
                  if(this._video) {
                    navigator.mediaDevices.getUserMedia({ video: true })
                      .then(stream => this._video.srcObject = stream)
                  }
                }}
                controls={false} autoPlay
                style={{ width: ‘100%‘,maxWidth: 300 }}
              ></video>

              <br />

              <button
                onClick={this.takeImage}
              >Take Image</button>

              <canvas 
                ref={c => this._canvas = c}
                style={{ display: ‘none‘ }}
              />

            </div>
          }

          <br />
          {
            this.state.supportsCamera &&
            <button
              onClick={this.startChangeImage}
            >
              Toggle Camera
            </button>
          }
        </div>

      </div>
    )
  }

}

 

Video,Code

相关文章

react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接...
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc ...