- added Konvas lib
- added feed from proof of concept
This commit is contained in:
11
src/features/cameras/components/CameraGrid.tsx
Normal file
11
src/features/cameras/components/CameraGrid.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import VideoFeedCard from "./VideoFeedCard";
|
||||
|
||||
const CameraGrid = () => {
|
||||
return (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2">
|
||||
<VideoFeedCard />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CameraGrid;
|
||||
13
src/features/cameras/components/VideoFeedCard.tsx
Normal file
13
src/features/cameras/components/VideoFeedCard.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import Card from "../../../ui/Card";
|
||||
|
||||
import VideoFeedGridPainter from "./VideoFeedGridPainter";
|
||||
|
||||
const VideoFeedCard = () => {
|
||||
return (
|
||||
<Card className="w-full md:w-[70%]">
|
||||
<VideoFeedGridPainter />
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoFeedCard;
|
||||
75
src/features/cameras/components/VideoFeedGridPainter.tsx
Normal file
75
src/features/cameras/components/VideoFeedGridPainter.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
import { useRef, type RefObject } from "react";
|
||||
import { Stage, Layer, Image, Rect } from "react-konva";
|
||||
import { useCreateVideoSnapshot } from "../hooks/useGetvideoSnapshots";
|
||||
|
||||
const VideoFeedGridPainter = () => {
|
||||
const { latestBitmapRef } = useCreateVideoSnapshot();
|
||||
const isDrawing = useRef(false);
|
||||
|
||||
const rows = 100;
|
||||
const cols = 100;
|
||||
const size = 10;
|
||||
const gap = 0;
|
||||
|
||||
const squares = [];
|
||||
for (let row = 0; row < rows; row++) {
|
||||
for (let col = 0; col < cols; col++) {
|
||||
squares.push(
|
||||
<Rect
|
||||
key={`${row}-${col}`}
|
||||
x={col * (size + gap)}
|
||||
y={row * (size + gap)}
|
||||
width={size}
|
||||
height={size}
|
||||
fill="#ddd"
|
||||
stroke="black"
|
||||
strokeWidth={0.5}
|
||||
opacity={0.5}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const getCoords = (e) => {
|
||||
isDrawing.current = true;
|
||||
};
|
||||
|
||||
const handleMouseMove = (e) => {
|
||||
if (!isDrawing.current) {
|
||||
return;
|
||||
}
|
||||
const pos = e.target.getStage().getPointerPosition();
|
||||
console.log(pos);
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDrawing.current = false;
|
||||
};
|
||||
|
||||
const draw = (bmp: RefObject<ImageBitmap | null>) => {
|
||||
if (!bmp || !bmp.current) {
|
||||
return;
|
||||
} else {
|
||||
const frame = bmp.current;
|
||||
return frame;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Stage
|
||||
width={640}
|
||||
height={360}
|
||||
onMouseDown={getCoords}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={handleMouseUp}
|
||||
>
|
||||
<Layer>
|
||||
<Image image={draw(latestBitmapRef)} width={640} height={360} />
|
||||
</Layer>
|
||||
<Layer opacity={0.3}>{squares}</Layer>
|
||||
</Stage>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoFeedGridPainter;
|
||||
22
src/features/cameras/hooks/useGetVideoFeed.ts
Normal file
22
src/features/cameras/hooks/useGetVideoFeed.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
const getfeed = async () => {
|
||||
const response = await fetch(`http://100.115.148.59/TargetDetectionColour-preview`, {
|
||||
signal: AbortSignal.timeout(300000),
|
||||
cache: "no-store",
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(`Cannot reach endpoint (${response.status})`);
|
||||
}
|
||||
return response.blob();
|
||||
};
|
||||
|
||||
export const useGetVideoFeed = () => {
|
||||
const videoQuery = useQuery({
|
||||
queryKey: ["getfeed"],
|
||||
queryFn: getfeed,
|
||||
refetchInterval: 500,
|
||||
});
|
||||
|
||||
return { videoQuery };
|
||||
};
|
||||
25
src/features/cameras/hooks/useGetvideoSnapshots.ts
Normal file
25
src/features/cameras/hooks/useGetvideoSnapshots.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useGetVideoFeed } from "./useGetVideoFeed";
|
||||
|
||||
export const useCreateVideoSnapshot = () => {
|
||||
const latestBitmapRef = useRef<ImageBitmap | null>(null);
|
||||
const { videoQuery } = useGetVideoFeed();
|
||||
|
||||
const snapShot = videoQuery?.data;
|
||||
|
||||
useEffect(() => {
|
||||
async function createBitmap() {
|
||||
if (!snapShot) return;
|
||||
|
||||
try {
|
||||
const bitmap = await createImageBitmap(snapShot);
|
||||
latestBitmapRef.current = bitmap;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
createBitmap();
|
||||
}, [snapShot]);
|
||||
|
||||
return { latestBitmapRef };
|
||||
};
|
||||
Reference in New Issue
Block a user