clean branch-scoped code quality issues
This commit is contained in:
@@ -31,6 +31,20 @@ interface EditorControlsProps {
|
||||
isPlayerMode?: boolean;
|
||||
}
|
||||
|
||||
const TRANSFORM_OPTIONS = [
|
||||
{ mode: "translate", label: "Translate", shortcut: "T", Icon: Move3D },
|
||||
{ mode: "rotate", label: "Rotate", shortcut: "R", Icon: RotateCw },
|
||||
{ mode: "scale", label: "Scale", shortcut: "S", Icon: Expand },
|
||||
] as const;
|
||||
|
||||
const EDITOR_SHORTCUTS = [
|
||||
["Click", "Select object"],
|
||||
["T / R / S", "Transform mode"],
|
||||
["Ctrl Z / Y", "Undo / redo"],
|
||||
["Esc", "Deselect"],
|
||||
["WASD", "Move when locked"],
|
||||
] as const;
|
||||
|
||||
export function EditorControls({
|
||||
transformMode,
|
||||
onTransformModeChange,
|
||||
@@ -69,33 +83,18 @@ export function EditorControls({
|
||||
</div>
|
||||
|
||||
<div className="editor-transform-buttons">
|
||||
<button
|
||||
className={`editor-transform-button ${transformMode === "translate" ? "active" : ""}`}
|
||||
onClick={() => onTransformModeChange("translate")}
|
||||
aria-pressed={transformMode === "translate"}
|
||||
>
|
||||
<Move3D size={16} aria-hidden="true" />
|
||||
<span>Translate</span>
|
||||
<kbd>T</kbd>
|
||||
</button>
|
||||
<button
|
||||
className={`editor-transform-button ${transformMode === "rotate" ? "active" : ""}`}
|
||||
onClick={() => onTransformModeChange("rotate")}
|
||||
aria-pressed={transformMode === "rotate"}
|
||||
>
|
||||
<RotateCw size={16} aria-hidden="true" />
|
||||
<span>Rotate</span>
|
||||
<kbd>R</kbd>
|
||||
</button>
|
||||
<button
|
||||
className={`editor-transform-button ${transformMode === "scale" ? "active" : ""}`}
|
||||
onClick={() => onTransformModeChange("scale")}
|
||||
aria-pressed={transformMode === "scale"}
|
||||
>
|
||||
<Expand size={16} aria-hidden="true" />
|
||||
<span>Scale</span>
|
||||
<kbd>S</kbd>
|
||||
</button>
|
||||
{TRANSFORM_OPTIONS.map(({ mode, label, shortcut, Icon }) => (
|
||||
<button
|
||||
key={mode}
|
||||
className={`editor-transform-button ${transformMode === mode ? "active" : ""}`}
|
||||
onClick={() => onTransformModeChange(mode)}
|
||||
aria-pressed={transformMode === mode}
|
||||
>
|
||||
<Icon size={16} aria-hidden="true" />
|
||||
<span>{label}</span>
|
||||
<kbd>{shortcut}</kbd>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="editor-history-buttons">
|
||||
@@ -203,26 +202,12 @@ export function EditorControls({
|
||||
</div>
|
||||
|
||||
<dl className="editor-shortcuts-list">
|
||||
<div>
|
||||
<dt>Click</dt>
|
||||
<dd>Select object</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>T / R / S</dt>
|
||||
<dd>Transform mode</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Ctrl Z / Y</dt>
|
||||
<dd>Undo / redo</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>Esc</dt>
|
||||
<dd>Deselect</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>WASD</dt>
|
||||
<dd>Move when locked</dd>
|
||||
</div>
|
||||
{EDITOR_SHORTCUTS.map(([keys, description]) => (
|
||||
<div key={keys}>
|
||||
<dt>{keys}</dt>
|
||||
<dd>{description}</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -29,6 +29,12 @@ interface EditorNodeCommonProps {
|
||||
onHoverNode: (index: number | null) => void;
|
||||
}
|
||||
|
||||
interface EditorNodePointerHandlers {
|
||||
onClick: (event: ThreeEvent<MouseEvent>) => void;
|
||||
onPointerEnter: (event: ThreeEvent<PointerEvent>) => void;
|
||||
onPointerLeave: (event: ThreeEvent<PointerEvent>) => void;
|
||||
}
|
||||
|
||||
function applyNodeTransform(object: THREE.Object3D, node: MapNode): void {
|
||||
object.position.set(...node.position);
|
||||
object.rotation.set(...node.rotation);
|
||||
@@ -88,6 +94,36 @@ function cloneHighlightedMaterial(
|
||||
return clone;
|
||||
}
|
||||
|
||||
function getNodeHighlightColor(
|
||||
isSelected: boolean,
|
||||
isHovered: boolean,
|
||||
): string | null {
|
||||
if (isSelected) return "#ffffff";
|
||||
if (isHovered) return "#b8b8b8";
|
||||
return null;
|
||||
}
|
||||
|
||||
function createEditorNodePointerHandlers(
|
||||
index: number,
|
||||
onSelectNode: (index: number | null) => void,
|
||||
onHoverNode: (index: number | null) => void,
|
||||
): EditorNodePointerHandlers {
|
||||
return {
|
||||
onClick: (event) => {
|
||||
event.stopPropagation();
|
||||
onSelectNode(index);
|
||||
},
|
||||
onPointerEnter: (event) => {
|
||||
event.stopPropagation();
|
||||
onHoverNode(index);
|
||||
},
|
||||
onPointerLeave: (event) => {
|
||||
event.stopPropagation();
|
||||
onHoverNode(null);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function EditorMap({
|
||||
sceneData,
|
||||
selectedNodeIndex,
|
||||
@@ -224,15 +260,16 @@ function EditorModelNode({
|
||||
const { scene } = useGLTF(modelUrl);
|
||||
|
||||
const sceneInstance = useMemo(() => scene.clone(true), [scene]);
|
||||
const pointerHandlers = createEditorNodePointerHandlers(
|
||||
index,
|
||||
onSelectNode,
|
||||
onHoverNode,
|
||||
);
|
||||
useRegisteredEditorNode(groupRef, index, node, objectsMapRef);
|
||||
|
||||
useEffect(() => {
|
||||
if (!groupRef.current) return;
|
||||
const highlightColor = isSelected
|
||||
? "#ffffff"
|
||||
: isHovered
|
||||
? "#b8b8b8"
|
||||
: null;
|
||||
const highlightColor = getNodeHighlightColor(isSelected, isHovered);
|
||||
|
||||
groupRef.current.traverse((child) => {
|
||||
if (!(child instanceof THREE.Mesh)) {
|
||||
@@ -288,18 +325,7 @@ function EditorModelNode({
|
||||
position={node.position}
|
||||
rotation={node.rotation}
|
||||
scale={node.scale}
|
||||
onClick={(e: ThreeEvent<MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
onSelectNode(index);
|
||||
}}
|
||||
onPointerEnter={(e: ThreeEvent<PointerEvent>) => {
|
||||
e.stopPropagation();
|
||||
onHoverNode(index);
|
||||
}}
|
||||
onPointerLeave={(e: ThreeEvent<PointerEvent>) => {
|
||||
e.stopPropagation();
|
||||
onHoverNode(null);
|
||||
}}
|
||||
{...pointerHandlers}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -314,9 +340,14 @@ function EditorFallbackNode({
|
||||
onHoverNode,
|
||||
}: EditorNodeCommonProps) {
|
||||
const meshRef = useRef<THREE.Mesh>(null);
|
||||
const pointerHandlers = createEditorNodePointerHandlers(
|
||||
index,
|
||||
onSelectNode,
|
||||
onHoverNode,
|
||||
);
|
||||
useRegisteredEditorNode(meshRef, index, node, objectsMapRef);
|
||||
|
||||
const color = isSelected ? "#ffffff" : isHovered ? "#b8b8b8" : "#6f6f6f";
|
||||
const color = getNodeHighlightColor(isSelected, isHovered) ?? "#6f6f6f";
|
||||
|
||||
return (
|
||||
<mesh
|
||||
@@ -324,18 +355,7 @@ function EditorFallbackNode({
|
||||
position={node.position}
|
||||
rotation={node.rotation}
|
||||
scale={node.scale}
|
||||
onClick={(e: ThreeEvent<MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
onSelectNode(index);
|
||||
}}
|
||||
onPointerEnter={(e: ThreeEvent<PointerEvent>) => {
|
||||
e.stopPropagation();
|
||||
onHoverNode(index);
|
||||
}}
|
||||
onPointerLeave={(e: ThreeEvent<PointerEvent>) => {
|
||||
e.stopPropagation();
|
||||
onHoverNode(null);
|
||||
}}
|
||||
{...pointerHandlers}
|
||||
>
|
||||
<boxGeometry args={[1, 1, 1]} />
|
||||
<meshStandardMaterial color={color} />
|
||||
|
||||
Reference in New Issue
Block a user