diff --git a/frontend/editor3d/app/components/reusable/Popover/Popover.tsx b/frontend/editor3d/app/components/reusable/Popover/Popover.tsx
index 41ad4e3633..a37bb816ca 100644
--- a/frontend/editor3d/app/components/reusable/Popover/Popover.tsx
+++ b/frontend/editor3d/app/components/reusable/Popover/Popover.tsx
@@ -42,11 +42,13 @@ export const PopoverMenu = ({
}: PopoverMenuProps) => {
const selectedItem = items.find((item) => item.selected);
- const handleItemClick = (item: PopoverItem) => {
+ const handleItemClick = (item: PopoverItem, close: () => void) => {
if (mode === "button" && item.action && onAction) {
onAction(item.action);
+ close();
} else {
onSelect?.(item);
+ close();
}
};
@@ -60,67 +62,75 @@ export const PopoverMenu = ({
return (
-
- {triggerIcon}
- {mode === "toggle" && selectedItem ? selectedItem.label : null}
- {mode === "default" && triggerLabel ? triggerLabel : null}
-
+ {({ close }) => (
+ <>
+
+ {triggerIcon}
+ {mode === "toggle" && selectedItem ? selectedItem.label : null}
+ {mode === "default" && triggerLabel ? triggerLabel : null}
+
-
-
-
-
+
- {panelTitle && (
-
- {panelTitle}
-
- )}
- {mode === "default" && children ? (
- {children}
- ) : (
-
- {items.map((item, index) => (
-
-
-
-
+
+
+
+ >
+ )}
);
};
diff --git a/frontend/editor3d/app/pages/PageEnigma/Editor/editor.ts b/frontend/editor3d/app/pages/PageEnigma/Editor/editor.ts
index d685aca0a1..3eaaf218e7 100644
--- a/frontend/editor3d/app/pages/PageEnigma/Editor/editor.ts
+++ b/frontend/editor3d/app/pages/PageEnigma/Editor/editor.ts
@@ -334,6 +334,20 @@ class Editor {
aspectRatio: 16 / 9,
};
}
+ case CameraAspectRatio.HORIZONTAL_3_2: {
+ return {
+ width: 1200,
+ height: 800,
+ aspectRatio: 3 / 2,
+ };
+ }
+ case CameraAspectRatio.VERTICAL_2_3: {
+ return {
+ width: 800,
+ height: 1200,
+ aspectRatio: 2 / 3,
+ };
+ }
case CameraAspectRatio.VERTICAL_9_16: {
return {
width: 720,
@@ -948,16 +962,28 @@ class Editor {
this.render_camera_aspect_ratio === CameraAspectRatio.HORIZONTAL_16_9
? 1024
: this.render_camera_aspect_ratio ===
- CameraAspectRatio.VERTICAL_9_16
+ CameraAspectRatio.VERTICAL_9_16
? 576
- : 1000;
+ : this.render_camera_aspect_ratio ===
+ CameraAspectRatio.HORIZONTAL_3_2
+ ? 900
+ : this.render_camera_aspect_ratio ===
+ CameraAspectRatio.VERTICAL_2_3
+ ? 600
+ : 1000;
const height =
this.render_camera_aspect_ratio === CameraAspectRatio.HORIZONTAL_16_9
? 576
: this.render_camera_aspect_ratio ===
- CameraAspectRatio.VERTICAL_9_16
+ CameraAspectRatio.VERTICAL_9_16
? 1024
- : 1000;
+ : this.render_camera_aspect_ratio ===
+ CameraAspectRatio.HORIZONTAL_3_2
+ ? 600
+ : this.render_camera_aspect_ratio ===
+ CameraAspectRatio.VERTICAL_2_3
+ ? 900
+ : 1000;
this.rawRenderer.setSize(width, height);
diff --git a/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx b/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx
index 2ada8208c1..ba5ae88c51 100644
--- a/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx
+++ b/frontend/editor3d/app/pages/PageEnigma/PageEditor.tsx
@@ -113,7 +113,6 @@ export const PageEditor = () => {
diff --git a/frontend/editor3d/app/pages/PageEnigma/comps/AspectRatioMenu/AspectRatioMenu.tsx b/frontend/editor3d/app/pages/PageEnigma/comps/AspectRatioMenu/AspectRatioMenu.tsx
index 84abe7e181..2065290cb2 100644
--- a/frontend/editor3d/app/pages/PageEnigma/comps/AspectRatioMenu/AspectRatioMenu.tsx
+++ b/frontend/editor3d/app/pages/PageEnigma/comps/AspectRatioMenu/AspectRatioMenu.tsx
@@ -18,13 +18,21 @@ export const AspectRatioMenu = () => {
? faRectangle
: cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16
? faRectangleVertical
- : faSquare;
+ : cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_3_2
+ ? faRectangle
+ : cameraAspectRatio.value === CameraAspectRatio.VERTICAL_2_3
+ ? faRectangleVertical
+ : faSquare;
const buttonText =
cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_16_9
? "16:9 Horizontal"
: cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16
? "9:16 Vertical"
- : "1:1 Squared";
+ : cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_3_2
+ ? "3:2 Horizontal"
+ : cameraAspectRatio.value === CameraAspectRatio.VERTICAL_2_3
+ ? "2:3 Vertical"
+ : "1:1 Squared";
const handleChangeAspectRatio = (newRatio: CameraAspectRatio) => {
Queue.publish({
@@ -52,6 +60,26 @@ export const AspectRatioMenu = () => {
onClick: () =>
handleChangeAspectRatio(CameraAspectRatio.HORIZONTAL_16_9),
},
+ {
+ label: "3:2",
+ icon: faRectangle,
+ className: "pl-4",
+ description: "Horizontal",
+ selected:
+ cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_3_2,
+ onClick: () =>
+ handleChangeAspectRatio(CameraAspectRatio.HORIZONTAL_3_2),
+ },
+ {
+ label: "2:3",
+ icon: faRectangleVertical,
+ className: "pl-4",
+ description: "Vertical",
+ selected:
+ cameraAspectRatio.value === CameraAspectRatio.VERTICAL_2_3,
+ onClick: () =>
+ handleChangeAspectRatio(CameraAspectRatio.VERTICAL_2_3),
+ },
{
label: "9:16",
icon: faRectangleVertical,
diff --git a/frontend/editor3d/app/pages/PageEnigma/comps/PromptBox/PromptBox.tsx b/frontend/editor3d/app/pages/PageEnigma/comps/PromptBox/PromptBox.tsx
index 6229bb1998..6dfb06cf88 100644
--- a/frontend/editor3d/app/pages/PageEnigma/comps/PromptBox/PromptBox.tsx
+++ b/frontend/editor3d/app/pages/PageEnigma/comps/PromptBox/PromptBox.tsx
@@ -1,4 +1,5 @@
import { useState, useRef, useEffect } from "react";
+import { useSignals } from "@preact/signals-react/runtime";
import {
faPlus,
@@ -10,18 +11,46 @@ import {
faDownload,
faSpinnerThird,
} from "@fortawesome/pro-solid-svg-icons";
+import {
+ faRectangleWide,
+ faRectangleVertical,
+ faSquare,
+ faRectangle,
+} from "@fortawesome/pro-regular-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { PopoverItem, PopoverMenu } from "~/components/reusable/Popover";
import { Button } from "~/components";
+import { CameraAspectRatio } from "~/pages/PageEnigma/enums";
+import { cameraAspectRatio } from "~/pages/PageEnigma/signals";
+import { QueueNames } from "~/pages/PageEnigma/Queue/QueueNames";
+import Queue from "~/pages/PageEnigma/Queue/Queue";
+import { toEngineActions } from "~/pages/PageEnigma/Queue/toEngineActions";
export const PromptBox = () => {
+ useSignals();
const [prompt, setPrompt] = useState("");
const [isEnqueueing, setisEnqueueing] = useState(false);
const [aspectRatioList, setAspectRatioList] = useState([
- { label: "16:9", selected: true },
- { label: "3:2", selected: false },
- { label: "2:3", selected: false },
- { label: "1:1", selected: false },
+ {
+ label: "3:2",
+ selected: true,
+ icon: ,
+ },
+ {
+ label: "2:3",
+ selected: false,
+ icon: ,
+ },
+ {
+ label: "1:1",
+ selected: false,
+ icon: ,
+ },
+ {
+ label: "16:9",
+ selected: false,
+ icon: ,
+ },
]);
const [cameraList, setCameraList] = useState([
{
@@ -45,6 +74,25 @@ export const PromptBox = () => {
}
}, [prompt]);
+ // Update aspect ratio list based on the current cameraAspectRatio signal
+ useEffect(() => {
+ setAspectRatioList((prev) =>
+ prev.map((item) => ({
+ ...item,
+ selected:
+ (item.label === "16:9" &&
+ cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_16_9) ||
+ (item.label === "3:2" &&
+ cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_3_2) ||
+ (item.label === "2:3" &&
+ cameraAspectRatio.value === CameraAspectRatio.VERTICAL_2_3) ||
+ (item.label === "1:1" &&
+ cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1),
+ })),
+ );
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [cameraAspectRatio.value]);
+
const handleCameraSelect = (selectedItem: PopoverItem) => {
setCameraList((prev) =>
prev.map((item) => ({
@@ -73,6 +121,32 @@ export const PromptBox = () => {
selected: item.label === selectedItem.label,
})),
);
+
+ // Map the selected label to the corresponding CameraAspectRatio enum value
+ let newRatio: CameraAspectRatio;
+ switch (selectedItem.label) {
+ case "16:9":
+ newRatio = CameraAspectRatio.HORIZONTAL_16_9;
+ break;
+ case "3:2":
+ newRatio = CameraAspectRatio.HORIZONTAL_3_2;
+ break;
+ case "2:3":
+ newRatio = CameraAspectRatio.VERTICAL_2_3;
+ break;
+ case "1:1":
+ newRatio = CameraAspectRatio.SQUARE_1_1;
+ break;
+ default:
+ newRatio = CameraAspectRatio.HORIZONTAL_16_9;
+ }
+
+ // Publish the change to the engine
+ Queue.publish({
+ queueName: QueueNames.TO_ENGINE,
+ action: toEngineActions.CHANGE_CAMERA_ASPECT_RATIO,
+ data: newRatio,
+ });
};
const handleFileUpload = (event: React.ChangeEvent) => {
@@ -133,6 +207,24 @@ export const PromptBox = () => {
}
};
+ // Get the current aspect ratio icon based on the cameraAspectRatio signal
+ const getCurrentAspectRatioIcon = () => {
+ switch (cameraAspectRatio.value) {
+ case CameraAspectRatio.HORIZONTAL_16_9:
+ return faRectangleWide;
+ case CameraAspectRatio.HORIZONTAL_3_2:
+ return faRectangle;
+ case CameraAspectRatio.VERTICAL_2_3:
+ return faRectangleVertical;
+ case CameraAspectRatio.VERTICAL_9_16:
+ return faRectangleVertical;
+ case CameraAspectRatio.SQUARE_1_1:
+ return faSquare;
+ default:
+ return faRectangleWide;
+ }
+ };
+
return (
{
onSelect={handleAspectRatioSelect}
mode="toggle"
panelTitle="Aspect Ratio"
+ showIconsInList
+ triggerIcon={
+
+ }
/>
= 0
+ ? MatteOrientation.TOP_BOTTOM
+ : MatteOrientation.LEFT_RIGHT;
+ }
+ case CameraAspectRatio.HORIZONTAL_3_2: {
+ return (width / 3) * 2 - height >= 0
+ ? MatteOrientation.LEFT_RIGHT
+ : MatteOrientation.TOP_BOTTOM;
+ }
case CameraAspectRatio.HORIZONTAL_16_9:
default: {
return (width / 16) * 9 - height >= 0
@@ -58,6 +68,12 @@ export const calcMatteWidth = ({
case CameraAspectRatio.VERTICAL_9_16: {
return (width - (height / 16) * 9) / 2;
}
+ case CameraAspectRatio.HORIZONTAL_3_2: {
+ return (width - (height / 2) * 3) / 2;
+ }
+ case CameraAspectRatio.VERTICAL_2_3: {
+ return (width - (height / 3) * 2) / 2;
+ }
default: {
return undefined;
}
@@ -88,6 +104,12 @@ export const calcMatteHeight = ({
case CameraAspectRatio.VERTICAL_9_16: {
return (height - (width / 9) * 16) / 2;
}
+ case CameraAspectRatio.HORIZONTAL_3_2: {
+ return (height - (width / 3) * 2) / 2;
+ }
+ case CameraAspectRatio.VERTICAL_2_3: {
+ return (height - (width / 2) * 3) / 2;
+ }
default: {
return undefined;
}
diff --git a/frontend/editor3d/app/pages/PageEnigma/enums/EditorState.ts b/frontend/editor3d/app/pages/PageEnigma/enums/EditorState.ts
index 70375c046b..12c1af5b96 100644
--- a/frontend/editor3d/app/pages/PageEnigma/enums/EditorState.ts
+++ b/frontend/editor3d/app/pages/PageEnigma/enums/EditorState.ts
@@ -8,4 +8,6 @@ export enum CameraAspectRatio {
HORIZONTAL_16_9 = "horizontal_16_9",
VERTICAL_9_16 = "vertical_9_16",
SQUARE_1_1 = "SQUARE_1_1",
+ HORIZONTAL_3_2 = "horizontal_3_2",
+ VERTICAL_2_3 = "vertical_2_3",
}
diff --git a/frontend/editor3d/package-lock.json b/frontend/editor3d/package-lock.json
index 7cdc023616..293a635c71 100644
--- a/frontend/editor3d/package-lock.json
+++ b/frontend/editor3d/package-lock.json
@@ -9,6 +9,7 @@
"@awesome.me/kit-fde2be5eb0": "^1.0.7",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
+ "@fortawesome/pro-regular-svg-icons": "^6.5.1",
"@fortawesome/pro-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.18",
@@ -1423,6 +1424,17 @@
"node": ">=6"
}
},
+ "node_modules/@fortawesome/pro-regular-svg-icons": {
+ "version": "6.7.2",
+ "resolved": "https://npm.fontawesome.com/@fortawesome/pro-regular-svg-icons/-/6.7.2/pro-regular-svg-icons-6.7.2.tgz",
+ "integrity": "sha512-cJolK4K/s56mHAqOyno24SmjviHqSqG9ZfckBKCpWjJlgDexi61EfET5wWbmmEot6/BqasFjw9S6tudFQUL/PQ==",
+ "dependencies": {
+ "@fortawesome/fontawesome-common-types": "6.7.2"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@fortawesome/pro-solid-svg-icons": {
"version": "6.7.2",
"resolved": "https://npm.fontawesome.com/@fortawesome/pro-solid-svg-icons/-/6.7.2/pro-solid-svg-icons-6.7.2.tgz",
diff --git a/frontend/editor3d/package.json b/frontend/editor3d/package.json
index 09be8ba37c..a58ba39767 100644
--- a/frontend/editor3d/package.json
+++ b/frontend/editor3d/package.json
@@ -21,6 +21,7 @@
"@awesome.me/kit-fde2be5eb0": "^1.0.7",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.2",
+ "@fortawesome/pro-regular-svg-icons": "^6.5.1",
"@fortawesome/pro-solid-svg-icons": "^6.5.1",
"@fortawesome/react-fontawesome": "^0.2.0",
"@headlessui/react": "^1.7.18",