diff --git a/app/components/Button.tsx b/app/components/Button.tsx index 16955dec9e..8b78cc5d87 100644 --- a/app/components/Button.tsx +++ b/app/components/Button.tsx @@ -33,14 +33,14 @@ export const Button = ({ } const className = twMerge( - "text-sm font-semibold rounded-md px-3 py-2 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 transition-all duration-150", + "text-sm font-semibold rounded-md px-3 py-2 shadow-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 transition-all duration-150 flex gap-2 items-center", getVariantClassNames(variant), propsClassName, ); return ( ); diff --git a/app/components/Input.tsx b/app/components/Input.tsx index a9704e6dbb..18554df835 100644 --- a/app/components/Input.tsx +++ b/app/components/Input.tsx @@ -13,13 +13,7 @@ export function Input({ label, className, ...rest }: InputProps) { )} (e.currentTarget.style.outlineColor = "#e66462")} - onBlur={(e) => (e.currentTarget.style.outlineColor = "transparent")} + className="h-10 rounded-md bg-brand-secondary p-3 text-white transition-all duration-150 ease-in-out outline-none outline-offset-0 focus:outline-brand-primary" {...rest} /> diff --git a/app/components/InputVector.tsx b/app/components/InputVector.tsx new file mode 100644 index 0000000000..cf0df1934f --- /dev/null +++ b/app/components/InputVector.tsx @@ -0,0 +1,65 @@ +import { useRef } from "react"; +import { twMerge } from "tailwind-merge"; + + +interface InputVectorProps { + x: number; + y: number; + z: number; + onChange : (v:{ + x:number; + y:number; + z:number; + })=>void; +} + +export const InputVector = ({ + x,y,z, + onChange +}:InputVectorProps)=>{ + const xRef = useRef(null); + const yRef = useRef(null); + const zRef = useRef(null); + + const inputCommonClasses ="relative w-14 h-8 rounded-r-md bg-brand-secondary p-3 text-base text-white transition-all duration-150 ease-in-out outline-none -outline-offset-2 "; + + const wrapperCommonClasses = "flex items-center before:inline-block before:w-10 before:h-10 before:bg-brand-primary before:text-white before:rounded-l-md before:h-8 before:w-4 before:text-center before:align-middle before:leading-8 text-xs"; + + function handleOnChange(){ + const newVector = { + x: Number(xRef.current?.value), + y: Number(yRef.current?.value), + z: Number(zRef.current?.value), + } + onChange(newVector); + } + return( +
+ + + + + + + + + +
+ ); +} \ No newline at end of file diff --git a/app/components/index.tsx b/app/components/index.tsx index 323db7b12c..d3c627d58c 100644 --- a/app/components/index.tsx +++ b/app/components/index.tsx @@ -3,6 +3,7 @@ import { ButtonIcon } from "./ButtonIcon"; import { ButtonLink } from "./ButtonLink"; import { ButtonIconSelect } from "./ButtonIconSelect"; import { Input } from "./Input"; +import { InputVector } from "./InputVector"; import { H1, H2, H3, H4, H5, H6, P, Label} from "./Typography"; import { ItemPicker } from "./ItemPicker"; import { Textarea } from "./Textarea"; @@ -18,6 +19,7 @@ export { ItemPicker, Textarea, Input, + InputVector, LoadingBar, LoadingDots, LoadingDotsBricks, diff --git a/app/pages/PageEnigma/PageEnigmaComponent.tsx b/app/pages/PageEnigma/PageEnigmaComponent.tsx index 30b68687e8..55ac9143b8 100644 --- a/app/pages/PageEnigma/PageEnigmaComponent.tsx +++ b/app/pages/PageEnigma/PageEnigmaComponent.tsx @@ -5,12 +5,16 @@ import { faSparkles } from "@fortawesome/pro-solid-svg-icons"; import { Button, LoadingBar, LoadingDots } from "~/components"; import { TopBarHelmet } from "~/modules/TopBarHelmet/TopBarHelmet"; import { SidePanel } from "~/modules/SidePanel"; + import { Controls3D } from "./comps/Controls3D"; import { ControlsTopButtons } from "./comps/ControlsTopButtons"; import { ControlsVideo } from "./comps/ControlsVideo"; +import { ControlPanelSceneObject } from "./comps/ControlPanelSceneObject"; import { PreviewEngineCamera } from "./comps/PreviewEngineCamera"; -import { Timeline } from "./comps/Timeline"; +import { ViewSideBySide } from "./comps/ViewSideBySide"; import { SidePanelTabs } from "./comps/SidePanelTabs"; +import { Timeline } from "./comps/Timeline"; + import { EngineProvider } from "./contexts/EngineProvider"; import { AppUIProvider } from "./contexts/AppUiContext"; @@ -19,7 +23,6 @@ import { appUiInitialStateValues, APPUI_VIEW_MODES, } from "./reducers"; -import { ViewSideBySide } from "./comps/ViewSideBySide"; import { canDrop, clipLength, @@ -52,7 +55,7 @@ export const PageEnigmaComponent = () => {
{/* Engine section/side panel */}
@@ -78,6 +81,7 @@ export const PageEnigmaComponent = () => {
+
{appUiState.viewMode === APPUI_VIEW_MODES.SIDE_BY_SIDE && ( diff --git a/app/pages/PageEnigma/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx b/app/pages/PageEnigma/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx new file mode 100644 index 0000000000..976b902743 --- /dev/null +++ b/app/pages/PageEnigma/comps/ControlPanelSceneObject/ControlPanelSceneObject.tsx @@ -0,0 +1,117 @@ +import { useContext } from 'react'; +import { Transition } from "@headlessui/react"; +import { faArrowRightArrowLeft, faCube, faTrash} from "@fortawesome/pro-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; + +import { AppUiContext } from '../../contexts/AppUiContext'; +import { Button, H4, H6, InputVector } from "~/components"; + +import { XYZ } from '../../datastructures/common'; +import { ACTION_TYPES } from '../../reducers/appUiReducer/types'; + + + +export const ControlPanelSceneObject = () => { + const [appUiState, dispatchAppUiState ] = useContext(AppUiContext); + + const position = appUiState?.currentSceneObject.objectVectors.position; + const rotation = appUiState?.currentSceneObject.objectVectors.rotation; + const scalar = appUiState?.currentSceneObject.objectVectors.scalar; + + const handlePositionChange = (xyz:XYZ)=>{ + if(appUiState) + dispatchAppUiState({ + type: ACTION_TYPES.UPDATE_CONTROLPANELS_SCENEOBJECT, + payload:{ + currentSceneObject:{ + objectVectors:{ + position: {...xyz}, + rotation: appUiState.currentSceneObject.objectVectors.rotation, + scalar:appUiState.currentSceneObject.objectVectors.scalar, + } + } + } + }); + } + const handleRotationChange = (xyz:XYZ)=>{ + if(appUiState) + dispatchAppUiState({ + type: ACTION_TYPES.UPDATE_CONTROLPANELS_SCENEOBJECT, + payload:{ + currentSceneObject:{ + objectVectors:{ + position: appUiState.currentSceneObject.objectVectors.position, + rotation: {...xyz}, + scalar:appUiState.currentSceneObject.objectVectors.scalar, + } + } + } + }); + } + const handleScalarChange = (xyz:XYZ)=>{ + if(appUiState) + dispatchAppUiState({ + type: ACTION_TYPES.UPDATE_CONTROLPANELS_SCENEOBJECT, + payload:{ + currentSceneObject:{ + objectVectors:{ + position: appUiState.currentSceneObject.objectVectors.position, + rotation: appUiState.currentSceneObject.objectVectors.rotation, + scalar:{...xyz}, + } + } + } + }); + } + + return( + +
+
+ +

Object Name

+
+
+ +
Swap Object
+
+
+ +

Position

+ +

Rotation

+ +

Scale

+ + +
+ +
+
+ ); +} \ No newline at end of file diff --git a/app/pages/PageEnigma/comps/ControlPanelSceneObject/index.tsx b/app/pages/PageEnigma/comps/ControlPanelSceneObject/index.tsx new file mode 100644 index 0000000000..455b4b8534 --- /dev/null +++ b/app/pages/PageEnigma/comps/ControlPanelSceneObject/index.tsx @@ -0,0 +1 @@ +export { ControlPanelSceneObject } from './ControlPanelSceneObject'; \ No newline at end of file diff --git a/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx b/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx index 01670a0220..02a95bc58d 100644 --- a/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx +++ b/app/pages/PageEnigma/comps/ControlsTopButtons/ControlsTopButtons.tsx @@ -21,15 +21,6 @@ export const ControlsTopButtons = () => { editorEngine?.loadScene(sceneToken); }; - - const handleButtonCameraView = () => { - editorEngine?.switchCameraView(); - }; - - const handleButtonPlayBack = () => { - editorEngine?.startPlayback(); - }; - const handleButtonTest = () => { if(appUiState?.showEditorLoadingBar.isShowing){ //TO GO TO A HUNDRED AND DISAPPER @@ -71,10 +62,33 @@ export const ControlsTopButtons = () => { } }; - //const handleButtonRender = () => { - // editorEngine?.take_timeline_cam_clip(); - //}; + const handleObjectPanelTest = () => { + if (appUiState?.currentSceneObject.isShowing) { + dispatchAppUiState({ + type: APPUI_ACTION_TYPES.HIDE_CONTROLPANELS_SCENEOBJECT + }); + }else{ + dispatchAppUiState({ + type:APPUI_ACTION_TYPES.SHOW_CONTROLPANELS_SCENEOBJECT, + payload:{ + currentSceneObject:{ + objectVectors: { + position: {x:1,y:2,z:3}, + rotation: {x:4,y:5,z:6}, + scalar: {x:7,y:8,z:9}, + } + } + } + }); + } + } + const handleButtonCameraView = () => { + editorEngine?.switchCameraView(); + }; + const handleButtonPlayBack = () => { + editorEngine?.startPlayback(); + }; const handleButtonRender = () => { editorEngine?.generateVideo(); }; @@ -83,12 +97,7 @@ export const ControlsTopButtons = () => { editorEngine?.take_timeline_cam_clip(); }; - // const handleButtonCameraView = () => { - // editorEngine?.change_camera_view(); - // }; - const handleButtonLoad = () => {}; - // const handleButtonRender = () => {}; return (
@@ -147,6 +156,12 @@ export const ControlsTopButtons = () => { +
diff --git a/app/pages/PageEnigma/datastructures/common.ts b/app/pages/PageEnigma/datastructures/common.ts new file mode 100644 index 0000000000..5d6c4d1889 --- /dev/null +++ b/app/pages/PageEnigma/datastructures/common.ts @@ -0,0 +1,11 @@ +export type XYZ = { + x :number; + y: number; + z: number; +} + +export type Simple3DVector = { + position: XYZ; + rotation: XYZ; + scalar: XYZ; +} \ No newline at end of file diff --git a/app/pages/PageEnigma/reducers/appUiReducer/reducer.tsx b/app/pages/PageEnigma/reducers/appUiReducer/reducer.tsx index c632ebfef2..e95d3bb301 100644 --- a/app/pages/PageEnigma/reducers/appUiReducer/reducer.tsx +++ b/app/pages/PageEnigma/reducers/appUiReducer/reducer.tsx @@ -2,6 +2,33 @@ import { State, Action, ACTION_TYPES} from './types'; export function reducer(state: State, action: Action): State { switch(action.type){ + case ACTION_TYPES.SHOW_CONTROLPANELS_SCENEOBJECT:{ + return{ + ...state, + currentSceneObject: { + isShowing: true, + objectVectors: {...action.payload.currentSceneObject.objectVectors}, + }, + } + } + case ACTION_TYPES.UPDATE_CONTROLPANELS_SCENEOBJECT:{ + return{ + ...state, + currentSceneObject: { + isShowing: state.currentSceneObject.isShowing, + objectVectors: {...action.payload.currentSceneObject.objectVectors}, + }, + } + } + case ACTION_TYPES.HIDE_CONTROLPANELS_SCENEOBJECT:{ + return{ + ...state, + currentSceneObject: { + isShowing: false, + objectVectors: state.currentSceneObject.objectVectors, + }, + } + } case ACTION_TYPES.SHOW_EDITOR_LOADER:{ return{ ...state, diff --git a/app/pages/PageEnigma/reducers/appUiReducer/types.tsx b/app/pages/PageEnigma/reducers/appUiReducer/types.tsx index 5e07b24b3f..6772ea4d2c 100644 --- a/app/pages/PageEnigma/reducers/appUiReducer/types.tsx +++ b/app/pages/PageEnigma/reducers/appUiReducer/types.tsx @@ -1,3 +1,4 @@ +import { Simple3DVector } from "../../datastructures/common"; export enum VIEW_MODES { EDITOR = 'editor', SIDE_BY_SIDE = 'side-by-side' @@ -19,6 +20,10 @@ export type State = { progress?: number; useFakeTimer?: number; } + currentSceneObject:{ + isShowing: boolean; + objectVectors: Simple3DVector; + } }; @@ -30,9 +35,29 @@ export enum ACTION_TYPES { SHOW_EDITOR_LOADINGBAR = "show_editor_loadingbar", UPDATE_EDITOR_LOADINGBAR = "update_editor_loadingbar", HIDE_EDITOR_LOADINGBAR = "hide_editor_loadingbar", + SHOW_CONTROLPANELS_SCENEOBJECT = "show_controlpanels_sceneobject", + UPDATE_CONTROLPANELS_SCENEOBJECT = "update_controlpanels_sceneobject", + HIDE_CONTROLPANELS_SCENEOBJECT = "hide_controlpanels_sceneobject", }; -export type Action = +export type Action = + | {type: ACTION_TYPES.HIDE_CONTROLPANELS_SCENEOBJECT} + | { + type: ACTION_TYPES.UPDATE_CONTROLPANELS_SCENEOBJECT, + payload:{ + currentSceneObject: { + objectVectors: Simple3DVector; + }; + } + } + | { + type: ACTION_TYPES.SHOW_CONTROLPANELS_SCENEOBJECT, + payload:{ + currentSceneObject: { + objectVectors: Simple3DVector; + }; + } + } | {type: ACTION_TYPES.HIDE_EDITOR_LOADER,} | { type: ACTION_TYPES.SHOW_EDITOR_LOADER, diff --git a/app/pages/PageEnigma/reducers/appUiReducer/values.tsx b/app/pages/PageEnigma/reducers/appUiReducer/values.tsx index b62b819a6f..e69a9a313a 100644 --- a/app/pages/PageEnigma/reducers/appUiReducer/values.tsx +++ b/app/pages/PageEnigma/reducers/appUiReducer/values.tsx @@ -11,5 +11,13 @@ export const initialStateValues : State = { isShowing:true, progress:5, message: 'Loading Editor Engine 🦊' + }, + currentSceneObject:{ + isShowing:false, + objectVectors:{ + position:{x:0,y:0,z:0}, + rotation:{x:0,y:0,z:0}, + scalar:{x:0,y:0,z:0}, + } } } \ No newline at end of file diff --git a/tailwind.config.ts b/tailwind.config.ts index 482b42e119..2583148f3f 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -126,9 +126,16 @@ export default { "ui-controls-button": "#676781", "ui-divider": "#515168", + "axis-x" :"#D33242", + "axis-y" :"#308752", + "axis-z" :"#2E70FF", + red: "#D33242", + green:"#308752", + blue: "#2E70FF", + + white: colors.white, gray: colors.gray, black: colors.black, - white: colors.white, }, }, plugins: [],