diff --git a/index.html b/index.html index 7a9067e..1db786e 100644 --- a/index.html +++ b/index.html @@ -5,8 +5,73 @@ CamCheckMate | Browser Webcam Testing Tool + + +
diff --git a/package.json b/package.json index f33467c..4d6e71f 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "CamCheckMate", "private": true, - "version": "0.0.0", + "version": "0.1.0", "type": "module", - "homepage": "https://hidaytrahman.github.io/camcheckmate/", + "homepage": "https://camcheckmate.vercel.app/", "author": { "name": "Hidayt Rahman", "email": "hidaytrahman@gmail.com", diff --git a/src/App.css b/src/App.css index eac3b86..b90b46b 100644 --- a/src/App.css +++ b/src/App.css @@ -97,3 +97,31 @@ i { /* video { transform: scaleX(-1); } */ + + +.filter-sections { + display: flex; + gap: 10px; + align-items: center; + justify-content: center; +} + +.filter-sections img { + width: 100px; + cursor: pointer; + background-color: bisque; + height: 81px; + position: relative; +} + +.filter-sections img::after { + content: ""; + position: absolute; + background-color: red; + z-index: 99; + top: 0; + height: 100%; + width: 100%; + left: 0; + right: 0; +} \ No newline at end of file diff --git a/src/components/common/Dropdown.tsx b/src/components/common/Dropdown.tsx index 2af5b8d..4cd7e68 100644 --- a/src/components/common/Dropdown.tsx +++ b/src/components/common/Dropdown.tsx @@ -11,11 +11,15 @@ function classNames(...classes) { type DropdownPropsTypes = { title: string; items: []; onChangeAction: (arg: any) => void; activeDevice: any }; export default function Dropdown({ title = 'Choose', items, onChangeAction, activeDevice }: DropdownPropsTypes) { + console.log({activeDevice}) return (
- {activeDevice ? activeDevice?.label : title} + {/* @ts-ignore */} + {activeDevice ? activeDevice?.label : items?.[0].label || title} + + {/* {items?.[0].label} */}
@@ -29,7 +33,7 @@ export default function Dropdown({ title = 'Choose', items, onChangeAction, acti leaveFrom='transform opacity-100 scale-100' leaveTo='transform opacity-0 scale-95' > - +
{items.map((device: any) => ( diff --git a/src/components/features/LiveView.tsx b/src/components/features/LiveView.tsx index ccd4850..4ce1fab 100644 --- a/src/components/features/LiveView.tsx +++ b/src/components/features/LiveView.tsx @@ -69,7 +69,9 @@ function LiveView({ cameraMode, setCameraMode, setImgSrc }: LiveViewPropsTypes)
- + diff --git a/src/components/features/ResultView.tsx b/src/components/features/ResultView.tsx index 469f417..673c8b0 100644 --- a/src/components/features/ResultView.tsx +++ b/src/components/features/ResultView.tsx @@ -22,7 +22,7 @@ function ResultView({ cameraMode, imgSrc }: ResultViewPropsTypes) {

- {cameraMode ? 'Scanning from camera' : 'Connect with Camera'} + {cameraMode ? 'Camera is running' : 'Connect with Camera'}

{cameraMode diff --git a/src/components/features/WebCamera.tsx b/src/components/features/WebCamera.tsx index da0d360..54b95d0 100644 --- a/src/components/features/WebCamera.tsx +++ b/src/components/features/WebCamera.tsx @@ -1,22 +1,61 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import Dropdown from '../common/Dropdown'; import Webcam from 'react-webcam'; +import { FILTERS } from '../../utils/camera.utils'; type WebCameraPropsTypes = { cameraMode: boolean; setImgSrc: any; }; function WebCamera({ cameraMode, setImgSrc }: WebCameraPropsTypes) { - const webcamRef = useRef(null); + const webcamRef = useRef(null); const [deviceId, setDeviceId] = useState({}); const [devices, setDevices] = useState<[]>([]); const [activeDevice, setActiveDevice] = useState(null); + const [mirrored, setMirrored] = useState(false); + const [filter, setFilter] = useState("none"); + const [thumbnail, setThumbnail] = useState("none"); + const videoConstraints = { facingMode: 'user', deviceId: deviceId, }; + // Prefer camera resolution nearest to 1280x720. + // const constraints = { + // audio: true, + // video: { width: 1280, height: 720 }, + // }; + + // async function getMedia(constraints: any) { + // let stream = null; + + // try { + // stream = await navigator.mediaDevices.getUserMedia(constraints); + // /* use the stream */ + // } catch (err) { + // /* handle the error */ + // } + // } + + // navigator.mediaDevices + // .getUserMedia(constraints) + // .then((mediaStream) => { + // const video: any = document.querySelector("video"); + // video.srcObject = mediaStream; + // video.onloadedmetadata = () => { + // video.play(); + // }; + + + // }) + // .catch((err) => { + // // always check for errors at the end. + // console.error(`${err.name}: ${err.message}`); + // }); + + const onChangeAction = (device: any) => { setDeviceId(device.deviceId); setActiveDevice(device); @@ -24,10 +63,16 @@ function WebCamera({ cameraMode, setImgSrc }: WebCameraPropsTypes) { const capture = useCallback(() => { // @ts-ignore - const imageSrc = webcamRef.current.getScreenshot(); + const imageSrc = webcamRef.current?.getScreenshot(); setImgSrc(imageSrc); }, [webcamRef, setImgSrc]); + const captureThumbnail = useCallback(() => { + // @ts-ignore + const imageSrc = webcamRef.current?.getScreenshot(); + setThumbnail(imageSrc); + }, [webcamRef, setImgSrc]); + const handleDevices = useCallback( // @ts-ignore (mediaDevices) => @@ -38,10 +83,12 @@ function WebCamera({ cameraMode, setImgSrc }: WebCameraPropsTypes) { [setDevices] ); + useEffect(() => { navigator.mediaDevices.enumerateDevices().then(handleDevices); }, [handleDevices]); + return (

{cameraMode ? ( @@ -61,10 +108,40 @@ function WebCamera({ cameraMode, setImgSrc }: WebCameraPropsTypes) { audio={false} ref={webcamRef} videoConstraints={videoConstraints} + style={{ + // transform: mirrored ? "scaleX(-1)" : "none" + filter: filter + }} + mirrored={mirrored} /> + +
+
Apply Filters
+ + { + FILTERS.map((_filter, index) => + setFilter(_filter)} + alt={_filter} + title={_filter} + style={{ + filter: _filter + }} + /> + ) + } +
- + + {" "} ) : (

Switch on the camera

diff --git a/src/utils/camera.utils.ts b/src/utils/camera.utils.ts new file mode 100644 index 0000000..5ddcc4f --- /dev/null +++ b/src/utils/camera.utils.ts @@ -0,0 +1 @@ +export const FILTERS = ["grayscale(1)", "invert(1)", "sepia(1)", "brightness(5)"]; \ No newline at end of file diff --git a/src/views/Camera.tsx b/src/views/Camera.tsx index 8220b3c..2a94379 100644 --- a/src/views/Camera.tsx +++ b/src/views/Camera.tsx @@ -26,7 +26,10 @@ export default function Camera() {
{loading && } - + +
diff --git a/tailwind.config.js b/tailwind.config.js index e68506d..3e246f8 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -4,5 +4,6 @@ export default { theme: { extend: {}, }, + darkMode: 'class', plugins: [require('@tailwindcss/forms')], };