diff --git a/public/index.html b/public/index.html index 495c6cc..78cfedb 100644 --- a/public/index.html +++ b/public/index.html @@ -27,7 +27,9 @@
- Trash Recognizer logo +
+ Trash Recognizer logo +
diff --git a/src/assets/loadingCircle.png b/src/assets/loadingCircle.png new file mode 100644 index 0000000..e50c2db Binary files /dev/null and b/src/assets/loadingCircle.png differ diff --git a/src/components/About/index.module.scss b/src/components/About/index.module.scss new file mode 100644 index 0000000..51e2ba4 --- /dev/null +++ b/src/components/About/index.module.scss @@ -0,0 +1,5 @@ +@media screen and (max-width: 768px) { + .container { + flex-direction: column !important; + } +} diff --git a/src/components/About/index.tsx b/src/components/About/index.tsx new file mode 100644 index 0000000..5cc8cfa --- /dev/null +++ b/src/components/About/index.tsx @@ -0,0 +1,20 @@ +import { FC } from "react"; +import { Box } from "../Box"; +import { CreditTile } from "../CreditTile"; +import style from "./index.module.scss"; + +export const About: FC<{ cfn: (d: any) => void }> = (props) => { + return ( + +

Trash helper

+ + + + + + +
+ ); +}; diff --git a/src/AlertDialog/index.module.scss b/src/components/AlertDialog/index.module.scss similarity index 76% rename from src/AlertDialog/index.module.scss rename to src/components/AlertDialog/index.module.scss index 52c3aba..34888fa 100644 --- a/src/AlertDialog/index.module.scss +++ b/src/components/AlertDialog/index.module.scss @@ -1,4 +1,4 @@ -@import "../index.scss"; +@import "../../index.scss"; .container { width: 100%; @@ -18,4 +18,6 @@ padding: 10px; clip-path: inset(0 0 0 0); position: relative; + border: 1.5px solid lighten($background, 10%); + box-shadow: 0 0 0.5px black; } diff --git a/src/AlertDialog/index.tsx b/src/components/AlertDialog/index.tsx similarity index 100% rename from src/AlertDialog/index.tsx rename to src/components/AlertDialog/index.tsx diff --git a/src/AlertDialog/spawnDialog.tsx b/src/components/AlertDialog/spawnDialog.tsx similarity index 98% rename from src/AlertDialog/spawnDialog.tsx rename to src/components/AlertDialog/spawnDialog.tsx index 9dc31f1..0aa1036 100644 --- a/src/AlertDialog/spawnDialog.tsx +++ b/src/components/AlertDialog/spawnDialog.tsx @@ -5,7 +5,7 @@ import { AlertDialog } from "./index"; export const spawnDialog = async (elements: (close: (data: any) => void) => ReactNode, windowStyles?: CSSProperties) => { const container = document.createElement("div"); const backgroundColor = "rgba(0,0,0,0.75)"; - const animationDuration = 300; + const animationDuration = 250; (container.style as any) = "display: block; overflow: hidden; width: 100vw; height: 100vh; z-index: 20; position: fixed; top: 0; left: 0"; diff --git a/src/components/CreditTile/index.module.scss b/src/components/CreditTile/index.module.scss new file mode 100644 index 0000000..df78cbe --- /dev/null +++ b/src/components/CreditTile/index.module.scss @@ -0,0 +1,45 @@ +@import "../../index.scss"; + +.container { + text-decoration: none; + animation: in-anim 0.3s ease-out both; + transform: translateY(15px); + opacity: 0; + transition: all 0.3s ease; + background-color: transparent; + border-radius: 15px; + padding: 10px; + border: solid 1px transparent; + display: block; + &:hover { + background-color: rgba(200, 200, 200, 0.2); + border: solid 1px lighten(rgba(200, 200, 200, 0.2), 10%); + } +} + +.img { + border-radius: 50%; + padding: 10px; + transition: transform 0.2s ease-out; + width: 10vh; + height: 10vh; + .container:hover & { + transform: scale(1.1); + } +} + +.title { + font-size: 20px; + color: $text; +} + +@keyframes in-anim { + from { + transform: translateY(15px); + opacity: 0; + } + to { + transform: translateY(0); + opacity: 1; + } +} diff --git a/src/components/CreditTile/index.tsx b/src/components/CreditTile/index.tsx new file mode 100644 index 0000000..57fce74 --- /dev/null +++ b/src/components/CreditTile/index.tsx @@ -0,0 +1,20 @@ +import { FC } from "react"; +import { Box } from "../Box"; +import style from "./index.module.scss"; + +export const CreditTile: FC<{ title: string; imageUrl?: string; gh?: string; delay?: number }> = (props) => { + return ( + + + {props.title} +
{props.title}
+
+
+ ); +}; diff --git a/src/components/Overlay/index.tsx b/src/components/Overlay/index.tsx index 42a7e50..4bbeb75 100644 --- a/src/components/Overlay/index.tsx +++ b/src/components/Overlay/index.tsx @@ -1,39 +1,29 @@ import { FC, useContext } from "react"; -import { spawnDialog } from "../../AlertDialog/spawnDialog"; +import { spawnDialog } from "../AlertDialog/spawnDialog"; import { modelCtx } from "../../constants"; -import { getVideoFrame } from "../../utils/getVideoFrame"; +import { About } from "../About"; import { Icon } from "../Icon"; +import { Results } from "../Results"; import style from "./index.module.scss"; export const Overlay: FC = () => { const model = useContext(modelCtx); - return (
- - + + + + ); }); }} diff --git a/src/components/Results/index.module.scss b/src/components/Results/index.module.scss new file mode 100644 index 0000000..0eea74f --- /dev/null +++ b/src/components/Results/index.module.scss @@ -0,0 +1,15 @@ +.loadingLbl { + text-align: center; +} +.loadingCircle { + animation: spin 1s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/src/components/Results/index.tsx b/src/components/Results/index.tsx new file mode 100644 index 0000000..d8a53cc --- /dev/null +++ b/src/components/Results/index.tsx @@ -0,0 +1,32 @@ +import { FC, useContext, useEffect, useState } from "react"; +import { modelCtx } from "../../constants"; +import { getVideoFrame } from "../../utils/getVideoFrame"; +import style from "./index.module.scss"; +import loadingCircle from "../../assets/loadingCircle.png"; +import { Box } from "../Box"; + +export const Results: FC<{}> = (_) => { + const [el, uel] = useState( + + +

Trwa analizowanie zdjęcia...

+
+ ); + const model = useContext(modelCtx); + + useEffect(() => { + const can = getVideoFrame(document.querySelector("#video-feed") as HTMLVideoElement); + model?.classify(can).then((r) => { + console.log(r); + uel( + <> + {r?.[0].className} +

{r?.[0].className}

+

{r?.[0].probability}

+ + ); + }); + }, [model]); + + return el; +}; diff --git a/src/index.scss b/src/index.scss index bff67a6..da375fc 100644 --- a/src/index.scss +++ b/src/index.scss @@ -40,6 +40,29 @@ button { &:hover { background-color: $text; color: black; - border-color: darken($text, 10%); + border-color: darken($text, 30%); } } + +.btn-inverse { + border: none; + padding: 10px; + box-shadow: none; + border-radius: $borderRadius; + background-color: $text; + color: black; + transition: all $transitionDuration ease; + border: 1.5px solid darken($text, 30%); + box-shadow: 0 0 0.5px black; + cursor: pointer; + &:hover { + background-color: $background; + color: $text; + border-color: lighten($background, 10%); + } +} + +::selection { + background-color: darken($text, 20%); + color: black; +} diff --git a/src/index.tsx b/src/index.tsx index 2ddbef4..91a44e0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,7 +7,14 @@ import { modelCtx, videoStreamCtx } from "./constants"; import { load as loadModel } from "@tensorflow-models/mobilenet"; const main = async () => { - console.log("Requesting camera access..."); + const appContainer = document.querySelector("#app"); + const infoLabel = document.createElement("p"); + infoLabel.style.color = "white"; + infoLabel.style.fontSize = "25px"; + infoLabel.style.fontFamily = "Arial, sans-serif"; + infoLabel.style.fontWeight = "100"; + infoLabel.innerHTML = "Oczekiwanie na uprawnienia dostępu do kamery..."; + appContainer?.children[0].appendChild(infoLabel); const videoStream = (await window.navigator.mediaDevices?.getUserMedia({ video: { facingMode: "environment" } }).catch((e) => { if (e instanceof DOMException) { @@ -15,7 +22,7 @@ const main = async () => { } return null; })) ?? null; - console.log("Loading AI model..."); + infoLabel.innerHTML = "Wczytywanie aplikacji..."; const model = await loadModel(); ReactDOM.render( @@ -25,7 +32,7 @@ const main = async () => { , - document.querySelector("#app") + appContainer ); };