Refactor and enhance zone and wall item management:
- Update zone handling in ZoneGroup to include selected zone visibility. - Improve camera transition speed in ZoneCentreTarget. - Add clearSelectedZone functionality in useZoneStore. - Integrate clearSelectedZone in KeyPressListener for ESCAPE key action. - Adjust sidebar and module toggle positioning for better UI layout. - Clean up unused code and comments in Project component.
This commit is contained in:
@@ -141,7 +141,7 @@ const DropDownList: React.FC<DropDownListProps> = ({
|
|||||||
value="Buildings"
|
value="Buildings"
|
||||||
showKebabMenu={false}
|
showKebabMenu={false}
|
||||||
showAddIcon={false}
|
showAddIcon={false}
|
||||||
items={zoneDataList}
|
// items={zoneDataList}
|
||||||
/>
|
/>
|
||||||
<DropDownList
|
<DropDownList
|
||||||
value="Zones"
|
value="Zones"
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
import { useFrame, useThree } from "@react-three/fiber";
|
import { useFrame, useThree } from "@react-three/fiber";
|
||||||
import { useAddAction, useDeleteTool, useRoofVisibility, useToggleView, useWallVisibility, useUpdateScene } from "../../../store/store";
|
import {
|
||||||
|
useAddAction,
|
||||||
|
useDeleteTool,
|
||||||
|
useRoofVisibility,
|
||||||
|
useToggleView,
|
||||||
|
useWallVisibility,
|
||||||
|
useUpdateScene,
|
||||||
|
} from "../../../store/store";
|
||||||
import hideRoof from "../geomentries/roofs/hideRoof";
|
import hideRoof from "../geomentries/roofs/hideRoof";
|
||||||
import hideWalls from "../geomentries/walls/hideWalls";
|
import hideWalls from "../geomentries/walls/hideWalls";
|
||||||
import addAndUpdateReferencePillar from "../geomentries/pillars/addAndUpdateReferencePillar";
|
import addAndUpdateReferencePillar from "../geomentries/pillars/addAndUpdateReferencePillar";
|
||||||
@@ -9,93 +16,97 @@ import DeletePillar from "../geomentries/pillars/deletePillar";
|
|||||||
import DeletableHoveredPillar from "../geomentries/pillars/deletableHoveredPillar";
|
import DeletableHoveredPillar from "../geomentries/pillars/deletableHoveredPillar";
|
||||||
import loadFloor from "../geomentries/floors/loadFloor";
|
import loadFloor from "../geomentries/floors/loadFloor";
|
||||||
|
|
||||||
const FloorGroup = ({ floorGroup, lines, referencePole, hoveredDeletablePillar }: any) => {
|
const FloorGroup = ({
|
||||||
const state = useThree();
|
floorGroup,
|
||||||
const { roofVisibility, setRoofVisibility } = useRoofVisibility();
|
lines,
|
||||||
const { wallVisibility, setWallVisibility } = useWallVisibility();
|
referencePole,
|
||||||
const { toggleView, setToggleView } = useToggleView();
|
hoveredDeletablePillar,
|
||||||
const { scene, camera, pointer, raycaster, gl } = useThree();
|
}: any) => {
|
||||||
const { addAction, setAddAction } = useAddAction();
|
const state = useThree();
|
||||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
const { roofVisibility } = useRoofVisibility();
|
||||||
const { updateScene, setUpdateScene } = useUpdateScene();
|
const { wallVisibility } = useWallVisibility();
|
||||||
|
const { toggleView } = useToggleView();
|
||||||
|
const { scene, camera, raycaster, gl } = useThree();
|
||||||
|
const { addAction } = useAddAction();
|
||||||
|
const { deleteTool } = useDeleteTool();
|
||||||
|
const { updateScene, setUpdateScene } = useUpdateScene();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (updateScene) {
|
if (updateScene) {
|
||||||
loadFloor(lines, floorGroup);
|
loadFloor(lines, floorGroup);
|
||||||
setUpdateScene(false);
|
setUpdateScene(false);
|
||||||
|
}
|
||||||
|
}, [updateScene]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!addAction) {
|
||||||
|
if (referencePole.current) {
|
||||||
|
(referencePole.current as any).material.dispose();
|
||||||
|
(referencePole.current.geometry as any).dispose();
|
||||||
|
floorGroup.current.remove(referencePole.current);
|
||||||
|
referencePole.current = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [addAction]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const canvasElement = gl.domElement;
|
||||||
|
let drag = false;
|
||||||
|
let isLeftMouseDown = false;
|
||||||
|
|
||||||
|
const onMouseDown = (evt: any) => {
|
||||||
|
if (evt.button === 0) {
|
||||||
|
isLeftMouseDown = true;
|
||||||
|
drag = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = (evt: any) => {
|
||||||
|
if (evt.button === 0) {
|
||||||
|
isLeftMouseDown = false;
|
||||||
|
if (!drag) {
|
||||||
|
if (addAction === "pillar") {
|
||||||
|
addPillar(referencePole, floorGroup);
|
||||||
|
}
|
||||||
|
if (deleteTool) {
|
||||||
|
DeletePillar(hoveredDeletablePillar, floorGroup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [updateScene])
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const onMouseMove = () => {
|
||||||
if (!addAction) {
|
if (isLeftMouseDown) {
|
||||||
if (referencePole.current) {
|
drag = true;
|
||||||
(referencePole.current as any).material.dispose();
|
}
|
||||||
(referencePole.current.geometry as any).dispose();
|
};
|
||||||
floorGroup.current.remove(referencePole.current);
|
|
||||||
referencePole.current = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [addAction]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||||
const canvasElement = gl.domElement;
|
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||||
let drag = false;
|
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||||
let isLeftMouseDown = false;
|
|
||||||
|
|
||||||
const onMouseDown = (evt: any) => {
|
return () => {
|
||||||
if (evt.button === 0) {
|
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||||
isLeftMouseDown = true;
|
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||||
drag = false;
|
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||||
}
|
};
|
||||||
};
|
}, [deleteTool, addAction]);
|
||||||
|
|
||||||
const onMouseUp = (evt: any) => {
|
useFrame(() => {
|
||||||
if (evt.button === 0) {
|
hideRoof(roofVisibility, floorGroup, camera);
|
||||||
isLeftMouseDown = false;
|
hideWalls(wallVisibility, scene, camera);
|
||||||
if (!drag) {
|
|
||||||
if (addAction === "pillar") {
|
|
||||||
addPillar(referencePole, floorGroup);
|
|
||||||
}
|
|
||||||
if (deleteTool) {
|
|
||||||
DeletePillar(hoveredDeletablePillar, floorGroup);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onMouseMove = () => {
|
if (addAction === "pillar") {
|
||||||
if (isLeftMouseDown) {
|
addAndUpdateReferencePillar(raycaster, floorGroup, referencePole);
|
||||||
drag = true;
|
}
|
||||||
}
|
if (deleteTool) {
|
||||||
};
|
DeletableHoveredPillar(state, floorGroup, hoveredDeletablePillar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
return (
|
||||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
<group ref={floorGroup} visible={!toggleView} name="floorGroup"></group>
|
||||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return () => {
|
export default FloorGroup;
|
||||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
|
||||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
|
||||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
|
||||||
};
|
|
||||||
}, [deleteTool, addAction])
|
|
||||||
|
|
||||||
useFrame(() => {
|
|
||||||
hideRoof(roofVisibility, floorGroup, camera);
|
|
||||||
hideWalls(wallVisibility, scene, camera);
|
|
||||||
|
|
||||||
if (addAction === "pillar") {
|
|
||||||
addAndUpdateReferencePillar(raycaster, floorGroup, referencePole);
|
|
||||||
}
|
|
||||||
if (deleteTool) {
|
|
||||||
DeletableHoveredPillar(state, floorGroup, hoveredDeletablePillar);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return (
|
|
||||||
<group ref={floorGroup} visible={!toggleView} name="floorGroup">
|
|
||||||
</group>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default FloorGroup;
|
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useDeleteTool, useDeletePointOrLine, useObjectPosition, useObjectRotation, useObjectScale, useSelectedWallItem, useSocketStore, useWallItems } from "../../../store/store";
|
import {
|
||||||
|
useDeleteTool,
|
||||||
|
useDeletePointOrLine,
|
||||||
|
useObjectPosition,
|
||||||
|
useObjectRotation,
|
||||||
|
useSelectedWallItem,
|
||||||
|
useSocketStore,
|
||||||
|
useWallItems,
|
||||||
|
} from "../../../store/store";
|
||||||
import { Csg } from "../csg/csg";
|
import { Csg } from "../csg/csg";
|
||||||
import * as Types from "../../../types/world/worldTypes";
|
import * as Types from "../../../types/world/worldTypes";
|
||||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||||
@@ -11,236 +19,277 @@ import loadInitialWallItems from "../IntialLoad/loadInitialWallItems";
|
|||||||
import AddWallItems from "../geomentries/walls/addWallItems";
|
import AddWallItems from "../geomentries/walls/addWallItems";
|
||||||
import useModuleStore from "../../../store/useModuleStore";
|
import useModuleStore from "../../../store/useModuleStore";
|
||||||
|
|
||||||
|
const WallItemsGroup = ({
|
||||||
|
currentWallItem,
|
||||||
|
AssetConfigurations,
|
||||||
|
hoveredDeletableWallItem,
|
||||||
|
selectedItemsIndex,
|
||||||
|
setSelectedItemsIndex,
|
||||||
|
CSGGroup,
|
||||||
|
}: any) => {
|
||||||
|
const state = useThree();
|
||||||
|
const { socket } = useSocketStore();
|
||||||
|
const { pointer, camera, raycaster } = state;
|
||||||
|
const { deleteTool } = useDeleteTool();
|
||||||
|
const { wallItems, setWallItems } = useWallItems();
|
||||||
|
const { setObjectPosition } = useObjectPosition();
|
||||||
|
const { setObjectRotation } = useObjectRotation();
|
||||||
|
const { deletePointOrLine } = useDeletePointOrLine();
|
||||||
|
const { setSelectedWallItem } = useSelectedWallItem();
|
||||||
|
const { activeModule } = useModuleStore();
|
||||||
|
|
||||||
const WallItemsGroup = ({ currentWallItem, AssetConfigurations, hoveredDeletableWallItem, selectedItemsIndex, setSelectedItemsIndex, CSGGroup }: any) => {
|
useEffect(() => {
|
||||||
const state = useThree();
|
// Load Wall Items from the backend
|
||||||
const { socket } = useSocketStore();
|
loadInitialWallItems(setWallItems, AssetConfigurations);
|
||||||
const { pointer, camera, raycaster } = state;
|
}, []);
|
||||||
const { deleteTool, setDeleteTool } = useDeleteTool();
|
|
||||||
const { wallItems, setWallItems } = useWallItems();
|
|
||||||
const { objectPosition, setObjectPosition } = useObjectPosition();
|
|
||||||
const { objectScale, setObjectScale } = useObjectScale();
|
|
||||||
const { objectRotation, setObjectRotation } = useObjectRotation();
|
|
||||||
const { deletePointOrLine, setDeletePointOrLine } = useDeletePointOrLine();
|
|
||||||
const { selectedWallItem, setSelectedWallItem } = useSelectedWallItem();
|
|
||||||
const { activeModule } = useModuleStore();
|
|
||||||
|
|
||||||
useEffect(() => {
|
////////// Update the Scale value changes in thewallItems State //////////
|
||||||
// Load Wall Items from the backend
|
|
||||||
loadInitialWallItems(setWallItems, AssetConfigurations);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
////////// Update the Position value changes in the selected item //////////
|
||||||
|
|
||||||
////////// Update the Scale value changes in thewallItems State //////////
|
////////// Update the Rotation value changes in the selected item //////////
|
||||||
|
|
||||||
////////// Update the Position value changes in the selected item //////////
|
useEffect(() => {
|
||||||
|
const canvasElement = state.gl.domElement;
|
||||||
|
function handlePointerMove(e: any) {
|
||||||
|
if (
|
||||||
|
selectedItemsIndex !== null &&
|
||||||
|
!deletePointOrLine &&
|
||||||
|
e.buttons === 1
|
||||||
|
) {
|
||||||
|
const Raycaster = state.raycaster;
|
||||||
|
const intersects = Raycaster.intersectObjects(
|
||||||
|
CSGGroup.current?.children[0].children!,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const Object = intersects.find((child) =>
|
||||||
|
child.object.name.includes("WallRaycastReference")
|
||||||
|
);
|
||||||
|
|
||||||
////////// Update the Rotation value changes in the selected item //////////
|
if (Object) {
|
||||||
|
(state.controls as any)!.enabled = false;
|
||||||
|
setWallItems((prevItems: any) => {
|
||||||
|
const updatedItems = [...prevItems];
|
||||||
|
let position: [number, number, number] = [0, 0, 0];
|
||||||
|
|
||||||
useEffect(() => {
|
if (updatedItems[selectedItemsIndex].type === "Fixed-Move") {
|
||||||
const canvasElement = state.gl.domElement;
|
position = [
|
||||||
function handlePointerMove(e: any) {
|
Object!.point.x,
|
||||||
if (selectedItemsIndex !== null && !deletePointOrLine && e.buttons === 1) {
|
Math.floor(Object!.point.y / CONSTANTS.wallConfig.height) *
|
||||||
const Raycaster = state.raycaster;
|
CONSTANTS.wallConfig.height,
|
||||||
const intersects = Raycaster.intersectObjects(CSGGroup.current?.children[0].children!, true);
|
Object!.point.z,
|
||||||
const Object = intersects.find((child) => child.object.name.includes("WallRaycastReference"));
|
];
|
||||||
|
} else if (updatedItems[selectedItemsIndex].type === "Free-Move") {
|
||||||
if (Object) {
|
position = [Object!.point.x, Object!.point.y, Object!.point.z];
|
||||||
(state.controls as any)!.enabled = false;
|
|
||||||
setWallItems((prevItems: any) => {
|
|
||||||
const updatedItems = [...prevItems];
|
|
||||||
let position: [number, number, number] = [0, 0, 0];
|
|
||||||
|
|
||||||
if (updatedItems[selectedItemsIndex].type === "Fixed-Move") {
|
|
||||||
position = [Object!.point.x, Math.floor(Object!.point.y / CONSTANTS.wallConfig.height) * CONSTANTS.wallConfig.height, Object!.point.z];
|
|
||||||
} else if (updatedItems[selectedItemsIndex].type === "Free-Move") {
|
|
||||||
position = [Object!.point.x, Object!.point.y, Object!.point.z];
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
setObjectPosition(new THREE.Vector3(...position));
|
|
||||||
setObjectRotation({
|
|
||||||
x: THREE.MathUtils.radToDeg(Object!.object.rotation.x),
|
|
||||||
y: THREE.MathUtils.radToDeg(Object!.object.rotation.y),
|
|
||||||
z: THREE.MathUtils.radToDeg(Object!.object.rotation.z),
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
updatedItems[selectedItemsIndex] = {
|
|
||||||
...updatedItems[selectedItemsIndex],
|
|
||||||
position: position,
|
|
||||||
quaternion: Object!.object.quaternion.clone() as Types.QuaternionType,
|
|
||||||
};
|
|
||||||
|
|
||||||
return updatedItems;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
setObjectPosition(new THREE.Vector3(...position));
|
||||||
|
setObjectRotation({
|
||||||
|
x: THREE.MathUtils.radToDeg(Object!.object.rotation.x),
|
||||||
|
y: THREE.MathUtils.radToDeg(Object!.object.rotation.y),
|
||||||
|
z: THREE.MathUtils.radToDeg(Object!.object.rotation.z),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
updatedItems[selectedItemsIndex] = {
|
||||||
|
...updatedItems[selectedItemsIndex],
|
||||||
|
position: position,
|
||||||
|
quaternion:
|
||||||
|
Object!.object.quaternion.clone() as Types.QuaternionType,
|
||||||
|
};
|
||||||
|
|
||||||
|
return updatedItems;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handlePointerUp() {
|
async function handlePointerUp() {
|
||||||
const Raycaster = state.raycaster;
|
const Raycaster = state.raycaster;
|
||||||
const intersects = Raycaster.intersectObjects(CSGGroup.current?.children[0].children!, true);
|
const intersects = Raycaster.intersectObjects(
|
||||||
const Object = intersects.find((child) => child.object.name.includes("WallRaycastReference"));
|
CSGGroup.current?.children[0].children!,
|
||||||
if (Object) {
|
true
|
||||||
if (selectedItemsIndex !== null) {
|
);
|
||||||
let currentItem: any = null;
|
const Object = intersects.find((child) =>
|
||||||
setWallItems((prevItems: any) => {
|
child.object.name.includes("WallRaycastReference")
|
||||||
const updatedItems = [...prevItems];
|
);
|
||||||
const WallItemsForStorage = updatedItems.map((item) => {
|
if (Object) {
|
||||||
const { model, ...rest } = item;
|
if (selectedItemsIndex !== null) {
|
||||||
return {
|
let currentItem: any = null;
|
||||||
...rest,
|
setWallItems((prevItems: any) => {
|
||||||
modelUuid: model?.uuid,
|
const updatedItems = [...prevItems];
|
||||||
};
|
const WallItemsForStorage = updatedItems.map((item) => {
|
||||||
});
|
const { model, ...rest } = item;
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
modelUuid: model?.uuid,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
currentItem = updatedItems[selectedItemsIndex];
|
currentItem = updatedItems[selectedItemsIndex];
|
||||||
localStorage.setItem("WallItems", JSON.stringify(WallItemsForStorage));
|
localStorage.setItem(
|
||||||
return updatedItems;
|
"WallItems",
|
||||||
});
|
JSON.stringify(WallItemsForStorage)
|
||||||
|
);
|
||||||
|
return updatedItems;
|
||||||
|
});
|
||||||
|
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
|
const email = localStorage.getItem("email");
|
||||||
|
const organization = email!.split("@")[1].split(".")[0];
|
||||||
|
|
||||||
const email = localStorage.getItem('email')
|
//REST
|
||||||
const organization = (email!.split("@")[1]).split(".")[0];
|
|
||||||
|
|
||||||
//REST
|
// await setWallItem(
|
||||||
|
// organization,
|
||||||
|
// currentItem?.model?.uuid,
|
||||||
|
// currentItem.modelName,
|
||||||
|
// currentItem.type!,
|
||||||
|
// currentItem.csgposition!,
|
||||||
|
// currentItem.csgscale!,
|
||||||
|
// currentItem.position,
|
||||||
|
// currentItem.quaternion,
|
||||||
|
// currentItem.scale!,
|
||||||
|
// )
|
||||||
|
|
||||||
// await setWallItem(
|
//SOCKET
|
||||||
// organization,
|
|
||||||
// currentItem?.model?.uuid,
|
|
||||||
// currentItem.modelName,
|
|
||||||
// currentItem.type!,
|
|
||||||
// currentItem.csgposition!,
|
|
||||||
// currentItem.csgscale!,
|
|
||||||
// currentItem.position,
|
|
||||||
// currentItem.quaternion,
|
|
||||||
// currentItem.scale!,
|
|
||||||
// )
|
|
||||||
|
|
||||||
//SOCKET
|
const data = {
|
||||||
|
organization: organization,
|
||||||
|
modelUuid: currentItem.model?.uuid!,
|
||||||
|
modelName: currentItem.modelName!,
|
||||||
|
type: currentItem.type!,
|
||||||
|
csgposition: currentItem.csgposition!,
|
||||||
|
csgscale: currentItem.csgscale!,
|
||||||
|
position: currentItem.position!,
|
||||||
|
quaternion: currentItem.quaternion,
|
||||||
|
scale: currentItem.scale!,
|
||||||
|
socketId: socket.id,
|
||||||
|
};
|
||||||
|
|
||||||
const data = {
|
socket.emit("v1:wallItems:set", data);
|
||||||
organization: organization,
|
}, 0);
|
||||||
modelUuid: currentItem.model?.uuid!,
|
(state.controls as any)!.enabled = true;
|
||||||
modelName: currentItem.modelName!,
|
|
||||||
type: currentItem.type!,
|
|
||||||
csgposition: currentItem.csgposition!,
|
|
||||||
csgscale: currentItem.csgscale!,
|
|
||||||
position: currentItem.position!,
|
|
||||||
quaternion: currentItem.quaternion,
|
|
||||||
scale: currentItem.scale!,
|
|
||||||
socketId: socket.id
|
|
||||||
}
|
|
||||||
|
|
||||||
socket.emit('v1:wallItems:set', data);
|
|
||||||
}, 0);
|
|
||||||
(state.controls as any)!.enabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
canvasElement.addEventListener("pointermove", handlePointerMove);
|
canvasElement.addEventListener("pointermove", handlePointerMove);
|
||||||
canvasElement.addEventListener("pointerup", handlePointerUp);
|
canvasElement.addEventListener("pointerup", handlePointerUp);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
canvasElement.removeEventListener("pointermove", handlePointerMove);
|
canvasElement.removeEventListener("pointermove", handlePointerMove);
|
||||||
canvasElement.removeEventListener("pointerup", handlePointerUp);
|
canvasElement.removeEventListener("pointerup", handlePointerUp);
|
||||||
};
|
};
|
||||||
}, [selectedItemsIndex]);
|
}, [selectedItemsIndex]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const canvasElement = state.gl.domElement;
|
const canvasElement = state.gl.domElement;
|
||||||
let drag = false;
|
let drag = false;
|
||||||
let isLeftMouseDown = false;
|
let isLeftMouseDown = false;
|
||||||
|
|
||||||
const onMouseDown = (evt: any) => {
|
const onMouseDown = (evt: any) => {
|
||||||
if (evt.button === 0) {
|
if (evt.button === 0) {
|
||||||
isLeftMouseDown = true;
|
isLeftMouseDown = true;
|
||||||
drag = false;
|
drag = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMouseUp = (evt: any) => {
|
const onMouseUp = (evt: any) => {
|
||||||
if (evt.button === 0) {
|
if (evt.button === 0) {
|
||||||
isLeftMouseDown = false;
|
isLeftMouseDown = false;
|
||||||
if (!drag && deleteTool && activeModule === "builder") {
|
if (!drag && deleteTool && activeModule === "builder") {
|
||||||
DeleteWallItems(hoveredDeletableWallItem, setWallItems, wallItems, socket);
|
DeleteWallItems(
|
||||||
}
|
hoveredDeletableWallItem,
|
||||||
}
|
setWallItems,
|
||||||
};
|
wallItems,
|
||||||
|
socket
|
||||||
const onMouseMove = () => {
|
);
|
||||||
if (isLeftMouseDown) {
|
|
||||||
drag = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onDrop = (event: any) => {
|
|
||||||
|
|
||||||
if (!event.dataTransfer?.files[0]) return
|
|
||||||
|
|
||||||
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
|
||||||
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
|
||||||
raycaster.setFromCamera(pointer, camera);
|
|
||||||
|
|
||||||
if (AssetConfigurations[(event.dataTransfer.files[0].name.split('.'))[0]]) {
|
|
||||||
const selected = (event.dataTransfer.files[0].name.split('.'))[0];
|
|
||||||
|
|
||||||
if (AssetConfigurations[selected]?.type) {
|
|
||||||
AddWallItems(selected, raycaster, CSGGroup, AssetConfigurations, setWallItems, socket);
|
|
||||||
}
|
|
||||||
event.preventDefault();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const onDragOver = (event: any) => {
|
const onMouseMove = () => {
|
||||||
event.preventDefault();
|
if (isLeftMouseDown) {
|
||||||
};
|
drag = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
const onDrop = (event: any) => {
|
||||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
if (!event.dataTransfer?.files[0]) return;
|
||||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
|
||||||
canvasElement.addEventListener("drop", onDrop);
|
|
||||||
canvasElement.addEventListener("dragover", onDragOver);
|
|
||||||
|
|
||||||
return () => {
|
pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||||
canvasElement.removeEventListener("mousedown", onMouseDown);
|
pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||||
canvasElement.removeEventListener("mouseup", onMouseUp);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
canvasElement.removeEventListener("mousemove", onMouseMove);
|
|
||||||
canvasElement.removeEventListener("drop", onDrop);
|
|
||||||
canvasElement.removeEventListener("dragover", onDragOver);
|
|
||||||
};
|
|
||||||
}, [deleteTool, wallItems])
|
|
||||||
|
|
||||||
useEffect(() => {
|
if (AssetConfigurations[event.dataTransfer.files[0].name.split(".")[0]]) {
|
||||||
if (deleteTool && activeModule === "builder") {
|
const selected = event.dataTransfer.files[0].name.split(".")[0];
|
||||||
handleMeshMissed(currentWallItem, setSelectedWallItem, setSelectedItemsIndex);
|
|
||||||
setSelectedWallItem(null);
|
if (AssetConfigurations[selected]?.type) {
|
||||||
setSelectedItemsIndex(null);
|
AddWallItems(
|
||||||
|
selected,
|
||||||
|
raycaster,
|
||||||
|
CSGGroup,
|
||||||
|
AssetConfigurations,
|
||||||
|
setWallItems,
|
||||||
|
socket
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}, [deleteTool])
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
const onDragOver = (event: any) => {
|
||||||
<>
|
event.preventDefault();
|
||||||
{wallItems.map((item: Types.WallItem, index: number) => (
|
};
|
||||||
<group
|
|
||||||
key={index}
|
|
||||||
position={item.position}
|
|
||||||
quaternion={item.quaternion}
|
|
||||||
scale={item.scale}
|
|
||||||
>
|
|
||||||
<Csg
|
|
||||||
position={item.csgposition!}
|
|
||||||
scale={item.csgscale!}
|
|
||||||
model={item.model!}
|
|
||||||
hoveredDeletableWallItem={hoveredDeletableWallItem}
|
|
||||||
/>
|
|
||||||
</group>
|
|
||||||
))}
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default WallItemsGroup;
|
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||||
|
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||||
|
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||||
|
canvasElement.addEventListener("drop", onDrop);
|
||||||
|
canvasElement.addEventListener("dragover", onDragOver);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
canvasElement.removeEventListener("mousedown", onMouseDown);
|
||||||
|
canvasElement.removeEventListener("mouseup", onMouseUp);
|
||||||
|
canvasElement.removeEventListener("mousemove", onMouseMove);
|
||||||
|
canvasElement.removeEventListener("drop", onDrop);
|
||||||
|
canvasElement.removeEventListener("dragover", onDragOver);
|
||||||
|
};
|
||||||
|
}, [deleteTool, wallItems]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (deleteTool && activeModule === "builder") {
|
||||||
|
handleMeshMissed(
|
||||||
|
currentWallItem,
|
||||||
|
setSelectedWallItem,
|
||||||
|
setSelectedItemsIndex
|
||||||
|
);
|
||||||
|
setSelectedWallItem(null);
|
||||||
|
setSelectedItemsIndex(null);
|
||||||
|
}
|
||||||
|
}, [deleteTool]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{wallItems.map((item: Types.WallItem, index: number) => (
|
||||||
|
<group
|
||||||
|
key={index}
|
||||||
|
position={item.position}
|
||||||
|
quaternion={item.quaternion}
|
||||||
|
scale={item.scale}
|
||||||
|
>
|
||||||
|
<Csg
|
||||||
|
position={item.csgposition!}
|
||||||
|
scale={item.csgscale!}
|
||||||
|
model={item.model!}
|
||||||
|
hoveredDeletableWallItem={hoveredDeletableWallItem}
|
||||||
|
/>
|
||||||
|
</group>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default WallItemsGroup;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
import { getZonesApi } from "../../../services/factoryBuilder/zones/getZonesApi";
|
||||||
|
|
||||||
import * as CONSTANTS from "../../../types/world/worldConstants";
|
import * as CONSTANTS from "../../../types/world/worldConstants";
|
||||||
|
import { useSelectedZoneStore } from "../../../store/visualization/useZoneStore";
|
||||||
|
|
||||||
const ZoneGroup: React.FC = () => {
|
const ZoneGroup: React.FC = () => {
|
||||||
const { camera, pointer, gl, raycaster, scene, controls } = useThree();
|
const { camera, pointer, gl, raycaster, scene, controls } = useThree();
|
||||||
@@ -24,6 +25,7 @@ const ZoneGroup: React.FC = () => {
|
|||||||
const { zones, setZones } = useZones();
|
const { zones, setZones } = useZones();
|
||||||
const { zonePoints, setZonePoints } = useZonePoints();
|
const { zonePoints, setZonePoints } = useZonePoints();
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
|
const { selectedZone } = useSelectedZoneStore();
|
||||||
const [draggedSphere, setDraggedSphere] = useState<THREE.Vector3 | null>(
|
const [draggedSphere, setDraggedSphere] = useState<THREE.Vector3 | null>(
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
@@ -308,7 +310,7 @@ const ZoneGroup: React.FC = () => {
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
if (intersects.length > 0 && toolMode === 'move') {
|
if (intersects.length > 0 && toolMode === "move") {
|
||||||
const clickedObject = intersects[0].object;
|
const clickedObject = intersects[0].object;
|
||||||
const sphereIndex = zonePoints.findIndex((point: any) =>
|
const sphereIndex = zonePoints.findIndex((point: any) =>
|
||||||
point.equals(clickedObject.position)
|
point.equals(clickedObject.position)
|
||||||
@@ -326,7 +328,7 @@ const ZoneGroup: React.FC = () => {
|
|||||||
if (evt.button === 0 && !drag && !isDragging && !deletePointOrLine) {
|
if (evt.button === 0 && !drag && !isDragging && !deletePointOrLine) {
|
||||||
isLeftMouseDown = false;
|
isLeftMouseDown = false;
|
||||||
|
|
||||||
if (!startPoint && toolMode !== 'move') {
|
if (!startPoint && toolMode !== "move") {
|
||||||
raycaster.setFromCamera(pointer, camera);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
const intersectionPoint = new THREE.Vector3();
|
const intersectionPoint = new THREE.Vector3();
|
||||||
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
@@ -334,7 +336,7 @@ const ZoneGroup: React.FC = () => {
|
|||||||
setStartPoint(point);
|
setStartPoint(point);
|
||||||
setEndPoint(null);
|
setEndPoint(null);
|
||||||
}
|
}
|
||||||
} else if (startPoint && toolMode !== 'move') {
|
} else if (startPoint && toolMode !== "move") {
|
||||||
raycaster.setFromCamera(pointer, camera);
|
raycaster.setFromCamera(pointer, camera);
|
||||||
const intersectionPoint = new THREE.Vector3();
|
const intersectionPoint = new THREE.Vector3();
|
||||||
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
const point = raycaster.ray.intersectPlane(plane, intersectionPoint);
|
||||||
@@ -436,7 +438,8 @@ const ZoneGroup: React.FC = () => {
|
|||||||
intersects.length > 0 &&
|
intersects.length > 0 &&
|
||||||
intersects[0].object.name.includes("point")
|
intersects[0].object.name.includes("point")
|
||||||
) {
|
) {
|
||||||
gl.domElement.style.cursor = toolMode === 'move' ? "pointer" : "default";
|
gl.domElement.style.cursor =
|
||||||
|
toolMode === "move" ? "pointer" : "default";
|
||||||
} else {
|
} else {
|
||||||
gl.domElement.style.cursor = "default";
|
gl.domElement.style.cursor = "default";
|
||||||
}
|
}
|
||||||
@@ -476,7 +479,7 @@ const ZoneGroup: React.FC = () => {
|
|||||||
setEndPoint(null);
|
setEndPoint(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (toolMode === "Zone" || deletePointOrLine || toolMode === 'move') {
|
if (toolMode === "Zone" || deletePointOrLine || toolMode === "move") {
|
||||||
canvasElement.addEventListener("mousedown", onMouseDown);
|
canvasElement.addEventListener("mousedown", onMouseDown);
|
||||||
canvasElement.addEventListener("mouseup", onMouseUp);
|
canvasElement.addEventListener("mouseup", onMouseUp);
|
||||||
canvasElement.addEventListener("mousemove", onMouseMove);
|
canvasElement.addEventListener("mousemove", onMouseMove);
|
||||||
@@ -526,7 +529,11 @@ const ZoneGroup: React.FC = () => {
|
|||||||
<group ref={groupsRef} name="zoneGroup">
|
<group ref={groupsRef} name="zoneGroup">
|
||||||
<group name="zones" visible={!toggleView}>
|
<group name="zones" visible={!toggleView}>
|
||||||
{zones.map((zone: any) => (
|
{zones.map((zone: any) => (
|
||||||
<group key={zone.zoneId} name={zone.zoneName} visible={false}>
|
<group
|
||||||
|
key={zone.zoneId}
|
||||||
|
name={zone.zoneName}
|
||||||
|
visible={zone.zoneName === selectedZone.zoneName}
|
||||||
|
>
|
||||||
{zone.points
|
{zone.points
|
||||||
.slice(0, -1)
|
.slice(0, -1)
|
||||||
.map((point: [number, number, number], index: number) => {
|
.map((point: [number, number, number], index: number) => {
|
||||||
@@ -545,7 +552,7 @@ const ZoneGroup: React.FC = () => {
|
|||||||
const midpoint = new THREE.Vector3(
|
const midpoint = new THREE.Vector3(
|
||||||
(point1.x + point2.x) / 2,
|
(point1.x + point2.x) / 2,
|
||||||
CONSTANTS.zoneConfig.height / 2 +
|
CONSTANTS.zoneConfig.height / 2 +
|
||||||
(zone.layer - 1) * CONSTANTS.zoneConfig.height,
|
(zone.layer - 1) * CONSTANTS.zoneConfig.height,
|
||||||
(point1.z + point2.z) / 2
|
(point1.z + point2.z) / 2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ export default function ZoneCentreTarget() {
|
|||||||
const { setZoneTarget } = usezoneTarget();
|
const { setZoneTarget } = usezoneTarget();
|
||||||
const { Edit } = useEditPosition();
|
const { Edit } = useEditPosition();
|
||||||
|
|
||||||
|
const TRANSITION_SPEED = 2000;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
selectedZone.zoneViewPortTarget &&
|
selectedZone.zoneViewPortTarget &&
|
||||||
@@ -50,30 +52,29 @@ export default function ZoneCentreTarget() {
|
|||||||
const setCam = async () => {
|
const setCam = async () => {
|
||||||
controls.setLookAt(
|
controls.setLookAt(
|
||||||
centrePoint[0],
|
centrePoint[0],
|
||||||
100,
|
26,
|
||||||
centrePoint[2],
|
centrePoint[2],
|
||||||
...centrePoint,
|
...centrePoint,
|
||||||
true
|
true,
|
||||||
|
TRANSITION_SPEED
|
||||||
);
|
);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
controls?.setLookAt(
|
controls?.setLookAt(
|
||||||
...selectedZone.zoneViewPortPosition,
|
...selectedZone.zoneViewPortPosition,
|
||||||
selectedZone.zoneViewPortTarget[0],
|
...selectedZone.zoneViewPortTarget,
|
||||||
selectedZone.zoneViewPortTarget[1],
|
true,
|
||||||
selectedZone.zoneViewPortTarget[2],
|
TRANSITION_SPEED
|
||||||
true
|
|
||||||
);
|
);
|
||||||
}, 400);
|
}, 100);
|
||||||
};
|
};
|
||||||
setCam();
|
setCam();
|
||||||
} else {
|
} else {
|
||||||
const setCam = async () => {
|
const setCam = async () => {
|
||||||
controls?.setLookAt(
|
controls?.setLookAt(
|
||||||
...selectedZone.zoneViewPortPosition,
|
...selectedZone.zoneViewPortPosition,
|
||||||
selectedZone.zoneViewPortTarget[0],
|
...selectedZone.zoneViewPortTarget,
|
||||||
selectedZone.zoneViewPortTarget[1],
|
true,
|
||||||
selectedZone.zoneViewPortTarget[2],
|
TRANSITION_SPEED
|
||||||
true
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
setCam();
|
setCam();
|
||||||
|
|||||||
@@ -136,26 +136,3 @@ const Project: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default Project;
|
export default Project;
|
||||||
|
|
||||||
// src/global.d.ts
|
|
||||||
// import { LogType } from "../components/ui/log/LoggerContext";
|
|
||||||
|
|
||||||
// export declare global {
|
|
||||||
// const echo: {
|
|
||||||
// log: (message: string) => void;
|
|
||||||
// info: (message: string) => void;
|
|
||||||
// warn: (message: string) => void;
|
|
||||||
// error: (message: string) => void;
|
|
||||||
// success: (message: string) => void;
|
|
||||||
// clear: () => void;
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Project.tsx:61 Uncaught ReferenceError: echo is not defined
|
|
||||||
// at Project.tsx:61:1
|
|
||||||
// at commitHookEffectListMount (react-dom.development.js:23189:1)
|
|
||||||
// at commitPassiveMountOnFiber (react-dom.development.js:24965:1)
|
|
||||||
// at commitPassiveMountEffects_complete (react-dom.development.js:24930:1)
|
|
||||||
// at commitPassiveMountEffects_begin (react-dom.development.js:24917:1)
|
|
||||||
// at commitPassiveMountEffects (react-dom.development.js:24905:1)
|
|
||||||
// this error occurs some time's
|
|
||||||
|
|||||||
@@ -29,25 +29,40 @@ interface SelectedZoneStore {
|
|||||||
| Partial<SelectedZoneState>
|
| Partial<SelectedZoneState>
|
||||||
| ((prev: SelectedZoneState) => SelectedZoneState)
|
| ((prev: SelectedZoneState) => SelectedZoneState)
|
||||||
) => void;
|
) => void;
|
||||||
|
clearSelectedZone: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
export const useSelectedZoneStore = create<SelectedZoneStore>((set) => ({
|
||||||
selectedZone: {
|
selectedZone: {
|
||||||
zoneName: "", // Empty string initially
|
zoneName: "",
|
||||||
activeSides: [], // Empty array
|
activeSides: [],
|
||||||
panelOrder: [], // Empty array
|
panelOrder: [],
|
||||||
lockedPanels: [], // Empty array
|
lockedPanels: [],
|
||||||
points: [],
|
points: [],
|
||||||
zoneId: "",
|
zoneId: "",
|
||||||
zoneViewPortTarget: [],
|
zoneViewPortTarget: [],
|
||||||
zoneViewPortPosition: [],
|
zoneViewPortPosition: [],
|
||||||
widgets: [], // Empty array
|
widgets: [],
|
||||||
},
|
},
|
||||||
setSelectedZone: (zone) =>
|
setSelectedZone: (zone) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
selectedZone:
|
selectedZone:
|
||||||
typeof zone === "function"
|
typeof zone === "function"
|
||||||
? zone(state.selectedZone) // Handle functional updates
|
? zone(state.selectedZone)
|
||||||
: { ...state.selectedZone, ...zone }, // Handle partial updates
|
: { ...state.selectedZone, ...zone },
|
||||||
|
})),
|
||||||
|
clearSelectedZone: () =>
|
||||||
|
set(() => ({
|
||||||
|
selectedZone: {
|
||||||
|
zoneName: "",
|
||||||
|
activeSides: [],
|
||||||
|
panelOrder: [],
|
||||||
|
lockedPanels: [],
|
||||||
|
points: [],
|
||||||
|
zoneId: "",
|
||||||
|
zoneViewPortTarget: [],
|
||||||
|
zoneViewPortPosition: [],
|
||||||
|
widgets: [],
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
gap: 8px;
|
gap: 8px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
top: 32px;
|
top: 22px;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
z-index: #{$z-index-tools};
|
z-index: #{$z-index-tools};
|
||||||
.module-list {
|
.module-list {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
.sidebar-left-wrapper {
|
.sidebar-left-wrapper {
|
||||||
width: 270px;
|
width: 270px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 32px;
|
top: 22px;
|
||||||
left: 8px;
|
left: 8px;
|
||||||
background: var(--background-color);
|
background: var(--background-color);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
@@ -280,7 +280,7 @@
|
|||||||
.sidebar-right-wrapper {
|
.sidebar-right-wrapper {
|
||||||
width: 320px;
|
width: 320px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 32px;
|
top: 22px;
|
||||||
right: 8px;
|
right: 8px;
|
||||||
background: var(--background-color);
|
background: var(--background-color);
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
} from "../../store/store";
|
} from "../../store/store";
|
||||||
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
|
import { usePlayButtonStore } from "../../store/usePlayButtonStore";
|
||||||
import { detectModifierKeys } from "./detectModifierKeys";
|
import { detectModifierKeys } from "./detectModifierKeys";
|
||||||
|
import { useSelectedZoneStore } from "../../store/visualization/useZoneStore";
|
||||||
|
|
||||||
const KeyPressListener: React.FC = () => {
|
const KeyPressListener: React.FC = () => {
|
||||||
const { activeModule, setActiveModule } = useModuleStore();
|
const { activeModule, setActiveModule } = useModuleStore();
|
||||||
@@ -25,6 +26,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
const { setAddAction } = useAddAction();
|
const { setAddAction } = useAddAction();
|
||||||
const { setSelectedWallItem } = useSelectedWallItem();
|
const { setSelectedWallItem } = useSelectedWallItem();
|
||||||
const { setActiveTool } = useActiveTool();
|
const { setActiveTool } = useActiveTool();
|
||||||
|
const { clearSelectedZone} = useSelectedZoneStore();
|
||||||
|
|
||||||
const isTextInput = (element: Element | null): boolean =>
|
const isTextInput = (element: Element | null): boolean =>
|
||||||
element instanceof HTMLInputElement ||
|
element instanceof HTMLInputElement ||
|
||||||
@@ -131,6 +133,7 @@ const KeyPressListener: React.FC = () => {
|
|||||||
if (keyCombination === "ESCAPE") {
|
if (keyCombination === "ESCAPE") {
|
||||||
setActiveTool("cursor");
|
setActiveTool("cursor");
|
||||||
setIsPlaying(false);
|
setIsPlaying(false);
|
||||||
|
clearSelectedZone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Placeholder for future implementation
|
// Placeholder for future implementation
|
||||||
|
|||||||
Reference in New Issue
Block a user