Let's create a new SharePoint solution.
What is your solution name?
react-spfx-webcam
Which baseline packages do you want to target for your component(s)?
SharePoint Online only (latest)
Where do you want to place the files?
Use the current folder
Do you want to allow the tenant admin the choice of being able to deploy the solution to all sites immediately without running any feature deployment or adding apps in sites?
No
Will the components in the solution require permissions to access web APIs that are unique and not shared with other components in the tenant?
No
Which type of client-side component to create?
WebPart
Add new Web part to solution.
react-spfx-webcam.
What is your Web part name?
spFxwebcam
What is your Web part description?
spFxwebcam description
Which framework would you like to use?
React
We should see local workbench opened in the browser and should be able to add the web part.
Next thing we will do is to install the npm package which will allow the functionality of interacting with desktop/mobile camera.
Go to node js command prompt, run the below command.
Then run the below command.
- npm install @types/react-webcam
Step 4
Let us modify our React component.
Path - \react-spfx-webcam\src\webparts\spFxWebCam\components\SpFxWebCam.tsx
First thing is to add and import the below 2 packages,
- import * as Webcam from "react-webcam";
- import * as ReactDom from 'react-dom';
Please note that package documentation has different syntax to import react-webcam package, but won't work with SPFx hence, use * to import all components in react-webcam.
Replace class definition line with below, what we are doing here is adding 2nd json object to hold data related to camera.
- export default class SpFxWebCam extends React.Component<ISpFxWebCamProps,{imageData: string, image_name:string,webcam:Webcam}> {
Replace render method with below,
- public render(): React.ReactElement<ISpFxWebCamProps> {
- return (
- <div>
- <div className={ styles.spFxWebCam }>
- <div className={ styles.container }>
- <div className={ styles.row }>
- <div className={ styles.column }>
- <span className={ styles.title }>SPFx Web/Mobile Camera Demo </span>
- <p className={ styles.subTitle }>This is demo of how to open webcam and take photo from SPFx webpart.
- It will open camera in mobile web browser also</p>
- <a onClick={() => this.opencam()} className={ styles.button }>
- <span className={ styles.label }>Open webcam</span>
- </a>
- <a onClick={() => this.capture()} className={ styles.button }>
- <span className={ styles.label }>Take Photo</span>
- </a>
- <a onClick={() => this.close()} className={ styles.button }>
- <span className={ styles.label }>Close webcam</span>
- </a>
- </div>
- </div>
- </div>
- </div>
- <div id="camContainer">
- </div>
- <div id="capturedPhoto">
- </div>
- </div>
- );
- }
Let us understand what are we doing here in render method.
- Added 3 buttons, open cam, take a photo and close cam and bind event handler to respective method. We will add events method in the next step.
- Added one div camContainer
where we will add Camera object.
- Added one div capturedPhoto
where we will render captured photo from camera.
Next, let us add supporting methods/events.
Open Cam
- private opencam () {
- const element2: React.ReactElement<Webcam.WebcamProps > = React.createElement(
- Webcam,
- {
- height:350,
- width:350,
- screenshotFormat:"image/jpeg",
- ref:this.setRef,
- }
- );
- ReactDom.render(element2, document.getElementById("camContainer"));
- }
Here, we are creating new React Element and passing Webcam (which itself is a react component). Provide some configuration options as properties to Webcam component. You can find all the available properties at this
link. All these properties can be used, but to keep it simple in the demo, we are using just a basic one.
SetRef
- private setRef = (webcam) => {
- this.setState({webcam:webcam})
- }
This method is setting webcam reference which we just created above to the local component's variable webcam. This will allow us to use webcam properties and methods to the scope of this class (SpFxWebCam).
Capture
- private capture(){
- const imageSrc = this.state.webcam.getScreenshot();
- const element = React.createElement(
- 'img',
- {
- src:imageSrc
- }
- );
- ReactDom.render(element, document.getElementById("capturedPhoto"));
- }
This method will be called when user clicks on 'Take Photo' button. Here the first thing we are doing is using Webcam's getScreenshot method which will take a photo and return as base64 string of the captured photo. We are creating html element img using React.createElement method and providing src as base 64 string. And again finally rendering it to container which we defined in render method.
Close
- public close(){
- ReactDom.unmountComponentAtNode(document.getElementById('camContainer'));
- }
This method will be called when the user clicks on 'Close webcam'. Here we are unmounting webcam from DOM. This will remove camera element from the page.
Step 5
Let us put it to the test, and run 'gulp serve'
We should see local workbench open, add web part like below.
Output
Click on Open Cam
Click on Take photo, it will capture photo and render the image below the camera canvas.
Click on Close cam, it will close the camera.
Photo mentions
Ved in yellow, Ansh in blue and me :).
I have also tested this on a mobile Safari browser on the iPhone, it works as it does on the desktop. Of course we need to take care of mobile responsive CSS.
Looks easy, but it took me a while to put everything together being my first react web part. You can extend this web part to store the captured image in the SharePoint library. We can also do video recording using the stream method on the react-webcam package. We can always extend this web part to -
- Take Photo and update User profile picture using Graph API.
- Store photo in SharePoint document library using JSOM, REST API.
Hope you enjoyed reading!!!