Merge pull request #982 from siddharth-vaghasia/gdev

Sample webpart for opening webcam and capture photo
This commit is contained in:
Laura Kokkarinen 2019-09-08 12:36:33 +03:00 committed by GitHub
commit af2908daee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 19934 additions and 0 deletions

View File

@ -0,0 +1,25 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# change these settings to your own preference
indent_style = space
indent_size = 2
# we recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[{package,bower}.json]
indent_style = space
indent_size = 2

32
samples/react-spfx-webcam/.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
# Logs
logs
*.log
npm-debug.log*
# Dependency directories
node_modules
# Build generated files
dist
lib
solution
temp
*.sppkg
# Coverage directory used by tools like istanbul
coverage
# OSX
.DS_Store
# Visual Studio files
.ntvs_analysis.dat
.vs
bin
obj
# Resx Generated Code
*.resx.ts
# Styles Generated Code
*.scss.ts

View File

@ -0,0 +1,12 @@
{
"@microsoft/generator-sharepoint": {
"isCreatingSolution": false,
"environment": "spo",
"version": "1.9.1",
"libraryName": "react--spfx-webcam",
"libraryId": "a8075f7d-4517-44af-884c-5f0b348f8e57",
"packageManager": "npm",
"isDomainIsolated": false,
"componentType": "webpart"
}
}

View File

@ -0,0 +1,62 @@
# SPFx Web/Mobile Camera Demo
## Summary
This is sample webpart to showcase how to open webcam and take photo in SPFx webpart. This will work in desktop/laptop with webcam and mobile device also(from browser). This can be extended to stored captured photo in document library or it can be saved as user profile photo using GRAPH API.
* [Please refer this link on How to build this from Scratch](https://www.c-sharpcorner.com/article/how-to-open-webmobile-camera-and-take-photo-from-spfx-webpart/)
![Options Available](screens/3.png?raw=true "Options Available")
![Opening webcam](screens/4.png?raw=true "Opening webcam")
![Taking photo](screens/4.png?raw=true "Taking photo")
## Used SharePoint Framework Version
![drop](https://img.shields.io/badge/version-1.9.1-green.svg)
## Applies to
* [SharePoint Framework](http://dev.office.com/sharepoint/docs/spfx/sharepoint-framework-overview)
* [Office 365 tenant](http://dev.office.com/sharepoint/docs/spfx/set-up-your-developer-tenant)
## Prerequisites
> N/A
## Solution
Solution|Author(s)
--------|---------
react-spfx-webcam | Siddharth Vaghasia(@siddh_me)
## Version history
Version|Date|Comments
-------|----|--------
1.0.0|Sept 05, 2019|Upgraded to Latest SPFx Version 1.9.1
1.0.0|Sept 04, 2019|Initial release
## Disclaimer
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
---
## Minimal Path to Awesome
* Clone this repository
* in the command line run:
* `npm install`
* `gulp serve`
## Features
This Web Part illustrates the following concepts on top of the SharePoint Framework:
* Using react framework in SPFx webpart
* Using react-webcam npm package in SPFx webpart
* Open web cam or mobile camera to capture photo and display in img html element
<img src="https://telemetry.sharepointpnp.com/sp-dev-fx-webparts/samples/react-spfx-webcam" />

View File

@ -0,0 +1,18 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/config.2.0.schema.json",
"version": "2.0",
"bundles": {
"sp-fx-web-cam-web-part": {
"components": [
{
"entrypoint": "./lib/webparts/spFxWebCam/SpFxWebCamWebPart.js",
"manifest": "./src/webparts/spFxWebCam/SpFxWebCamWebPart.manifest.json"
}
]
}
},
"externals": {},
"localizedResources": {
"SpFxWebCamWebPartStrings": "lib/webparts/spFxWebCam/loc/{locale}.js"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/copy-assets.schema.json",
"deployCdnPath": "temp/deploy"
}

View File

@ -0,0 +1,7 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/deploy-azure-storage.schema.json",
"workingDir": "./temp/deploy/",
"account": "<!-- STORAGE ACCOUNT NAME -->",
"container": "react-spfx-webcam",
"accessKey": "<!-- ACCESS KEY -->"
}

View File

@ -0,0 +1,13 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
"solution": {
"name": "react-spfx-webcam-client-side-solution",
"id": "a8075f7d-4517-44af-884c-5f0b348f8e57",
"version": "1.0.0.0",
"includeClientSideAssets": true,
"isDomainIsolated": false
},
"paths": {
"zippedPackage": "solution/react-spfx-webcam.sppkg"
}
}

View File

@ -0,0 +1,10 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/core-build/serve.schema.json",
"port": 4321,
"https": true,
"initialPage": "https://localhost:5432/workbench",
"api": {
"port": 5432,
"entryPath": "node_modules/@microsoft/sp-webpart-workbench/lib/api/"
}
}

View File

@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx-build/write-manifests.schema.json",
"cdnBasePath": "<!-- PATH TO CDN -->"
}

