Merge branch 'AW-6-changeCameraSize-cameraButton' into 'develop'
AW-6-changeCameraSize-cameraButton See merge request witapp/aura-webapp!98
This commit is contained in:
commit
79ebe25a18
@ -1,28 +1,39 @@
|
|||||||
import './modal.css';
|
import "./modal.css";
|
||||||
|
|
||||||
export enum ModalType {
|
export enum ModalType {
|
||||||
Error = 'error',
|
Error = "error",
|
||||||
}
|
}
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
type?: ModalType;
|
type?: ModalType;
|
||||||
noCloseButton?: boolean;
|
noCloseButton?: boolean;
|
||||||
|
modalClassName?: string;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function Modal(props: Props) {
|
export default function Modal(props: Props) {
|
||||||
const className = ['modal'];
|
const className = ["modal"];
|
||||||
|
|
||||||
|
if (props.modalClassName?.length) {
|
||||||
|
className.push(props.modalClassName);
|
||||||
|
}
|
||||||
|
|
||||||
if (props.type === ModalType.Error) {
|
if (props.type === ModalType.Error) {
|
||||||
className.push('modal_type_error');
|
className.push("modal_type_error");
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className.join(' ')}>
|
<div className={className.join(" ")}>
|
||||||
{!props.noCloseButton && (
|
{!props.noCloseButton && (
|
||||||
<div className="modal__close-button" onClick={props.onClose}>
|
<div className="modal__close-button" onClick={props.onClose}>
|
||||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg
|
||||||
|
width="14"
|
||||||
|
height="14"
|
||||||
|
viewBox="0 0 14 14"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
fillRule="evenodd"
|
fillRule="evenodd"
|
||||||
clipRule="evenodd"
|
clipRule="evenodd"
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
min-height: 100dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.palm-camera-modal__hand-icon {
|
.palm-camera-modal__hand-icon {
|
||||||
@ -21,9 +22,27 @@
|
|||||||
bottom: 30px;
|
bottom: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
outline: 20px solid hsla(0,0%,100%,.28);
|
outline: 20px solid hsla(0, 0%, 100%, 0.28);
|
||||||
position: absolute;
|
position: absolute;
|
||||||
-webkit-transform: translateX(-50%);
|
-webkit-transform: translateX(-50%);
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
width: 30px;
|
width: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.palm-camera-modal__camera-video {
|
||||||
|
min-height: 100dvh;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palm-camera-modal {
|
||||||
|
top: 0;
|
||||||
|
transform: translate(-50%, 0);
|
||||||
|
min-height: 100dvh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.palm-camera-modal__overlay {
|
||||||
|
height: fit-content;
|
||||||
|
min-height: 100dvh;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import React from 'react';
|
import React from "react";
|
||||||
|
|
||||||
import './palm-camera-modal.css';
|
import "./palm-camera-modal.css";
|
||||||
|
|
||||||
import ModalOverlay, { ModalOverlayType } from '../modal-overlay/modal-overlay';
|
import ModalOverlay, { ModalOverlayType } from "../modal-overlay/modal-overlay";
|
||||||
import Modal from '../modal/modal';
|
import Modal from "../modal/modal";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@ -13,7 +13,9 @@ type Props = {
|
|||||||
export default function PalmCameraModal(props: Props) {
|
export default function PalmCameraModal(props: Props) {
|
||||||
const videoEl = React.useRef<HTMLVideoElement | null>(null);
|
const videoEl = React.useRef<HTMLVideoElement | null>(null);
|
||||||
|
|
||||||
const [mediaStream, setMediaStream] = React.useState<MediaStream | null>(null);
|
const [mediaStream, setMediaStream] = React.useState<MediaStream | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
const onClickOverlay = (e: React.MouseEvent) => {
|
const onClickOverlay = (e: React.MouseEvent) => {
|
||||||
if (e.target === e.currentTarget) {
|
if (e.target === e.currentTarget) {
|
||||||
@ -26,20 +28,20 @@ export default function PalmCameraModal(props: Props) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
video: { facingMode: { ideal: 'environment' } },
|
video: { facingMode: { ideal: "environment" } },
|
||||||
})
|
});
|
||||||
|
|
||||||
setMediaStream(stream);
|
setMediaStream(stream);
|
||||||
|
|
||||||
videoEl.current.srcObject = stream;
|
videoEl.current.srcObject = stream;
|
||||||
videoEl.current.addEventListener('loadedmetadata', videoEl.current.play);
|
videoEl.current.addEventListener("loadedmetadata", videoEl.current.play);
|
||||||
} catch(error) {
|
} catch (error) {
|
||||||
console.error('Camera is not available', error);
|
console.error("Camera is not available", error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const deactivateCamera = React.useCallback(() => {
|
const deactivateCamera = React.useCallback(() => {
|
||||||
mediaStream?.getTracks().forEach(track => track.stop());
|
mediaStream?.getTracks().forEach((track) => track.stop());
|
||||||
}, [mediaStream]);
|
}, [mediaStream]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -49,9 +51,9 @@ export default function PalmCameraModal(props: Props) {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const takePhoto = () => {
|
const takePhoto = () => {
|
||||||
const canvas = document.createElement('canvas');
|
const canvas = document.createElement("canvas");
|
||||||
|
|
||||||
const context = canvas.getContext('2d');
|
const context = canvas.getContext("2d");
|
||||||
|
|
||||||
if (!context || !videoEl.current) return null;
|
if (!context || !videoEl.current) return null;
|
||||||
|
|
||||||
@ -62,7 +64,7 @@ export default function PalmCameraModal(props: Props) {
|
|||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
context.drawImage(videoEl.current, 0, 0, width, height);
|
context.drawImage(videoEl.current, 0, 0, width, height);
|
||||||
|
|
||||||
const data = canvas.toDataURL('image/png');
|
const data = canvas.toDataURL("image/png");
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
@ -78,9 +80,15 @@ export default function PalmCameraModal(props: Props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalOverlay type={ModalOverlayType.Dark} className="palm-camera-modal" onClick={onClickOverlay}>
|
<ModalOverlay
|
||||||
<Modal onClose={props.onClose} noCloseButton>
|
type={ModalOverlayType.Dark}
|
||||||
<div className="palm-camera-modal__camera">
|
className="palm-camera-modal__overlay"
|
||||||
|
onClick={onClickOverlay}
|
||||||
|
>
|
||||||
|
<Modal onClose={props.onClose} noCloseButton modalClassName="palm-camera-modal">
|
||||||
|
<div
|
||||||
|
className="palm-camera-modal__camera"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
width="222"
|
width="222"
|
||||||
height="424"
|
height="424"
|
||||||
@ -127,9 +135,12 @@ export default function PalmCameraModal(props: Props) {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<video ref={videoEl} autoPlay playsInline muted/>
|
<video className="palm-camera-modal__camera-video" ref={videoEl} autoPlay playsInline muted />
|
||||||
|
|
||||||
<div className="palm-camera-modal__button-shutter" onClick={onClickTakePhoto}/>
|
<div
|
||||||
|
className="palm-camera-modal__button-shutter"
|
||||||
|
onClick={onClickTakePhoto}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
</ModalOverlay>
|
</ModalOverlay>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user