Skip to content

Commit b8e4cf2

Browse files
authored
Merge pull request #54 from ut-code/fix-simulation-issues
Fix simulation issues
2 parents 340fd0d + 1ee7011 commit b8e4cf2

27 files changed

+3665
-3866
lines changed

package-lock.json

Lines changed: 2972 additions & 2948 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@mui/icons-material": "^6.3.0",
1919
"@mui/material": "^6.3.0",
2020
"eventemitter3": "^5.0.1",
21+
"lodash-es": "^4.17.21",
2122
"memoize-one": "^6.0.0",
2223
"mnemonist": "^0.39.8",
2324
"nullthrows": "^1.1.1",
@@ -31,6 +32,7 @@
3132
"devDependencies": {
3233
"@biomejs/biome": "^1.9.4",
3334
"@tsconfig/strictest": "^2.0.5",
35+
"@types/lodash-es": "^4.17.12",
3436
"@types/react": "^19.0.2",
3537
"@types/react-dom": "^19.0.2",
3638
"@vitejs/plugin-react": "^4.3.4",

src/common/theme.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
import { createTheme } from "@mui/material";
22

33
// See https://www.figma.com/file/M3dC0Gk98IGSGlxY901rBh/
4-
export const blackColor = "#000000";
5-
export const whiteColor = "#ffffff";
6-
export const primaryColor = "#009966";
7-
export const errorColor = "#ff0000";
8-
export const editorBackgroundColor = "#fafafa";
9-
export const editorGridColor = "#dddddd";
4+
export const theme = {
5+
palette: {
6+
black: "#000000",
7+
white: "#ffffff",
8+
textPrimary: "#444444",
9+
primary: "#009966",
10+
error: "#ff0000",
11+
editorBackground: "#fafafa",
12+
editorGrid: "#dddddd",
13+
},
14+
};
1015

11-
export const theme = createTheme({
16+
export const muiTheme = createTheme({
1217
palette: {
13-
primary: { main: primaryColor },
18+
primary: { main: theme.palette.primary },
1419
},
1520
});

src/common/vector2.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ export const vector2 = {
1818
x: a.x / b,
1919
y: a.y / b,
2020
}),
21+
size: (a: Vector2): number => Math.hypot(a.x, a.y),
22+
distance: (a: Vector2, b: Vector2): number => vector2.size(vector2.sub(a, b)),
2123
fromDomEvent: (e: { offsetX: number; offsetY: number }): Vector2 => ({
2224
x: e.offsetX,
2325
y: e.offsetY,

src/components/GlobalHeader.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AppBar } from "@mui/material";
22
import type { CSSProperties } from "react";
3-
import { whiteColor } from "../common/theme";
3+
import { theme } from "../common/theme";
44

55
export type GlobalHeaderProps = {
66
style: CSSProperties;
@@ -15,7 +15,7 @@ export default function GlobalHeader({ style }: GlobalHeaderProps) {
1515
style={style}
1616
sx={{
1717
p: 2,
18-
background: whiteColor,
18+
background: theme.palette.white,
1919
borderBottom: "1px solid",
2020
borderColor: "divider",
2121
}}

src/hooks/drag.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { type PointerEvent, useRef } from "react";
2+
import { type Vector2, vector2 } from "../common/vector2";
3+
4+
const DRAG_THRESHOLD = 5;
5+
6+
export type UseDraggableProps = {
7+
onClick?(e: PointerEvent): void;
8+
onDragStart?(e: PointerEvent): void;
9+
onDrag?(e: PointerEvent): void;
10+
onDragEnd?(e: PointerEvent): void;
11+
};
12+
13+
export function useDraggable(props: UseDraggableProps) {
14+
const { onClick, onDragStart, onDrag, onDragEnd } = props;
15+
16+
const dragStateRef = useRef<{
17+
pointerId: number;
18+
initialPosition: Vector2;
19+
isDragging: boolean;
20+
} | null>(null);
21+
22+
return {
23+
onPointerDown: (e: PointerEvent) => {
24+
if (!(e.buttons & 1)) return;
25+
dragStateRef.current = {
26+
pointerId: e.pointerId,
27+
initialPosition: vector2.fromDomEvent(e.nativeEvent),
28+
isDragging: false,
29+
};
30+
onDragStart?.(e);
31+
e.currentTarget.setPointerCapture(e.pointerId);
32+
},
33+
onPointerMove: (e: PointerEvent) => {
34+
if (!dragStateRef.current) return;
35+
if (dragStateRef.current.pointerId !== e.pointerId) return;
36+
if (dragStateRef.current.isDragging) {
37+
onDrag?.(e);
38+
return;
39+
}
40+
41+
const currentPosition = vector2.fromDomEvent(e.nativeEvent);
42+
const distance = vector2.distance(
43+
dragStateRef.current.initialPosition,
44+
currentPosition,
45+
);
46+
if (distance > DRAG_THRESHOLD) {
47+
dragStateRef.current.isDragging = true;
48+
onDragStart?.(e);
49+
onDrag?.(e);
50+
}
51+
},
52+
onPointerUp: (e: PointerEvent) => {
53+
if (!dragStateRef.current) return;
54+
if (dragStateRef.current.pointerId !== e.pointerId) return;
55+
e.currentTarget.releasePointerCapture(e.pointerId);
56+
},
57+
onLostPointerCapture: (e: PointerEvent) => {
58+
if (!dragStateRef.current) return;
59+
if (dragStateRef.current.isDragging) onDragEnd?.(e);
60+
else onClick?.(e);
61+
dragStateRef.current = null;
62+
},
63+
};
64+
}

src/main.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import React from "react";
33
import ReactDOM from "react-dom/client";
44
import App from "./App";
55
import "./index.css";
6-
import { theme } from "./common/theme";
6+
import { muiTheme } from "./common/theme";
77
import { StoreProvider } from "./store/react";
88

99
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
1010
<React.StrictMode>
1111
<StoreProvider>
12-
<ThemeProvider theme={theme}>
12+
<ThemeProvider theme={muiTheme}>
1313
<App />
1414
</ThemeProvider>
1515
</StoreProvider>

src/pages/edit/Editor/components/Grid.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { ReactElement } from "react";
2+
import { theme } from "../../../../common/theme";
23
import { vector2 } from "../../../../common/vector2";
34
import { useComponentEditorStore } from "../store";
45

@@ -8,7 +9,7 @@ export default function CCComponentEditorGrid() {
89
const canvasOriginPosition = componentEditorState.fromStageToCanvas(
910
vector2.zero,
1011
);
11-
const canvasGridSize = 100 * 2 ** (Math.ceil(logScale) - logScale);
12+
const canvasGridSize = 80 * 2 ** (Math.ceil(logScale) - logScale);
1213

1314
const elements: ReactElement[] = [];
1415
let i = 0;
@@ -26,7 +27,7 @@ export default function CCComponentEditorGrid() {
2627
left: 0,
2728
width: "1px",
2829
height: "100%",
29-
backgroundColor: "rgba(0, 0, 0, 0.1)",
30+
backgroundColor: theme.palette.editorGrid,
3031
transform: `translateX(${x}px)`,
3132
}}
3233
/>,
@@ -47,7 +48,7 @@ export default function CCComponentEditorGrid() {
4748
left: 0,
4849
width: "100%",
4950
height: "1px",
50-
backgroundColor: "rgba(0, 0, 0, 0.1)",
51+
backgroundColor: theme.palette.editorGrid,
5152
transform: `translateY(${y}px)`,
5253
}}
5354
/>,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export function CCComponentEditorNodePinPropertyEditor() {}

src/pages/edit/Editor/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Box } from "@mui/material";
22
import nullthrows from "nullthrows";
33
import { useState } from "react";
4-
import { editorBackgroundColor } from "../../../common/theme";
4+
import { theme } from "../../../common/theme";
55
import { ComponentPropertyDialog } from "../../../components/ComponentPropertyDialog";
66
import type { CCComponentId } from "../../../store/component";
77
import { useStore } from "../../../store/react";
@@ -33,7 +33,7 @@ function CCComponentEditorContent({
3333
sx={{
3434
position: "relative",
3535
overflow: "hidden",
36-
backgroundColor: editorBackgroundColor,
36+
backgroundColor: theme.palette.editorBackground,
3737
}}
3838
>
3939
<CCComponentEditorGrid />

0 commit comments

Comments
 (0)