7
samples/react-spfx-webcam/gulpfile.js vendored Normal file
View File

@ -0,0 +1,7 @@
'use strict';
const gulp = require('gulp');
const build = require('@microsoft/sp-build-web');
build.addSuppression(`Warning - [sass] The local CSS class 'ms-Grid' is not camelCase and will not be type-safe.`);
build.initialize(gulp);

19357
samples/react-spfx-webcam/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,45 @@
{
"name": "react-spfx-webcam",
"version": "1.0.0",
"private": true,
"engines": {
"node": ">=0.10.0"
},
"scripts": {
"build": "gulp bundle",
"clean": "gulp clean",
"test": "gulp test"
},
"dependencies": {
"@microsoft/rush-stack-compiler-3.2": "^0.3.33",
"@microsoft/sp-core-library": "1.9.1",
"@microsoft/sp-lodash-subset": "1.9.1",
"@microsoft/sp-office-ui-fabric-core": "1.9.1",
"@microsoft/sp-property-pane": "1.9.1",
"@microsoft/sp-webpart-base": "1.9.1",
"@types/es6-promise": "0.0.33",
"@types/react": "16.8.8",
"@types/react-dom": "16.8.3",
"@types/react-webcam": "^1.1.0",
"@types/webpack-env": "1.13.1",
"office-ui-fabric-react": "6.189.2",
"react": "16.7.0",
"react-dom": "16.7.0",
"react-webcam": "^1.1.1"
},
"resolutions": {
"@types/react": "16.8.8"
},
"devDependencies": {
"@microsoft/rush-stack-compiler-2.9": "0.7.16",
"@microsoft/sp-build-web": "1.9.1",
"@microsoft/sp-module-interfaces": "1.9.1",
"@microsoft/sp-tslint-rules": "1.9.1",
"@microsoft/sp-webpart-workbench": "1.9.1",
"@types/chai": "3.4.34",
"@types/mocha": "2.2.38",
"ajv": "~5.2.2",
"gulp": "~3.9.1",
"webpack": "^4.39.3"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

View File

@ -0,0 +1 @@
// A file is required to be in the root of the /src directory by the TypeScript compiler

View File

@ -0,0 +1,27 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
"id": "0c2e8714-8a46-464f-8211-dc47216ae32d",
"alias": "SpFxWebCamWebPart",
"componentType": "WebPart",
// The "*" signifies that the version should be taken from the package.json
"version": "*",
"manifestVersion": 2,
// If true, the component can only be installed on sites where Custom Script is allowed.
// Components that allow authors to embed arbitrary script code should set this to true.
// https://support.office.com/en-us/article/Turn-scripting-capabilities-on-or-off-1f2c515f-5d7e-448a-9fd7-835da935584f
"requiresCustomScript": false,
"supportedHosts": ["SharePointWebPart"],
"preconfiguredEntries": [{
"groupId": "5c03119e-3074-46fd-976b-c60198311f70", // Other
"group": { "default": "Other" },
"title": { "default": "SPFxWebCam" },
"description": { "default": "SPFxWebCam description" },
"officeFabricIconFontName": "Camera",
"properties": {
"description": "SPFxWebCam"
}
}]
}

View File

@ -0,0 +1,63 @@
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import {
IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import * as strings from 'SpFxWebCamWebPartStrings';
import SpFxWebCam from './components/SpFxWebCam';
import { ISpFxWebCamProps } from './components/ISpFxWebCamProps';
export interface ISpFxWebCamWebPartProps {
description: string;
}
export default class SpFxWebCamWebPart extends BaseClientSideWebPart<ISpFxWebCamWebPartProps> {
public render(): void {
const element: React.ReactElement<ISpFxWebCamProps > = React.createElement(
SpFxWebCam,
{
description: this.properties.description
}
);
ReactDom.render(element, this.domElement);
//ReactDom.render(element2, document.getElementById("mywebcam"));
}
protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}
protected get dataVersion(): Version {
return Version.parse('1.0');
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: strings.PropertyPaneDescription
},
groups: [
{
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField('description', {
label: strings.DescriptionFieldLabel
})
]
}
]
}
]
};
}
}

View File

@ -0,0 +1,7 @@
export interface ISpFxWebCamProps {
description: string;
}

View File

