mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
undo points based on order added to polygon (#11035)
This commit is contained in:
parent
5f15641b1b
commit
d6dfa596de
@ -61,9 +61,20 @@ export function PolygonCanvas({
|
||||
|
||||
const addPointToPolygon = (polygon: Polygon, newPoint: number[]) => {
|
||||
const points = polygon.points;
|
||||
const pointsOrder = polygon.pointsOrder;
|
||||
|
||||
const [newPointX, newPointY] = newPoint;
|
||||
const updatedPoints = [...points];
|
||||
|
||||
let updatedPointsOrder: number[];
|
||||
if (!pointsOrder) {
|
||||
updatedPointsOrder = [];
|
||||
} else {
|
||||
updatedPointsOrder = [...pointsOrder];
|
||||
}
|
||||
|
||||
let insertIndex = points.length;
|
||||
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const [x1, y1] = points[i];
|
||||
const [x2, y2] = i === points.length - 1 ? points[0] : points[i + 1];
|
||||
@ -76,48 +87,16 @@ export function PolygonCanvas({
|
||||
(y1 <= newPointY && newPointY <= y2) ||
|
||||
(y2 <= newPointY && newPointY <= y1)
|
||||
) {
|
||||
const insertIndex = i + 1;
|
||||
updatedPoints.splice(insertIndex, 0, [newPointX, newPointY]);
|
||||
insertIndex = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return updatedPoints;
|
||||
};
|
||||
updatedPoints.splice(insertIndex, 0, [newPointX, newPointY]);
|
||||
updatedPointsOrder.splice(insertIndex, 0, updatedPoints.length);
|
||||
|
||||
const isPointNearLineSegment = (
|
||||
polygon: Polygon,
|
||||
mousePos: number[],
|
||||
radius = 10,
|
||||
) => {
|
||||
const points = polygon.points;
|
||||
const [x, y] = mousePos;
|
||||
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
const [x1, y1] = points[i];
|
||||
const [x2, y2] = i === points.length - 1 ? points[0] : points[i + 1];
|
||||
|
||||
const crossProduct = (x - x1) * (x2 - x1) + (y - y1) * (y2 - y1);
|
||||
if (crossProduct > 0) {
|
||||
const lengthSquared = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
|
||||
const dot = (x - x1) * (x2 - x1) + (y - y1) * (y2 - y1);
|
||||
if (dot < 0 || dot > lengthSquared) {
|
||||
continue;
|
||||
}
|
||||
const lineSegmentDistance = Math.abs(
|
||||
((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1) /
|
||||
Math.sqrt(Math.pow(y2 - y1, 2) + Math.pow(x2 - x1, 2)),
|
||||
);
|
||||
if (lineSegmentDistance <= radius) {
|
||||
const midPointX = (x1 + x2) / 2;
|
||||
const midPointY = (y1 + y2) / 2;
|
||||
return [midPointX, midPointY];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return { updatedPoints, updatedPointsOrder };
|
||||
};
|
||||
|
||||
const isMouseOverFirstPoint = (polygon: Polygon, mousePos: number[]) => {
|
||||
@ -176,18 +155,15 @@ export function PolygonCanvas({
|
||||
!activePolygon.isFinished &&
|
||||
!isMouseOverAnyPoint(activePolygon, mousePos)
|
||||
) {
|
||||
let updatedPoints;
|
||||
const { updatedPoints, updatedPointsOrder } = addPointToPolygon(
|
||||
activePolygon,
|
||||
mousePos,
|
||||
);
|
||||
|
||||
if (isPointNearLineSegment(activePolygon, mousePos)) {
|
||||
// we've clicked near a line segment, so add a new point in the right position
|
||||
updatedPoints = addPointToPolygon(activePolygon, mousePos);
|
||||
} else {
|
||||
// Add a new point to the active polygon
|
||||
updatedPoints = [...activePolygon.points, mousePos];
|
||||
}
|
||||
updatedPolygons[activePolygonIndex] = {
|
||||
...activePolygon,
|
||||
points: updatedPoints,
|
||||
pointsOrder: updatedPointsOrder,
|
||||
};
|
||||
setPolygons(updatedPolygons);
|
||||
}
|
||||
@ -318,6 +294,24 @@ export function PolygonCanvas({
|
||||
e.target.getStage()!.container().style.cursor = "crosshair";
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (activePolygonIndex === undefined || !polygons) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedPolygons = [...polygons];
|
||||
const activePolygon = updatedPolygons[activePolygonIndex];
|
||||
|
||||
// add default points order for already completed polygons
|
||||
if (!activePolygon.pointsOrder && activePolygon.isFinished) {
|
||||
updatedPolygons[activePolygonIndex] = {
|
||||
...activePolygon,
|
||||
pointsOrder: activePolygon.points.map((_, index) => index),
|
||||
};
|
||||
setPolygons(updatedPolygons);
|
||||
}
|
||||
}, [activePolygonIndex, polygons, setPolygons]);
|
||||
|
||||
return (
|
||||
<Stage
|
||||
ref={stageRef}
|
||||
|
@ -21,12 +21,31 @@ export default function PolygonEditControls({
|
||||
|
||||
const updatedPolygons = [...polygons];
|
||||
const activePolygon = updatedPolygons[activePolygonIndex];
|
||||
updatedPolygons[activePolygonIndex] = {
|
||||
...activePolygon,
|
||||
points: [...activePolygon.points.slice(0, -1)],
|
||||
isFinished: false,
|
||||
};
|
||||
setPolygons(updatedPolygons);
|
||||
|
||||
if (
|
||||
activePolygon.points.length > 0 &&
|
||||
activePolygon.pointsOrder &&
|
||||
activePolygon.pointsOrder.length > 0
|
||||
) {
|
||||
const lastPointOrderIndex = activePolygon.pointsOrder.indexOf(
|
||||
Math.max(...activePolygon.pointsOrder),
|
||||
);
|
||||
|
||||
updatedPolygons[activePolygonIndex] = {
|
||||
...activePolygon,
|
||||
points: [
|
||||
...activePolygon.points.slice(0, lastPointOrderIndex),
|
||||
...activePolygon.points.slice(lastPointOrderIndex + 1),
|
||||
],
|
||||
pointsOrder: [
|
||||
...activePolygon.pointsOrder.slice(0, lastPointOrderIndex),
|
||||
...activePolygon.pointsOrder.slice(lastPointOrderIndex + 1),
|
||||
],
|
||||
isFinished: false,
|
||||
};
|
||||
|
||||
setPolygons(updatedPolygons);
|
||||
}
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
|
@ -7,8 +7,8 @@ export type Polygon = {
|
||||
type: PolygonType;
|
||||
objects: string[];
|
||||
points: number[][];
|
||||
pointsOrder?: number[];
|
||||
isFinished: boolean;
|
||||
// isUnsaved: boolean;
|
||||
color: number[];
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user