aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/webcam/DashWebCam.tsx115
1 files changed, 80 insertions, 35 deletions
diff --git a/src/client/views/webcam/DashWebCam.tsx b/src/client/views/webcam/DashWebCam.tsx
index 3659bbc6e..ce33114eb 100644
--- a/src/client/views/webcam/DashWebCam.tsx
+++ b/src/client/views/webcam/DashWebCam.tsx
@@ -2,6 +2,8 @@ import React = require("react");
import { observer } from "mobx-react";
import { FieldViewProps, FieldView } from "../nodes/FieldView";
import { observable } from "mobx";
+import { DocumentDecorations } from "../DocumentDecorations";
+import { InkingControl } from "../InkingControl";
@@ -23,8 +25,13 @@ interface WebcamProps {
videoConstraints?: MediaStreamConstraints["video"];
}
+interface OuterWebcamProps {
+ local: FieldViewProps;
+ external: WebcamProps & React.HtmlHTMLAttributes<HTMLVideoElement>;
+}
+
@observer
-export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & React.HTMLAttributes<HTMLVideoElement>> {
+export class DashWebCam extends React.Component<OuterWebcamProps> {
static defaultProps = {
audio: true,
imageSmoothing: true,
@@ -63,13 +70,14 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
}
}
- componentDidUpdate(nextProps: WebcamProps) {
- const { props } = this;
+ componentDidUpdate(nextProps: OuterWebcamProps) {
+ const { external } = this.props;
+ const nextExternal = nextProps.external;
if (
- JSON.stringify(nextProps.audioConstraints) !==
- JSON.stringify(props.audioConstraints) ||
- JSON.stringify(nextProps.videoConstraints) !==
- JSON.stringify(props.videoConstraints)
+ JSON.stringify(nextExternal.audioConstraints) !==
+ JSON.stringify(external.audioConstraints) ||
+ JSON.stringify(nextExternal.videoConstraints) !==
+ JSON.stringify(external.videoConstraints)
) {
this.requestUserMedia();
}
@@ -96,19 +104,19 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
}
getScreenshot() {
- const { props } = this;
+ const { external } = this.props;
if (!this.hasUserMedia) return null;
const canvas = this.getCanvas();
return (
canvas &&
- canvas.toDataURL(props.screenshotFormat, props.screenshotQuality)
+ canvas.toDataURL(external.screenshotFormat, external.screenshotQuality)
);
}
getCanvas() {
- const { props } = this;
+ const { external } = this.props;
if (!this.video) {
return null;
@@ -120,14 +128,14 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
const canvas = document.createElement("canvas");
const aspectRatio = this.video.videoWidth / this.video.videoHeight;
- let canvasWidth = props.minScreenshotWidth || this.video.clientWidth;
+ let canvasWidth = external.minScreenshotWidth || this.video.clientWidth;
let canvasHeight = canvasWidth / aspectRatio;
if (
- props.minScreenshotHeight &&
- canvasHeight < props.minScreenshotHeight
+ external.minScreenshotHeight &&
+ canvasHeight < external.minScreenshotHeight
) {
- canvasHeight = props.minScreenshotHeight;
+ canvasHeight = external.minScreenshotHeight;
canvasWidth = canvasHeight * aspectRatio;
}
@@ -141,7 +149,7 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
const { ctx, canvas } = this;
if (ctx) {
- ctx.imageSmoothingEnabled = props.imageSmoothing;
+ ctx.imageSmoothingEnabled = external.imageSmoothing;
ctx.drawImage(this.video, 0, 0, canvas!.width, canvas!.height);
}
@@ -149,7 +157,7 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
}
requestUserMedia() {
- const { props } = this;
+ const { external } = this.props;
navigator.getUserMedia =
navigator.mediaDevices.getUserMedia;
@@ -159,7 +167,7 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
video: typeof videoConstraints !== "undefined" ? videoConstraints : true
};
- if (props.audio) {
+ if (external.audio) {
constraints.audio =
typeof audioConstraints !== "undefined" ? audioConstraints : true;
}
@@ -179,7 +187,7 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
};
if ("mediaDevices" in navigator) {
- sourceSelected(props.audioConstraints, props.videoConstraints);
+ sourceSelected(external.audioConstraints, external.videoConstraints);
} else {
const optionalSource = (id: any) => ({ optional: [{ sourceId: id }] });
@@ -214,12 +222,12 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
}
});
- const audioSourceId = constraintToSourceId(props.audioConstraints);
+ const audioSourceId = constraintToSourceId(external.audioConstraints);
if (audioSourceId) {
audioSource = audioSourceId;
}
- const videoSourceId = constraintToSourceId(props.videoConstraints);
+ const videoSourceId = constraintToSourceId(external.videoConstraints);
if (videoSourceId) {
videoSource = videoSourceId;
}
@@ -235,11 +243,11 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
}
handleUserMedia(err: string | null, stream?: MediaStream) {
- const { props } = this;
+ const { external } = this.props;
if (err || !stream) {
this.setState({ hasUserMedia: false });
- props.onUserMediaError(err!);
+ external.onUserMediaError(err!);
return;
}
@@ -258,9 +266,26 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
});
}
- props.onUserMedia();
+ external.onUserMedia();
}
+ _ignore = 0;
+ onPreWheel = (e: React.WheelEvent) => {
+ this._ignore = e.timeStamp;
+ }
+ onPrePointer = (e: React.PointerEvent) => {
+ this._ignore = e.timeStamp;
+ }
+ onPostPointer = (e: React.PointerEvent) => {
+ if (this._ignore !== e.timeStamp) {
+ e.stopPropagation();
+ }
+ }
+ onPostWheel = (e: React.WheelEvent) => {
+ if (this._ignore !== e.timeStamp) {
+ e.stopPropagation();
+ }
+ }
@@ -271,6 +296,9 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
render() {
const { props } = this;
+ const { external, local } = this.props;
+
+
const {
audio,
onUserMedia,
@@ -283,20 +311,37 @@ export class DashWebCam extends React.Component<FieldViewProps & WebcamProps & R
videoConstraints,
imageSmoothing,
...rest
- } = props;
+ } = external;
+
+
+
+ let content =
+ <div className="webcam-cont" style={{ width: "100%", height: "100%", position: "absolute" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+ <video
+ autoPlay
+ src={this.src}
+ muted={audio}
+ playsInline
+ ref={ref => {
+ this.video = ref;
+ }}
+ {...rest}
+
+ />
+ </div>;
+
+
+ let frozen = !local.isSelected() || DocumentDecorations.Instance.Interacting;
+ let classname = "webBox-cont" + (local.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
return (
- <video
- autoPlay
- src={this.src}
- muted={audio}
- playsInline
- ref={ref => {
- this.video = ref;
- }}
- {...rest}
- />
- );
+ <>
+ <div className={classname} >
+ {content}
+ </div>
+ {!frozen ? (null) : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
+ </>);
+
}
} \ No newline at end of file