diff --git a/frontend/react/src/ui/libs/useDrag.ts b/frontend/react/src/ui/libs/useDrag.ts
index ccb343f3..2c1e31c8 100644
--- a/frontend/react/src/ui/libs/useDrag.ts
+++ b/frontend/react/src/ui/libs/useDrag.ts
@@ -44,8 +44,8 @@ export const useDrag = (props: { ref, initialPosition, count}) => {
const [parentTop, parentLeft, parentWidth, parentHeight] = [parentRect.top, parentRect.left, parentRect.width, parentRect.height];
setFinalPosition({
- x: Math.max(width / 2, Math.min(mouseX - parentLeft, parentWidth - width / 2)),
- y: Math.max(height / 2, Math.min(mouseY - parentTop, parentHeight - height / 2)),
+ x: Math.round(Math.max(width / 2, Math.min(mouseX - parentLeft, parentWidth - width / 2)) / 10) * 10,
+ y: Math.round(Math.max(height / 2, Math.min(mouseY - parentTop, parentHeight - height / 2)) / 10) * 10,
});
},
[isDragging, props.ref]
diff --git a/frontend/react/src/ui/panels/components/menu.tsx b/frontend/react/src/ui/panels/components/menu.tsx
index e5697267..8477f51f 100644
--- a/frontend/react/src/ui/panels/components/menu.tsx
+++ b/frontend/react/src/ui/panels/components/menu.tsx
@@ -41,7 +41,7 @@ export function Menu(props: {
>
{})}
icon={faArrowLeft}
className={`
- mr-1 cursor-pointer rounded-md p-2
+ mr-1 h-8 cursor-pointer rounded-md p-2
dark:text-gray-500 dark:hover:bg-gray-700 dark:hover:text-white
`}
/>
@@ -68,7 +68,9 @@ export function Menu(props: {
`}
/>
+
{props.children}
+
{props.canBeHidden == true && (
{
+ if (idx < units.length) units[idx + 1] = unit;
+ });
+
+ /* Init state variables */
const [formationType, setFormationType] = useState("echelon-lh");
const [horizontalScale, setHorizontalScale] = useState(0);
const [verticalScale, setVerticalScale] = useState(30);
+ const [offsets, setOffsets] = useState(
+ units.map((unit, idx) => {
+ return computeFormationOffset(formationType, idx);
+ })
+ );
+
+ /* The count state is used to force the reset of the initial position of the silhouettes */
+ // TODO it works but I don't like it, it feels like a hack
const [count, setCount] = useState(0);
- let units = Array(128).fill(null) as (Unit | null)[];
- units[0] = props.leader;
- props.wingmen?.forEach((unit, idx) => (units[idx + 1] = unit));
-
+ /* Init references and hooks */
const containerRef = useRef(null);
- const silhouetteReferences = units.map((unit) => useRef(null));
- const silhouetteHandles = units.map((unit, idx) => {
- let offset = computeFormationOffset(formationType, idx);
+ const scrollRef = useRef(null);
+ const silhouetteReferences = units.map((_) => useRef(null));
+ const silhouetteHandles = units.map((_, idx) => {
+ /* Set the initial position of the unit to be centered in the drawing canvas, depending on the currently loaded formation */
+ let offset = offsets[idx] ?? { x: 0, y: 0, z: 0 };
let center = { x: 0, y: 0 };
if (containerRef.current) {
center.x = (containerRef.current as HTMLDivElement).getBoundingClientRect().width / 2;
- center.y = 150;
+ center.y = (containerRef.current as HTMLDivElement).getBoundingClientRect().height / 2;
}
return useDrag({
ref: silhouetteReferences[idx],
@@ -37,53 +53,168 @@ export function FormationMenu(props: {
});
});
- let formationTypes = {
- "echelon-lh": "Echelon left",
- "echelon-rh": "Echelon right",
- "line-abreast-rh": "Line abreast right",
- "line-abreast-lh": "Line abreast left",
- trail: "Trail",
- front: "Front",
- diamond: "Diamond",
- };
+ /* When the formation type is changed, reset the position to the center and the position of the silhouettes depending on the aircraft */
+ useEffect(() => {
+ if (scrollRef.current && containerRef.current) {
+ const containerDiv = containerRef.current as HTMLDivElement;
+ const scrollDiv = scrollRef.current as HTMLDivElement;
+ scrollDiv.scrollTop = (containerDiv.clientHeight - scrollDiv.clientHeight) / 2 + 150;
+ scrollDiv.scrollLeft = (containerDiv.clientWidth - scrollDiv.clientWidth) / 2;
+ }
+
+ if (formationType !== "custom") {
+ setOffsets(
+ units.map((unit, idx) => {
+ return computeFormationOffset(formationType, idx);
+ })
+ );
+ setCount(count + 1);
+ }
+ }, [formationType]);
+
+ const horizontalRatio = 1 + (horizontalScale / 100) ** 2 * 100;
+ const verticalRatio = (verticalScale - 50) / 50;
+
+ let referenceDistance = 200 * horizontalRatio;
+ if (referenceDistance < 250) {
+ referenceDistance = 100;
+ } else if (referenceDistance < 500) {
+ referenceDistance = 250;
+ } else if (referenceDistance < 1000) {
+ referenceDistance = 500;
+ } else if (referenceDistance < 3000) {
+ referenceDistance = 1000;
+ } else if (referenceDistance < 10000) {
+ referenceDistance = 5000;
+ } else {
+ referenceDistance = 10000;
+ }
+
+ const referenceWidth = referenceDistance / horizontalRatio;
return (