@ -0,0 +1,75 @@
@import '~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss';
.spFxWebCam {
.container {
max-width: 700px;
margin: 0px auto;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
.row {
@include ms-Grid-row;
@include ms-fontColor-white;
background-color: $ms-color-themeDark;
padding: 20px;
}
.column {
@include ms-Grid-col;
@include ms-lg10;
@include ms-xl8;
@include ms-xlPush2;
@include ms-lgPush1;
}
.title {
@include ms-font-xl;
@include ms-fontColor-white;
}
.subTitle {
@include ms-font-l;
@include ms-fontColor-white;
}
.description {
@include ms-font-l;
@include ms-fontColor-white;
}
.button {
// Our button
text-decoration: none;
height: 32px;
margin-right: 10px;
// Primary Button
min-width: 80px;
background-color: $ms-color-themePrimary;
border-color: $ms-color-themePrimary;
color: $ms-color-white;
// Basic Button
outline: transparent;
position: relative;
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
-webkit-font-smoothing: antialiased;
font-size: $ms-font-size-m;
font-weight: $ms-font-weight-regular;
border-width: 0;
text-align: center;
cursor: pointer;
display: inline-block;
padding: 0 16px;
.label {
font-weight: $ms-font-weight-semibold;
font-size: $ms-font-size-m;
height: 32px;
line-height: 32px;
margin: 0 4px;
vertical-align: top;
display: inline-block;
}
}
}

View File

@ -0,0 +1,79 @@
import * as React from 'react';
import styles from './SpFxWebCam.module.scss';
import { ISpFxWebCamProps } from './ISpFxWebCamProps';
import { escape } from '@microsoft/sp-lodash-subset';
import * as Webcam from "react-webcam";
import * as ReactDom from 'react-dom';
import { Button } from 'office-ui-fabric-react/lib/Button';
export default class SpFxWebCam extends React.Component<ISpFxWebCamProps,{imageData: string, image_name:string,webcam:Webcam,stream:any}> {
private _camContainer: HTMLElement = undefined;
private _capturedPhoto: HTMLElement = undefined;
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" ref={(elm) => { this._camContainer = elm; }}>
</div>
<div id="capturedPhoto" ref={(elm) => { this._capturedPhoto = elm; }}>
</div>
</div>
);
}
private setRef = (webcam) => {
this.setState({webcam:webcam})
}
public close(){
ReactDom.unmountComponentAtNode(this._camContainer);
}
private capture(){
const imageSrc = this.state.webcam.getScreenshot();
const element = React.createElement(
'img',
{
src:imageSrc
}
);
ReactDom.render(element, this._capturedPhoto);
}
private opencam () {
const element2: React.ReactElement<Webcam.WebcamProps > = React.createElement(
Webcam,
{
height:350,
width:350,
screenshotFormat:"image/jpeg",
ref:this.setRef,
}
);
//const camContainer = document.getElementById("camContainer")
ReactDom.render(element2, this._camContainer);
}
}

View File

@ -0,0 +1,7 @@
define([], function() {
return {
"PropertyPaneDescription": "Description",
"BasicGroupName": "Group Name",
"DescriptionFieldLabel": "Description Field"
}
});

View File

@ -0,0 +1,10 @@
declare interface ISpFxWebCamWebPartStrings {
PropertyPaneDescription: string;
BasicGroupName: string;
DescriptionFieldLabel: string;
}
declare module 'SpFxWebCamWebPartStrings' {
const strings: ISpFxWebCamWebPartStrings;
export = strings;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,39 @@
{
"extends": "./node_modules/@microsoft/rush-stack-compiler-2.9/includes/tsconfig-web.json",
"compilerOptions": {
"target": "es5",
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"jsx": "react",
"declaration": true,
"sourceMap": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"outDir": "lib",
"inlineSources": false,
"strictNullChecks": false,
"noUnusedLocals": false,
"allowSyntheticDefaultImports": true,
"typeRoots": [
"./node_modules/@types",
"./node_modules/@microsoft"
],
"types": [
"es6-promise",
"webpack-env"
],
"lib": [
"es5",
"dom",
"es2015.collection"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules",
"lib"
]
}

View File

@ -0,0 +1,30 @@
{
"extends": "@microsoft/sp-tslint-rules/base-tslint.json",
"rules": {
"class-name": false,
"export-name": false,
"forin": false,
"label-position": false,
"member-access": true,
"no-arg": false,
"no-console": false,
"no-construct": false,
"no-duplicate-variable": true,
"no-eval": false,
"no-function-expression": true,
"no-internal-module": true,
"no-shadowed-variable": true,
"no-switch-case-fall-through": true,
"no-unnecessary-semicolons": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-with-statement": true,
"semicolon": true,
"trailing-comma": false,
"typedef": false,
"typedef-whitespace": false,
"use-named-parameter": true,
"variable-name": false,
"whitespace": false
}
}