mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-04 17:38:10 +00:00
PageEnigma refactor Phase 5a: migrate engine.ts signal slice to the store
Migrates components and engine code from reading signals/engine.ts (cameraAspectRatio, editorState, gridVisibility, previewSrc) to reading the Zustand store. Components migrated to usePageEnigmaStore reads: - AspectRatioMenu (also dropped useSignals + collapsed two duplicated lookup ladders into ICON_BY_RATIO / LABEL_BY_RATIO) - PreviewFrameImage - Letterbox (no longer reactive via signals; reads camAspect from store) - StyleButtons (editorState, previewSrc, setEditorState) - Outliner (cameraAspectRatio) - SidePanelMenu (editorState + setEditorState) - ControlPanelSceneObject (editorState) - PreviewEngineCamera (cameraAspectRatio + editorState) - PageEditor (cameraAspectRatio for getScale; the signal version still flows into PromptBox3D as a prop) Engine code migrated to usePageEnigmaStore.getState(): - editor.ts: snapShotOfCurrentFrame reads cameraAspectRatio + grid; switchPreview / switchEdit set editorState - helper.ts: switchCameraView writes editorState - video_generation.ts: generateFrame writes previewSrc + editorState - SceneMetadata.ts: cameraAspectRatio for snapshot metadata - scene.ts: subscribes to store gridVisible (not the signal) signals/engine.ts becomes a thin compatibility layer for PromptBox3D's signal-typed props. Its setters dual-write into the store so any PromptBox3D-driven changes (grid toggle, aspect ratio dropdown) keep the store authoritative. editorState / previewSrc / setEditorState removed entirely -- nothing outside the store needs them anymore. Net effect on typecheck: 148 -> 147 errors in PageEnigma. Zero new errors introduced.
This commit is contained in:
1 parent
35aae54d49
commit
4b0618e50b
15 files changed
+173
-192
No files matched your search
@@ -1,6 +1,5 @@
|
||||
import { getArtStyle } from "~/enums/ArtStyle";
|
||||
import {
|
||||
cameraAspectRatio,
|
||||
cinematic,
|
||||
enginePreProcessing,
|
||||
faceDetail,
|
||||
@@ -11,6 +10,7 @@ import {
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import { SceneGenereationMetaData as SceneGenerationMetaData } from "~/pages/PageEnigma/models/sceneGenerationMetadata";
|
||||
import Editor from "./editor";
|
||||
import { usePageEnigmaStore } from "../PageEnigmaStore";
|
||||
|
||||
export const getSceneGenerationMetaData = (
|
||||
editorEngine: Editor,
|
||||
@@ -20,7 +20,7 @@ export const getSceneGenerationMetaData = (
|
||||
positivePrompt: editorEngine.positive_prompt,
|
||||
negativePrompt: editorEngine.negative_prompt,
|
||||
artisticStyle: getArtStyle(editorEngine.art_style.toString()),
|
||||
cameraAspectRatio: cameraAspectRatio.value,
|
||||
cameraAspectRatio: usePageEnigmaStore.getState().cameraAspectRatio,
|
||||
globalIPAMediaToken: globalIPAMediaToken.value || undefined,
|
||||
upscale: upscale.value,
|
||||
faceDetail: faceDetail.value,
|
||||
|
||||
@@ -16,11 +16,6 @@ import { PointerLockControls } from "three/addons/controls/PointerLockControls.j
|
||||
import { EditorStates, CameraAspectRatio } from "~/pages/PageEnigma/enums";
|
||||
import { AssetType, ClipGroup } from "~/enums";
|
||||
import { XYZ } from "../datastructures/common";
|
||||
import {
|
||||
editorState,
|
||||
cameraAspectRatio,
|
||||
gridVisibility,
|
||||
} from "../signals/engine";
|
||||
import { SceneUtils } from "./helper";
|
||||
import { VideoGeneration } from "./video_generation";
|
||||
import { MouseControls } from "./keybinds_controls";
|
||||
@@ -698,11 +693,12 @@ class Editor {
|
||||
return null;
|
||||
}
|
||||
|
||||
const currentAspectRatio = cameraAspectRatio.value;
|
||||
const store = usePageEnigmaStore.getState();
|
||||
const currentAspectRatio = store.cameraAspectRatio;
|
||||
|
||||
// Store grid visibility state and hide grid
|
||||
const wasGridVisible = gridVisibility.value;
|
||||
gridVisibility.value = false;
|
||||
const wasGridVisible = store.gridVisible;
|
||||
store.setGridVisible(false);
|
||||
|
||||
// Store and hide transform controls
|
||||
const wasControlVisible = this.control?.visible ?? false;
|
||||
@@ -810,7 +806,7 @@ class Editor {
|
||||
}
|
||||
|
||||
// Restore grid visibility
|
||||
gridVisibility.value = wasGridVisible;
|
||||
usePageEnigmaStore.getState().setGridVisible(wasGridVisible);
|
||||
|
||||
// Restore transform controls visibility
|
||||
if (this.control) {
|
||||
@@ -1336,7 +1332,7 @@ class Editor {
|
||||
async switchPreview() {
|
||||
if (!this.switchPreviewToggle) {
|
||||
this.switchPreviewToggle = true;
|
||||
editorState.value = EditorStates.PREVIEW;
|
||||
usePageEnigmaStore.getState().setEditorState(EditorStates.PREVIEW);
|
||||
await this.generateFrame();
|
||||
}
|
||||
}
|
||||
@@ -1348,7 +1344,7 @@ class Editor {
|
||||
this.rawRenderPass
|
||||
) {
|
||||
this.switchPreviewToggle = false;
|
||||
editorState.value = EditorStates.EDIT;
|
||||
usePageEnigmaStore.getState().setEditorState(EditorStates.EDIT);
|
||||
setTimeout(() => {
|
||||
// if (!this.canvasRenderCamReference) {
|
||||
// this.canvasRenderCamReference =
|
||||
|
||||
@@ -2,7 +2,6 @@ import Scene from "./scene";
|
||||
import Editor from "./editor";
|
||||
import * as THREE from "three";
|
||||
import { XYZ } from "../datastructures/common";
|
||||
import { editorState } from "../signals/engine";
|
||||
import { EditorStates } from "../enums";
|
||||
import { hideObjectPanel } from "../signals";
|
||||
import { usePageEnigmaStore } from "../PageEnigmaStore";
|
||||
@@ -141,7 +140,7 @@ export class SceneUtils {
|
||||
this.editor.selected = this.editor.cam_obj;
|
||||
this.editor.publishSelect();
|
||||
this.editor.updateSelectedUI();
|
||||
editorState.value = EditorStates.CAMERA_VIEW;
|
||||
usePageEnigmaStore.getState().setEditorState(EditorStates.CAMERA_VIEW);
|
||||
if (this.editor.activeScene.hot_items) {
|
||||
this.editor.activeScene.hot_items.forEach((element) => {
|
||||
element.visible = false;
|
||||
@@ -174,7 +173,7 @@ export class SceneUtils {
|
||||
}
|
||||
|
||||
hideObjectPanel();
|
||||
editorState.value = EditorStates.EDIT;
|
||||
usePageEnigmaStore.getState().setEditorState(EditorStates.EDIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { MMDAnimationHelper, Water } from "three/examples/jsm/Addons.js";
|
||||
import { MediaFileType } from "../enums";
|
||||
import { ChromaKeyMaterial } from "./chromakey";
|
||||
import { LoadWithoutCors } from "@storyteller/tauri-api";
|
||||
import { gridVisibility } from "../signals/engine";
|
||||
import { usePageEnigmaStore } from "../PageEnigmaStore";
|
||||
import { InfiniteGridHelper } from "./InfiniteGridHelper";
|
||||
import { cameras, selectedCameraId } from "../signals/camera";
|
||||
import { MediaFilesApi } from "@storyteller/api";
|
||||
@@ -91,16 +91,15 @@ class Scene {
|
||||
this.helper = new MMDAnimationHelper({ afterglow: 0.0 });
|
||||
this.scene.userData["helper"] = this.helper;
|
||||
|
||||
// Subscribe to grid visibility changes
|
||||
gridVisibility.subscribe((isVisible) => {
|
||||
if (this.gridHelper) {
|
||||
if (isVisible) {
|
||||
if (!this.scene.children.includes(this.gridHelper)) {
|
||||
this.scene.add(this.gridHelper);
|
||||
}
|
||||
} else {
|
||||
this.scene.remove(this.gridHelper);
|
||||
// Subscribe to grid visibility changes from the store
|
||||
usePageEnigmaStore.subscribe((state, prev) => {
|
||||
if (state.gridVisible === prev.gridVisible || !this.gridHelper) return;
|
||||
if (state.gridVisible) {
|
||||
if (!this.scene.children.includes(this.gridHelper)) {
|
||||
this.scene.add(this.gridHelper);
|
||||
}
|
||||
} else {
|
||||
this.scene.remove(this.gridHelper);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1093,9 +1092,9 @@ class Scene {
|
||||
this.scene.add(this.groundPlane);
|
||||
}
|
||||
|
||||
// Update grid visibility based on the signal
|
||||
// Update grid visibility based on the store
|
||||
updateGridVisibility() {
|
||||
if (gridVisibility.value) {
|
||||
if (usePageEnigmaStore.getState().gridVisible) {
|
||||
if (!this.scene.children.includes(this.gridHelper)) {
|
||||
this.scene.add(this.gridHelper);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Editor from "./editor";
|
||||
import { EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { editorState, previewSrc } from "../signals/engine";
|
||||
import { usePageEnigmaStore } from "../PageEnigmaStore";
|
||||
import { ToastTypes, ClipType } from "~/enums";
|
||||
|
||||
import { Visibility } from "./api_manager.js";
|
||||
@@ -109,7 +109,7 @@ export class VideoGeneration {
|
||||
});
|
||||
}
|
||||
|
||||
previewSrc.value = "";
|
||||
usePageEnigmaStore.getState().setPreviewSrc("");
|
||||
|
||||
this.editor.rawRenderer.setSize(
|
||||
this.editor.render_width,
|
||||
@@ -132,7 +132,7 @@ export class VideoGeneration {
|
||||
|
||||
if (!this.editor.camera_person_mode) {
|
||||
this.editor.switchCameraView();
|
||||
editorState.value = EditorStates.PREVIEW;
|
||||
usePageEnigmaStore.getState().setEditorState(EditorStates.PREVIEW);
|
||||
}
|
||||
|
||||
this.editor.generating_preview = false;
|
||||
@@ -146,7 +146,7 @@ export class VideoGeneration {
|
||||
this.editor.negative_prompt,
|
||||
);
|
||||
|
||||
previewSrc.value = url;
|
||||
usePageEnigmaStore.getState().setPreviewSrc(url);
|
||||
return Promise.resolve(url);
|
||||
} catch (err: unknown) {
|
||||
const errorMessage =
|
||||
|
||||
@@ -61,6 +61,7 @@ import {
|
||||
} from "~/components/signaled/TopBar/TopBar";
|
||||
import { uploadPlaneFromMediaToken } from "~/components/reusable/UploadModalMedia/uploadPlane";
|
||||
import { addObject, addCharacter } from "./actions";
|
||||
import { usePageEnigmaStore } from "./PageEnigmaStore";
|
||||
import { AssetType, AUTH_STATUS } from "~/enums";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { MediaItem } from "~/pages/PageEnigma/models";
|
||||
@@ -106,6 +107,7 @@ export const PageEditor = () => {
|
||||
|
||||
const tabStore = useTabStore();
|
||||
const storyboardPageEnabled = useStoryboardPageEnabled();
|
||||
const camAspect = usePageEnigmaStore((s) => s.cameraAspectRatio);
|
||||
const handleOverlayClick = (event: React.MouseEvent<HTMLDivElement>) => {
|
||||
event.stopPropagation();
|
||||
};
|
||||
@@ -134,7 +136,7 @@ export const PageEditor = () => {
|
||||
const scaleHeight = height < 610 ? height / 610 : 1;
|
||||
|
||||
if (
|
||||
cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16 &&
|
||||
camAspect === CameraAspectRatio.VERTICAL_9_16 &&
|
||||
outlinerIsShowing.value &&
|
||||
height < 900
|
||||
) {
|
||||
@@ -145,7 +147,7 @@ export const PageEditor = () => {
|
||||
}
|
||||
|
||||
if (
|
||||
cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1 &&
|
||||
camAspect === CameraAspectRatio.SQUARE_1_1 &&
|
||||
pageWidth.value < 2000
|
||||
) {
|
||||
return scaleHeight * 0.85;
|
||||
|
||||
+26
-34
@@ -1,4 +1,3 @@
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import {
|
||||
faRectangle,
|
||||
faRectangleVertical,
|
||||
@@ -6,45 +5,42 @@ import {
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { useContext } from "react";
|
||||
import { CameraAspectRatio } from "~/pages/PageEnigma/enums";
|
||||
import { cameraAspectRatio } from "~/pages/PageEnigma/signals";
|
||||
import { setCameraAspect } from "~/pages/PageEnigma/actions";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
import { EngineContext } from "~/pages/PageEnigma/contexts/EngineContext";
|
||||
import { ButtonDropdown } from "@storyteller/ui-button-dropdown";
|
||||
|
||||
const ICON_BY_RATIO: Record<CameraAspectRatio, typeof faRectangle> = {
|
||||
[CameraAspectRatio.HORIZONTAL_16_9]: faRectangle,
|
||||
[CameraAspectRatio.VERTICAL_9_16]: faRectangleVertical,
|
||||
[CameraAspectRatio.HORIZONTAL_3_2]: faRectangle,
|
||||
[CameraAspectRatio.VERTICAL_2_3]: faRectangleVertical,
|
||||
[CameraAspectRatio.SQUARE_1_1]: faSquare,
|
||||
};
|
||||
|
||||
const LABEL_BY_RATIO: Record<CameraAspectRatio, string> = {
|
||||
[CameraAspectRatio.HORIZONTAL_16_9]: "16:9 Horizontal",
|
||||
[CameraAspectRatio.VERTICAL_9_16]: "9:16 Vertical",
|
||||
[CameraAspectRatio.HORIZONTAL_3_2]: "3:2 Horizontal",
|
||||
[CameraAspectRatio.VERTICAL_2_3]: "2:3 Vertical",
|
||||
[CameraAspectRatio.SQUARE_1_1]: "1:1 Squared",
|
||||
};
|
||||
|
||||
export const AspectRatioMenu = () => {
|
||||
useSignals();
|
||||
const aspect = usePageEnigmaStore((s) => s.cameraAspectRatio);
|
||||
const editor = useContext(EngineContext);
|
||||
const buttonIcon =
|
||||
cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_16_9
|
||||
? faRectangle
|
||||
: cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16
|
||||
? faRectangleVertical
|
||||
: 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"
|
||||
: 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) => {
|
||||
if (!editor) return;
|
||||
setCameraAspect(editor, newRatio);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="absolute right-0 top-0 m-2 flex flex-col items-end">
|
||||
<ButtonDropdown
|
||||
label={`${buttonText}`}
|
||||
label={LABEL_BY_RATIO[aspect]}
|
||||
className="shadow-xl"
|
||||
icon={buttonIcon}
|
||||
icon={ICON_BY_RATIO[aspect]}
|
||||
align="right"
|
||||
showSelected={true}
|
||||
options={[
|
||||
@@ -53,8 +49,7 @@ export const AspectRatioMenu = () => {
|
||||
icon: faRectangle,
|
||||
className: "pl-4",
|
||||
description: "Horizontal",
|
||||
selected:
|
||||
cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_16_9,
|
||||
selected: aspect === CameraAspectRatio.HORIZONTAL_16_9,
|
||||
onClick: () =>
|
||||
handleChangeAspectRatio(CameraAspectRatio.HORIZONTAL_16_9),
|
||||
},
|
||||
@@ -63,8 +58,7 @@ export const AspectRatioMenu = () => {
|
||||
icon: faRectangle,
|
||||
className: "pl-4",
|
||||
description: "Horizontal",
|
||||
selected:
|
||||
cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_3_2,
|
||||
selected: aspect === CameraAspectRatio.HORIZONTAL_3_2,
|
||||
onClick: () =>
|
||||
handleChangeAspectRatio(CameraAspectRatio.HORIZONTAL_3_2),
|
||||
},
|
||||
@@ -73,8 +67,7 @@ export const AspectRatioMenu = () => {
|
||||
icon: faRectangleVertical,
|
||||
className: "pl-4",
|
||||
description: "Vertical",
|
||||
selected:
|
||||
cameraAspectRatio.value === CameraAspectRatio.VERTICAL_2_3,
|
||||
selected: aspect === CameraAspectRatio.VERTICAL_2_3,
|
||||
onClick: () =>
|
||||
handleChangeAspectRatio(CameraAspectRatio.VERTICAL_2_3),
|
||||
},
|
||||
@@ -83,8 +76,7 @@ export const AspectRatioMenu = () => {
|
||||
icon: faRectangleVertical,
|
||||
className: "pl-4",
|
||||
description: "Vertical",
|
||||
selected:
|
||||
cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16,
|
||||
selected: aspect === CameraAspectRatio.VERTICAL_9_16,
|
||||
onClick: () =>
|
||||
handleChangeAspectRatio(CameraAspectRatio.VERTICAL_9_16),
|
||||
},
|
||||
@@ -93,7 +85,7 @@ export const AspectRatioMenu = () => {
|
||||
icon: faSquare,
|
||||
className: "pl-4",
|
||||
description: "Squared",
|
||||
selected: cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1,
|
||||
selected: aspect === CameraAspectRatio.SQUARE_1_1,
|
||||
onClick: () =>
|
||||
handleChangeAspectRatio(CameraAspectRatio.SQUARE_1_1),
|
||||
},
|
||||
|
||||
+3
-2
@@ -17,7 +17,7 @@ import {
|
||||
import { EngineContext } from "~/pages/PageEnigma/contexts/EngineContext";
|
||||
import { InputVector } from "@storyteller/ui-input";
|
||||
import { Button } from "@storyteller/ui-button";
|
||||
import { editorState } from "~/pages/PageEnigma/signals/engine";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { sanitize } from "./utils/sanitize";
|
||||
@@ -43,6 +43,7 @@ const defaultAxises: Record<string, string> = {
|
||||
|
||||
export const ControlPanelSceneObject = () => {
|
||||
useSignals();
|
||||
const editorState = usePageEnigmaStore((s) => s.editorState);
|
||||
const { isShowing, currentObject } = objectPanelSignals;
|
||||
|
||||
const editorEngine = useContext(EngineContext);
|
||||
@@ -114,7 +115,7 @@ export const ControlPanelSceneObject = () => {
|
||||
setColor(editorEngine?.selected?.userData.color);
|
||||
}, [currentSceneObject, editorEngine]);
|
||||
|
||||
if (!currentSceneObject || editorState.value === EditorStates.PREVIEW) {
|
||||
if (!currentSceneObject || editorState === EditorStates.PREVIEW) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import { Transition } from "@headlessui/react";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { EngineContext } from "../../contexts/EngineContext";
|
||||
import { cameraAspectRatio } from "../../signals";
|
||||
import { usePageEnigmaStore } from "../../PageEnigmaStore";
|
||||
import { pageHeight, pageWidth } from "~/signals";
|
||||
import { CameraAspectRatio } from "../../enums";
|
||||
import { effect } from "@preact/signals-react";
|
||||
@@ -121,6 +121,7 @@ const OutlinerItem = ({ item }: { item: SceneObject }) => {
|
||||
|
||||
export const Outliner = () => {
|
||||
useSignals();
|
||||
const camAspect = usePageEnigmaStore((s) => s.cameraAspectRatio);
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const [editorHeight, setEditorHeight] = useState(0);
|
||||
|
||||
@@ -158,9 +159,9 @@ export const Outliner = () => {
|
||||
|
||||
const getOutlinerHeightClass = () => {
|
||||
if (pageWidth.value >= 2000) {
|
||||
if (cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16) {
|
||||
if (camAspect === CameraAspectRatio.VERTICAL_9_16) {
|
||||
return `${editorHeight * 0.5 - 120}px`;
|
||||
} else if (cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1) {
|
||||
} else if (camAspect === CameraAspectRatio.SQUARE_1_1) {
|
||||
return `${editorHeight * 0.42}px`;
|
||||
} else {
|
||||
return `${editorHeight * 0.54}px`;
|
||||
@@ -168,9 +169,9 @@ export const Outliner = () => {
|
||||
}
|
||||
|
||||
if (pageWidth.value < 2000) {
|
||||
if (cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16) {
|
||||
if (camAspect === CameraAspectRatio.VERTICAL_9_16) {
|
||||
return `${editorHeight * 0.7 - 10}px`;
|
||||
} else if (cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1) {
|
||||
} else if (camAspect === CameraAspectRatio.SQUARE_1_1) {
|
||||
return `${editorHeight * 0.7}px`;
|
||||
} else {
|
||||
return `${editorHeight * 0.7}px`;
|
||||
|
||||
+26
-23
@@ -7,14 +7,14 @@ import {
|
||||
faCameraViewfinder,
|
||||
faSpinnerThird,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { useShallow } from "zustand/shallow";
|
||||
import {
|
||||
cameraAspectRatio,
|
||||
editorState,
|
||||
editorLetterBox,
|
||||
toggleEditorLetterBox,
|
||||
sidePanelHeight,
|
||||
outlinerIsShowing,
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
import { pageWidth } from "~/signals";
|
||||
import { CameraAspectRatio, EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { CameraViewCanvas } from "~/pages/PageEnigma/comps/EngineCanvases";
|
||||
@@ -25,26 +25,31 @@ import { useEffect } from "react";
|
||||
|
||||
export const PreviewEngineCamera = () => {
|
||||
useSignals();
|
||||
const { camAspect, editorState } = usePageEnigmaStore(
|
||||
useShallow((s) => ({
|
||||
camAspect: s.cameraAspectRatio,
|
||||
editorState: s.editorState,
|
||||
})),
|
||||
);
|
||||
|
||||
const handleButtonCameraView = () => {
|
||||
// TODO: wire to editor.toggleCameraView() once editor.ts is migrated.
|
||||
};
|
||||
|
||||
const getLargeScreenHeightClass = () => {
|
||||
if (cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16) {
|
||||
if (camAspect === CameraAspectRatio.VERTICAL_9_16) {
|
||||
return pageWidth.value >= 2000
|
||||
? "w-44 justify-center"
|
||||
: "w-36 justify-center";
|
||||
} else {
|
||||
return pageWidth.value >= 2000
|
||||
? "w-72 justify-between"
|
||||
: "w-64 justify-between";
|
||||
}
|
||||
return pageWidth.value >= 2000
|
||||
? "w-72 justify-between"
|
||||
: "w-64 justify-between";
|
||||
};
|
||||
|
||||
const getSmallScreenHeightClass = () => {
|
||||
if (
|
||||
cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16 &&
|
||||
camAspect === CameraAspectRatio.VERTICAL_9_16 &&
|
||||
sidePanelHeight.value < 2000 &&
|
||||
outlinerIsShowing.value
|
||||
) {
|
||||
@@ -54,23 +59,24 @@ export const PreviewEngineCamera = () => {
|
||||
};
|
||||
|
||||
const getSquareAspectRatioClass = () => {
|
||||
if (cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1) {
|
||||
if (camAspect === CameraAspectRatio.SQUARE_1_1) {
|
||||
return pageWidth.value >= 2000
|
||||
? "w-[240px] justify-between"
|
||||
: "w-60 justify-between";
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("Editor state changed:", editorState.value);
|
||||
}, [editorState.value]);
|
||||
console.log("Editor state changed:", editorState);
|
||||
}, [editorState]);
|
||||
|
||||
return (
|
||||
<div
|
||||
id="preview-engine-camera"
|
||||
className={twMerge(
|
||||
"hidden origin-bottom-left shadow-lg", //hidden right now with css
|
||||
editorState.value === EditorStates.PREVIEW
|
||||
editorState === EditorStates.PREVIEW
|
||||
? "invisible h-0 w-0"
|
||||
: "visible",
|
||||
)}
|
||||
@@ -86,17 +92,16 @@ export const PreviewEngineCamera = () => {
|
||||
<div
|
||||
className={twMerge(
|
||||
"origin -z-10 flex h-auto w-full flex-wrap items-center gap-1.5 rounded-t-lg bg-ui-panel p-2 text-white",
|
||||
cameraAspectRatio.value !== CameraAspectRatio.VERTICAL_9_16
|
||||
camAspect !== CameraAspectRatio.VERTICAL_9_16
|
||||
? "justify-between"
|
||||
: "flex-col justify-center",
|
||||
cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1 &&
|
||||
"justify-center",
|
||||
camAspect === CameraAspectRatio.SQUARE_1_1 && "justify-center",
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={twMerge(
|
||||
"ms-1 flex grow items-center gap-2",
|
||||
cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16 &&
|
||||
camAspect === CameraAspectRatio.VERTICAL_9_16 &&
|
||||
"-ms-1 justify-center",
|
||||
)}
|
||||
>
|
||||
@@ -105,7 +110,7 @@ export const PreviewEngineCamera = () => {
|
||||
</div>
|
||||
|
||||
<div className="flex gap-1.5">
|
||||
{editorState.value === EditorStates.CAMERA_VIEW && (
|
||||
{editorState === EditorStates.CAMERA_VIEW && (
|
||||
<Tooltip content="Toggle Letterbox" position={"top"}>
|
||||
<ButtonIcon
|
||||
icon={editorLetterBox.value ? faBlinds : faBlindsRaised}
|
||||
@@ -120,20 +125,18 @@ export const PreviewEngineCamera = () => {
|
||||
onClick={handleButtonCameraView}
|
||||
className="rounded-md px-2 py-1 text-sm"
|
||||
>
|
||||
{editorState.value === EditorStates.EDIT
|
||||
? "Enter View"
|
||||
: "Exit View"}
|
||||
{editorState === EditorStates.EDIT ? "Enter View" : "Exit View"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={twMerge(
|
||||
"relative overflow-hidden rounded-b-lg border border-gray-600",
|
||||
cameraAspectRatio.value === CameraAspectRatio.HORIZONTAL_16_9
|
||||
camAspect === CameraAspectRatio.HORIZONTAL_16_9
|
||||
? "aspect-[16/9]"
|
||||
: cameraAspectRatio.value === CameraAspectRatio.VERTICAL_9_16
|
||||
: camAspect === CameraAspectRatio.VERTICAL_9_16
|
||||
? "aspect-[9/16]"
|
||||
: cameraAspectRatio.value === CameraAspectRatio.SQUARE_1_1
|
||||
: camAspect === CameraAspectRatio.SQUARE_1_1
|
||||
? "aspect-[1/1]"
|
||||
: "aspect-video",
|
||||
)}
|
||||
|
||||
@@ -1,52 +1,49 @@
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { faSpinnerThird } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useShallow } from "zustand/shallow";
|
||||
import { EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { pageHeight, pageWidth } from "~/signals";
|
||||
import { editorState, previewSrc } from "~/pages/PageEnigma/signals/engine";
|
||||
import {
|
||||
sidePanelWidth,
|
||||
sidePanelVisible,
|
||||
} from "~/pages/PageEnigma/signals";
|
||||
import { sidePanelWidth, sidePanelVisible } from "~/pages/PageEnigma/signals";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
|
||||
export const PreviewFrameImage = () => {
|
||||
useSignals();
|
||||
if (editorState.value === EditorStates.PREVIEW) {
|
||||
if (previewSrc.value === "") {
|
||||
return (
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
width:
|
||||
pageWidth.value -
|
||||
(sidePanelVisible.value ? sidePanelWidth.value : 0) -
|
||||
84,
|
||||
height: pageHeight.value - 56,
|
||||
}}
|
||||
>
|
||||
<div className="relative flex h-full w-full flex-col items-center justify-center gap-5">
|
||||
<span className="absolute h-full w-full bg-black opacity-50" />
|
||||
<FontAwesomeIcon icon={faSpinnerThird} spin size="4x" />
|
||||
<h3 className="z-20 text-white">Generating Preview...</h3>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<img
|
||||
alt="preview of the art style that renders over the 3d scene"
|
||||
className="absolute inset-0 object-cover"
|
||||
src={previewSrc.value}
|
||||
style={{
|
||||
width:
|
||||
pageWidth.value -
|
||||
(sidePanelVisible.value ? sidePanelWidth.value : 0) -
|
||||
84,
|
||||
height: pageHeight.value - 56,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
const { editorState, previewSrc } = usePageEnigmaStore(
|
||||
useShallow((s) => ({
|
||||
editorState: s.editorState,
|
||||
previewSrc: s.previewSrc,
|
||||
})),
|
||||
);
|
||||
|
||||
if (editorState !== EditorStates.PREVIEW) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
|
||||
const width =
|
||||
pageWidth.value -
|
||||
(sidePanelVisible.value ? sidePanelWidth.value : 0) -
|
||||
84;
|
||||
const height = pageHeight.value - 56;
|
||||
|
||||
if (previewSrc === "") {
|
||||
return (
|
||||
<div className="absolute inset-0" style={{ width, height }}>
|
||||
<div className="relative flex h-full w-full flex-col items-center justify-center gap-5">
|
||||
<span className="absolute h-full w-full bg-black opacity-50" />
|
||||
<FontAwesomeIcon icon={faSpinnerThird} spin size="4x" />
|
||||
<h3 className="z-20 text-white">Generating Preview...</h3>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
alt="preview of the art style that renders over the 3d scene"
|
||||
className="absolute inset-0 object-cover"
|
||||
src={previewSrc}
|
||||
style={{ width, height }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { cameraAspectRatio } from "~/pages/PageEnigma/signals";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
|
||||
import {
|
||||
calcMatteWidth,
|
||||
@@ -18,32 +17,11 @@ export const Letterbox = ({
|
||||
width: number;
|
||||
height: number;
|
||||
}) => {
|
||||
useSignals();
|
||||
const camAspect = usePageEnigmaStore((s) => s.cameraAspectRatio);
|
||||
|
||||
// if (editorState.value !== EditorStates.CAMERA_VIEW || !isShowing) {
|
||||
// //case of Letterbox should not show
|
||||
// return;
|
||||
// }
|
||||
|
||||
const matteOri = getMatteOrientation({
|
||||
camAspect: cameraAspectRatio.value,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
const matteWidth = calcMatteWidth({
|
||||
matteOri,
|
||||
camAspect: cameraAspectRatio.value,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
|
||||
const matteHeight = calcMatteHeight({
|
||||
matteOri,
|
||||
camAspect: cameraAspectRatio.value,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
const matteOri = getMatteOrientation({ camAspect, width, height });
|
||||
const matteWidth = calcMatteWidth({ matteOri, camAspect, width, height });
|
||||
const matteHeight = calcMatteHeight({ matteOri, camAspect, width, height });
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
+9
-2
@@ -1,12 +1,13 @@
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { useShallow } from "zustand/shallow";
|
||||
import { usePosthogFeatureFlag } from "~/hooks/usePosthogFeatureFlag";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { FeatureFlags, TabTitles } from "~/enums";
|
||||
import { EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { editorState, setEditorState } from "~/pages/PageEnigma/signals/engine";
|
||||
import { sidePanelVisible } from "~/pages/PageEnigma/signals/sidePanel";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
|
||||
import { TabItem } from "../SidePanel/tabList";
|
||||
import { currentPage, pageHeight } from "~/signals";
|
||||
@@ -23,6 +24,12 @@ export const SidePanelMenu = ({
|
||||
}) => {
|
||||
useSignals();
|
||||
const showStylePage = usePosthogFeatureFlag(FeatureFlags.SHOW_STYLE_PAGE);
|
||||
const { editorState, setEditorState } = usePageEnigmaStore(
|
||||
useShallow((s) => ({
|
||||
editorState: s.editorState,
|
||||
setEditorState: s.setEditorState,
|
||||
})),
|
||||
);
|
||||
return (
|
||||
<div
|
||||
className={twMerge(
|
||||
@@ -60,7 +67,7 @@ export const SidePanelMenu = ({
|
||||
if (!sidePanelVisible.value) {
|
||||
sidePanelVisible.value = true;
|
||||
}
|
||||
if (editorState.value === EditorStates.PREVIEW) {
|
||||
if (editorState === EditorStates.PREVIEW) {
|
||||
setEditorState(EditorStates.EDIT);
|
||||
}
|
||||
}}
|
||||
|
||||
+22
-17
@@ -4,13 +4,20 @@ import {
|
||||
faArrowsRotate,
|
||||
faChevronLeft,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { editorState, previewSrc, setEditorState } from "~/pages/PageEnigma/signals/engine";
|
||||
import { useShallow } from "zustand/shallow";
|
||||
import { EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { useSignals } from "@preact/signals-react/runtime";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
import { StyleStrength } from "~/pages/PageEnigma/comps/SidePanelTabs/tabComps/StylizeTab/StyleStrength";
|
||||
import { StyleOptions } from "~/pages/PageEnigma/comps/SidePanelTabs/tabComps/StylizeTab/StyleOptions";
|
||||
|
||||
export function StyleButtons() {
|
||||
useSignals();
|
||||
const { editorState, previewSrc, setEditorState } = usePageEnigmaStore(
|
||||
useShallow((s) => ({
|
||||
editorState: s.editorState,
|
||||
previewSrc: s.previewSrc,
|
||||
setEditorState: s.setEditorState,
|
||||
})),
|
||||
);
|
||||
|
||||
const switchPreview = async () => {
|
||||
setEditorState(EditorStates.PREVIEW);
|
||||
@@ -32,19 +39,17 @@ export function StyleButtons() {
|
||||
<div className="mb-2 text-xs text-white/70">
|
||||
(This helps you test and re-test your scene)
|
||||
</div>
|
||||
{editorState.value !== EditorStates.PREVIEW && (
|
||||
<>
|
||||
<Button
|
||||
icon={faArrowsRotate}
|
||||
variant="action"
|
||||
className="mt-1.5 w-full"
|
||||
onClick={switchPreview}
|
||||
>
|
||||
Preview Frame
|
||||
</Button>
|
||||
</>
|
||||
{editorState !== EditorStates.PREVIEW && (
|
||||
<Button
|
||||
icon={faArrowsRotate}
|
||||
variant="action"
|
||||
className="mt-1.5 w-full"
|
||||
onClick={switchPreview}
|
||||
>
|
||||
Preview Frame
|
||||
</Button>
|
||||
)}
|
||||
{editorState.value === EditorStates.PREVIEW && (
|
||||
{editorState === EditorStates.PREVIEW && (
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
icon={faChevronLeft}
|
||||
@@ -58,9 +63,9 @@ export function StyleButtons() {
|
||||
variant="primary"
|
||||
onClick={refreshPreview}
|
||||
className="grow"
|
||||
loading={previewSrc.value === ""}
|
||||
loading={previewSrc === ""}
|
||||
>
|
||||
{previewSrc.value === "" ? "Rendering..." : "Re-render Preview"}
|
||||
{previewSrc === "" ? "Rendering..." : "Re-render Preview"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { signal } from "@preact/signals-core";
|
||||
import { CameraAspectRatio, EditorStates } from "~/pages/PageEnigma/enums";
|
||||
import { usePageEnigmaStore } from "~/pages/PageEnigma/PageEnigmaStore";
|
||||
|
||||
export const editorState = signal<EditorStates>(EditorStates.EDIT);
|
||||
|
||||
export const setEditorState = (newState: EditorStates) => {
|
||||
editorState.value = newState;
|
||||
};
|
||||
// These signals exist only to satisfy PromptBox3D's signal-typed props.
|
||||
// Components inside PageEnigma read from the Zustand store; the setters
|
||||
// below dual-write into the store so PromptBox3D's onChange callbacks
|
||||
// keep the store authoritative.
|
||||
|
||||
export const cameraAspectRatio = signal<CameraAspectRatio>(
|
||||
CameraAspectRatio.HORIZONTAL_3_2,
|
||||
@@ -13,11 +13,12 @@ export const cameraAspectRatio = signal<CameraAspectRatio>(
|
||||
|
||||
export const setCameraAspectRatio = (newAspectRatio: CameraAspectRatio) => {
|
||||
cameraAspectRatio.value = newAspectRatio;
|
||||
usePageEnigmaStore.getState().setCameraAspectRatio(newAspectRatio);
|
||||
};
|
||||
export const previewSrc = signal("");
|
||||
|
||||
export const gridVisibility = signal<boolean>(true);
|
||||
|
||||
export const setGridVisibility = (isVisible: boolean) => {
|
||||
gridVisibility.value = isVisible;
|
||||
usePageEnigmaStore.getState().setGridVisible(isVisible);
|
||||
};
|
||||
Reference in new issue
Block a user