mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 05:35:25 +03:00
clean up
This commit is contained in:
parent
bbca5ffdfa
commit
0863d43e04
@ -5,7 +5,6 @@ import Konva from "konva";
|
||||
import type { KonvaEventObject } from "konva/lib/Node";
|
||||
import { Polygon } from "@/types/canvas";
|
||||
import { useApiHost } from "@/api";
|
||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||
|
||||
type PolygonCanvasProps = {
|
||||
camera: string;
|
||||
@ -14,7 +13,6 @@ type PolygonCanvasProps = {
|
||||
polygons: Polygon[];
|
||||
setPolygons: React.Dispatch<React.SetStateAction<Polygon[]>>;
|
||||
activePolygonIndex: number | null;
|
||||
setActivePolygonIndex: React.Dispatch<React.SetStateAction<number | null>>;
|
||||
};
|
||||
|
||||
export function PolygonCanvas({
|
||||
@ -24,77 +22,35 @@ export function PolygonCanvas({
|
||||
polygons,
|
||||
setPolygons,
|
||||
activePolygonIndex,
|
||||
setActivePolygonIndex,
|
||||
}: PolygonCanvasProps) {
|
||||
const [image, setImage] = useState<HTMLImageElement | undefined>();
|
||||
const imageRef = useRef<Konva.Image | null>(null);
|
||||
// const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const stageRef = useRef<Konva.Stage>(null);
|
||||
// const [points, setPoints] = useState<number[][]>([]);
|
||||
// const [activePolygonIndex, setActivePolygonIndex] = useState<number | null>(
|
||||
// null,
|
||||
// );
|
||||
// const [size, setSize] = useState<{ width: number; height: number }>({
|
||||
// width: width,
|
||||
// height: height,
|
||||
// });
|
||||
const apiHost = useApiHost();
|
||||
// const [position, setPosition] = useState([0, 0]);
|
||||
// const [{ width: windowWidth }] = useResizeObserver(window);
|
||||
|
||||
const videoElement = useMemo(() => {
|
||||
if (camera && width && height) {
|
||||
// console.log("width:", containerRef.current.clientWidth);
|
||||
// console.log("width:", containerRef.current.clientHeight);
|
||||
const element = new window.Image();
|
||||
element.width = width; //containerRef.current.clientWidth;
|
||||
element.height = height; //containerRef.current.clientHeight;
|
||||
element.width = width;
|
||||
element.height = height;
|
||||
element.src = `${apiHost}api/${camera}/latest.jpg`;
|
||||
// setSize({
|
||||
// width: width,
|
||||
// height: height,
|
||||
// });
|
||||
return element;
|
||||
}
|
||||
}, [camera, width, height, apiHost]);
|
||||
|
||||
// const imageScale = scaledWidth / 720;
|
||||
// console.log("window width", windowWidth);
|
||||
|
||||
useEffect(() => {
|
||||
if (!videoElement) {
|
||||
return;
|
||||
}
|
||||
const onload = function () {
|
||||
setImage(videoElement);
|
||||
// if (!imageRef.current) imageRef.current = videoElement;
|
||||
console.log(videoElement, Date.now());
|
||||
};
|
||||
videoElement.addEventListener("load", onload);
|
||||
return () => {
|
||||
console.log("unloading");
|
||||
videoElement.removeEventListener("load", onload);
|
||||
};
|
||||
}, [videoElement]);
|
||||
|
||||
// use Konva.Animation to redraw a layer
|
||||
// useEffect(() => {
|
||||
// //videoElement.play();
|
||||
// if (!videoElement && !imageRef && !imageRef.current) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// const layer = imageRef.current?.getLayer();
|
||||
// console.log("layer", layer);
|
||||
|
||||
// const anim = new Konva.Animation(() => {}, layer);
|
||||
// anim.start();
|
||||
|
||||
// return () => {
|
||||
// anim.stop();
|
||||
// };
|
||||
// }, [videoElement]);
|
||||
|
||||
const getMousePos = (stage: Konva.Stage) => {
|
||||
return [stage.getPointerPosition()!.x, stage.getPointerPosition()!.y];
|
||||
};
|
||||
@ -104,7 +60,6 @@ export function PolygonCanvas({
|
||||
return false;
|
||||
}
|
||||
const [firstPoint] = polygon.points;
|
||||
console.log("first", firstPoint);
|
||||
const distance = Math.hypot(
|
||||
mousePos[0] - firstPoint[0],
|
||||
mousePos[1] - firstPoint[1],
|
||||
@ -116,23 +71,7 @@ export function PolygonCanvas({
|
||||
if (!activePolygonIndex || !polygons) {
|
||||
return;
|
||||
}
|
||||
console.log("mouse down polygons", polygons);
|
||||
console.log(activePolygonIndex);
|
||||
|
||||
// if (!polygons[activePolygonIndex].points.length) {
|
||||
// // Start a new polygon
|
||||
// const stage = e.target.getStage()!;
|
||||
// const mousePos = getMousePos(stage);
|
||||
// setPolygons([
|
||||
// ...polygons,
|
||||
// {
|
||||
// name: "foo",
|
||||
// points: [mousePos],
|
||||
// isFinished: false,
|
||||
// },
|
||||
// ]);
|
||||
// setActivePolygonIndex(polygons.length);
|
||||
// } else {
|
||||
const updatedPolygons = [...polygons];
|
||||
const activePolygon = updatedPolygons[activePolygonIndex];
|
||||
const stage = e.target.getStage()!;
|
||||
@ -148,7 +87,6 @@ export function PolygonCanvas({
|
||||
isFinished: true,
|
||||
};
|
||||
setPolygons(updatedPolygons);
|
||||
// setActivePolygonIndex(null);
|
||||
} else {
|
||||
if (!activePolygon.isFinished) {
|
||||
// Add a new point to the active polygon
|
||||
@ -162,12 +100,6 @@ export function PolygonCanvas({
|
||||
// }
|
||||
};
|
||||
|
||||
const handleMouseMove = (e: KonvaEventObject<MouseEvent>) => {
|
||||
const stage = e.target.getStage()!;
|
||||
const mousePos = getMousePos(stage);
|
||||
// setPosition(mousePos);
|
||||
};
|
||||
|
||||
const handleMouseOverStartPoint = (e: KonvaEventObject<MouseEvent>) => {
|
||||
if (activePolygonIndex !== null && polygons) {
|
||||
const activePolygon = polygons[activePolygonIndex];
|
||||
@ -178,16 +110,13 @@ export function PolygonCanvas({
|
||||
};
|
||||
|
||||
const handleMouseOutStartPoint = (e: KonvaEventObject<MouseEvent>) => {
|
||||
// console.log("active index:", activePolygonIndex);
|
||||
e.currentTarget.scale({ x: 1, y: 1 });
|
||||
if (activePolygonIndex !== null && polygons) {
|
||||
const activePolygon = polygons[activePolygonIndex];
|
||||
// console.log(activePolygon);
|
||||
if (
|
||||
(!activePolygon.isFinished && activePolygon.points.length >= 3) ||
|
||||
activePolygon.isFinished
|
||||
) {
|
||||
// console.log(e.currentTarget);
|
||||
e.currentTarget.scale({ x: 1, y: 1 });
|
||||
}
|
||||
}
|
||||
@ -238,14 +167,12 @@ export function PolygonCanvas({
|
||||
setPolygons(updatedPolygons);
|
||||
}
|
||||
};
|
||||
// console.log("rendering canvas", Date.now());
|
||||
|
||||
return (
|
||||
<Stage
|
||||
ref={stageRef}
|
||||
width={width}
|
||||
height={height}
|
||||
// onMouseMove={handleMouseMove}
|
||||
onMouseDown={handleMouseDown}
|
||||
>
|
||||
<Layer>
|
||||
|
||||
@ -53,9 +53,6 @@ export function PolygonControls({
|
||||
name: "new",
|
||||
},
|
||||
]);
|
||||
console.log(polygons.length);
|
||||
console.log(polygons);
|
||||
console.log("active index", polygons.length);
|
||||
setActivePolygonIndex(polygons.length);
|
||||
};
|
||||
|
||||
|
||||
@ -19,12 +19,10 @@ import {
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import useSWR from "swr";
|
||||
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { PolygonCanvas } from "./PolygonCanvas";
|
||||
import { useApiHost } from "@/api";
|
||||
import { Polygon } from "@/types/canvas";
|
||||
import { interpolatePoints } from "@/utils/canvasUtil";
|
||||
import AutoUpdatingCameraImage from "../camera/AutoUpdatingCameraImage";
|
||||
import { isDesktop } from "react-device-detect";
|
||||
import PolygonControls from "./PolygonControls";
|
||||
import { Skeleton } from "../ui/skeleton";
|
||||
@ -50,10 +48,7 @@ export default function SettingsZones() {
|
||||
const [activePolygonIndex, setActivePolygonIndex] = useState<number | null>(
|
||||
null,
|
||||
);
|
||||
const imgRef = useRef<HTMLImageElement | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
const apiHost = useApiHost();
|
||||
// const videoSource = `${apiHost}api/ptzcam/latest.jpg`;
|
||||
|
||||
const cameras = useMemo(() => {
|
||||
if (!config) {
|
||||
@ -73,55 +68,28 @@ export default function SettingsZones() {
|
||||
}
|
||||
}, [config, selectedCamera]);
|
||||
|
||||
const cameraAspect = useMemo(() => {
|
||||
const grow = useMemo(() => {
|
||||
if (!cameraConfig) {
|
||||
return;
|
||||
}
|
||||
|
||||
const aspectRatio = cameraConfig.detect.width / cameraConfig.detect.height;
|
||||
console.log("aspect", aspectRatio);
|
||||
|
||||
if (!aspectRatio) {
|
||||
return "normal";
|
||||
} else if (aspectRatio > 2) {
|
||||
return "wide";
|
||||
} else if (aspectRatio < 16 / 9) {
|
||||
return "tall";
|
||||
} else {
|
||||
return "normal";
|
||||
}
|
||||
}, [cameraConfig]);
|
||||
|
||||
const grow = useMemo(() => {
|
||||
if (cameraAspect == "wide") {
|
||||
if (aspectRatio > 2) {
|
||||
return "aspect-wide";
|
||||
} else if (cameraAspect == "tall") {
|
||||
} else if (aspectRatio < 16 / 9) {
|
||||
if (isDesktop) {
|
||||
return "size-full aspect-tall";
|
||||
} else {
|
||||
return "size-full";
|
||||
}
|
||||
} else {
|
||||
return "aspect-video";
|
||||
return "size-full aspect-video";
|
||||
}
|
||||
}, [cameraAspect]);
|
||||
}, [cameraConfig]);
|
||||
|
||||
// const [{ width: containerWidth, height: containerHeight }] =
|
||||
// useResizeObserver(containerRef);
|
||||
const containerWidth = containerRef.current?.clientWidth;
|
||||
const containerHeight = containerRef.current?.clientHeight;
|
||||
|
||||
// Add scrollbar width (when visible) to the available observer width to eliminate screen juddering.
|
||||
// https://github.com/blakeblackshear/frigate/issues/1657
|
||||
let scrollBarWidth = 0;
|
||||
// if (window.innerWidth && document.body.offsetWidth) {
|
||||
// scrollBarWidth = window.innerWidth - document.body.offsetWidth;
|
||||
// }
|
||||
// const availableWidth = scrollBarWidth
|
||||
// ? containerWidth + scrollBarWidth
|
||||
// : containerWidth;
|
||||
|
||||
const availableWidth = containerWidth;
|
||||
const [{ width: containerWidth, height: containerHeight }] =
|
||||
useResizeObserver(containerRef);
|
||||
|
||||
const { width, height } = cameraConfig
|
||||
? cameraConfig.detect
|
||||
@ -129,12 +97,13 @@ export default function SettingsZones() {
|
||||
const aspectRatio = width / height;
|
||||
|
||||
const stretch = false;
|
||||
const fitAspect = 1;
|
||||
const fitAspect = 0.75;
|
||||
|
||||
const scaledHeight = useMemo(() => {
|
||||
const scaledHeight =
|
||||
aspectRatio < (fitAspect ?? 0)
|
||||
? Math.floor(containerHeight)
|
||||
: Math.floor(availableWidth / aspectRatio);
|
||||
: Math.floor(containerWidth / aspectRatio);
|
||||
const finalHeight = stretch ? scaledHeight : Math.min(scaledHeight, height);
|
||||
|
||||
if (finalHeight > 0) {
|
||||
@ -143,16 +112,17 @@ export default function SettingsZones() {
|
||||
|
||||
return 100;
|
||||
}, [
|
||||
availableWidth,
|
||||
aspectRatio,
|
||||
containerWidth,
|
||||
containerHeight,
|
||||
fitAspect,
|
||||
height,
|
||||
stretch,
|
||||
]);
|
||||
|
||||
const scaledWidth = useMemo(
|
||||
() => Math.ceil(scaledHeight * aspectRatio - scrollBarWidth),
|
||||
[scaledHeight, aspectRatio, scrollBarWidth],
|
||||
() => Math.ceil(scaledHeight * aspectRatio),
|
||||
[scaledHeight, aspectRatio],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@ -175,37 +145,10 @@ export default function SettingsZones() {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [cameraConfig, containerRef]);
|
||||
|
||||
// const image = useMemo(() => {
|
||||
// if (cameraConfig && containerRef && containerRef.current) {
|
||||
// console.log("width:", containerRef.current.clientWidth);
|
||||
// const element = new window.Image();
|
||||
// element.width = containerRef.current.clientWidth;
|
||||
// element.height = containerRef.current.clientHeight;
|
||||
// element.src = `${apiHost}api/${cameraConfig.name}/latest.jpg`;
|
||||
// return element;
|
||||
// }
|
||||
// }, [cameraConfig, apiHost, containerRef]);
|
||||
|
||||
// useEffect(() => {
|
||||
// if (image) {
|
||||
// imgRef.current = image;
|
||||
// }
|
||||
// }, [image]);
|
||||
|
||||
if (!cameraConfig && !selectedCamera) {
|
||||
return <ActivityIndicator />;
|
||||
}
|
||||
|
||||
// console.log("selected camera", selectedCamera);
|
||||
// console.log("threshold", motionThreshold);
|
||||
// console.log("contour area", motionContourArea);
|
||||
// console.log("zone polygons", zonePolygons);
|
||||
|
||||
// console.log("width:", containerRef.current.clientWidth);
|
||||
// const element = new window.Image();
|
||||
// element.width = containerRef.current.clientWidth;
|
||||
// element.height = containerRef.current.clientHeight;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Heading as="h2">Zones</Heading>
|
||||
@ -234,7 +177,7 @@ export default function SettingsZones() {
|
||||
{cameraConfig && (
|
||||
<div className="flex flex-row justify-evenly">
|
||||
<div
|
||||
className={`flex flex-col justify-center items-center w-[50%] ${grow}`}
|
||||
className={`flex flex-col justify-center items-center w-[60%] ${grow}`}
|
||||
>
|
||||
<div ref={containerRef} className="size-full">
|
||||
{cameraConfig ? (
|
||||
@ -245,7 +188,6 @@ export default function SettingsZones() {
|
||||
polygons={zonePolygons}
|
||||
setPolygons={setZonePolygons}
|
||||
activePolygonIndex={activePolygonIndex}
|
||||
setActivePolygonIndex={setActivePolygonIndex}
|
||||
/>
|
||||
) : (
|
||||
<Skeleton className="w-full h-full" />
|
||||
@ -295,6 +237,11 @@ export default function SettingsZones() {
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<div>
|
||||
scaled width: {scaledWidth}, scaled height: {scaledHeight},
|
||||
container width: {containerWidth}, container height:
|
||||
{containerHeight}
|
||||
</div>
|
||||
<PolygonControls
|
||||
camera={cameraConfig.name}
|
||||
width={scaledWidth}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user