diff --git a/package.json b/package.json index de4f817..eeb57b7 100644 --- a/package.json +++ b/package.json @@ -39,8 +39,8 @@ "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts", "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts", "lint": "concurrently \"npm run eslint\" \"npm run fs-lint\"", - "eslint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx", - "lint:fix": "cross-env NODE_ENV=development eslint . --fix --ext .js,.jsx,.ts,.tsx", + "eslint": "cross-env NODE_ENV=development eslint ./src --ext .js,.jsx,.ts,.tsx", + "lint:fix": "cross-env NODE_ENV=development eslint ./src --fix --ext .js,.jsx,.ts,.tsx", "fs-lint": "cross-env fs-lint", "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never", "prepare": "husky install", diff --git a/src/renderer/constants/routes.ts b/src/renderer/constants/routes.ts index fa3e36d..cdec84c 100644 --- a/src/renderer/constants/routes.ts +++ b/src/renderer/constants/routes.ts @@ -10,5 +10,6 @@ export default { COLUMNS_2D: '/modelling-ui-poc/columns-2d', COLUMN_SYSTEM: '/modelling-ui-poc/column-system', COLUMN_GROUP: '/modelling-ui-poc/column-group', + COLUMN_SELECT: '/modelling-ui-poc/column-select', }, }; diff --git a/src/renderer/pages/modelling-ui-poc/column-select/column-select.tsx b/src/renderer/pages/modelling-ui-poc/column-select/column-select.tsx new file mode 100644 index 0000000..284cf11 --- /dev/null +++ b/src/renderer/pages/modelling-ui-poc/column-select/column-select.tsx @@ -0,0 +1,201 @@ +import { useEffect } from 'react'; +import { + WebGLRenderer, + OrthographicCamera, + Scene, + Color, + Vector2, + Raycaster, +} from 'three'; +import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'; +import invariant from 'tiny-invariant'; +import { + InfiniteGrid, + ModelGrid, + ColumnsGroup, +} from 'renderer/three/components'; +import { CSS3DRenderer } from 'three/examples/jsm/renderers/CSS3DRenderer'; +import { COLORS } from 'renderer/constants'; + +const ColumnGroup = () => { + useEffect(() => { + const scene = new Scene(); + const webglContainerEl = document.querySelector('.webgl-wrapper'); + invariant(webglContainerEl, 'could not find container tag'); + const camera = new OrthographicCamera( + -webglContainerEl.clientWidth / 2, + webglContainerEl.clientWidth / 2, + webglContainerEl.clientHeight / 2, + -webglContainerEl.clientHeight / 2, + 0.1, + 1000 + ); + const mouse = new Vector2(); + const raycaster = new Raycaster(); + + function hoverPointer() { + raycaster.setFromCamera(mouse, camera); + const intersects = raycaster.intersectObjects(scene.children); + for (let i = 0; i < intersects.length; i += 1) { + const intObject = intersects[i].object as any; + if (intObject.name === 'column') { + intObject.material.color?.set(COLORS.NOTICE_SOFT_yellow); + } + } + } + + function onPointerMove(event: any) { + // calculate pointer position in normalized device coordinates + // (-1 to +1) for both components + if (!webglContainerEl) return null; + const clientRects = webglContainerEl.getBoundingClientRect(); + const myCoordx = event.clientX - clientRects.x; + const myCoordy = event.clientY - clientRects.y; + mouse.x = (myCoordx / clientRects.width) * 2 - 1; + mouse.y = -(myCoordy / clientRects.height) * 2 + 1; + hoverPointer(); + return null; + } + + const renderer = new WebGLRenderer({ alpha: true }); + renderer.setSize( + webglContainerEl.clientWidth, + webglContainerEl.clientHeight + ); + + webglContainerEl.appendChild(renderer.domElement); + + const cssContainerEl = document.querySelector('.css-wrapper'); + invariant(cssContainerEl, 'could not find container tag'); + + const cssRenderer = new CSS3DRenderer(); + cssRenderer.setSize( + cssContainerEl.clientWidth, + cssContainerEl.clientHeight + ); + + cssContainerEl.appendChild(cssRenderer.domElement); + + const controls = new OrbitControls(camera, renderer.domElement); + const cssControls = new OrbitControls(camera, cssRenderer.domElement); + + controls.enableRotate = false; + cssControls.enableRotate = false; + + camera.position.set(0, 0, 10); + controls.update(); + cssControls.update(); + + scene.background = new Color(COLORS.GRAY_DARK); + + const grid = new InfiniteGrid({ + spacingX: 10, + spacingY: 10, + color: new Color(COLORS.GRAY_SOFT), + distance: 2000, + }); + + grid.position.set(0, 0, -0.0001); // little tweak to make sure the grid stays behind all objects + + // scene.add(grid); + + const modelGrid = new ModelGrid({ + disposition: { + x: [ + { + label: 'A', + + coordinate: 0, + }, + { + label: 'B', + coordinate: 12.5, + }, + { + label: 'C', + coordinate: 17.5, + }, + ], + y: [ + { + label: '1', + coordinate: 0, + }, + { + label: '2', + coordinate: 7.5, + }, + { + label: '3', + coordinate: 15, + }, + ], + }, + containerEl: cssContainerEl, + }); + + const columns = [ + { + width: 2, + height: 2, + coorX: 15, + coorY: 17.5, + color: COLORS.NOTICE_SOFT_yellow, + }, + { + width: 2, + height: 2, + coorX: 0, + coorY: 5, + color: COLORS.NOTICE_RED, + }, + { + width: 1, + height: 3, + coorX: 0, + coorY: 10, + color: COLORS.NOTICE_RED, + }, + { + width: 2, + height: 4, + coorX: 5, + coorY: 0, + color: COLORS.NOTICE_RED, + }, + { + width: 2, + height: 1, + coorX: 10, + coorY: 0, + color: COLORS.NOTICE_RED, + }, + ]; + scene.add(modelGrid.object3D); + const columnGroup = ColumnsGroup({ columns }); + scene.add(columnGroup); + + window.addEventListener('click', onPointerMove, false); + function animate() { + requestAnimationFrame(animate); + controls.update(); + // cssControls.update(); + // cssRenderer.render(scene, camera); + renderer.render(scene, camera); + } + animate(); + }, []); + + return ( +
+

column Group

+ +
+
+
+
+
+ ); +}; + +export default ColumnGroup; diff --git a/src/renderer/pages/modelling-ui-poc/column-select/index.ts b/src/renderer/pages/modelling-ui-poc/column-select/index.ts new file mode 100644 index 0000000..425ceb7 --- /dev/null +++ b/src/renderer/pages/modelling-ui-poc/column-select/index.ts @@ -0,0 +1 @@ +export { default } from './column-select'; diff --git a/src/renderer/pages/modelling-ui-poc/index.ts b/src/renderer/pages/modelling-ui-poc/index.ts index 26b190e..4bd0a5b 100644 --- a/src/renderer/pages/modelling-ui-poc/index.ts +++ b/src/renderer/pages/modelling-ui-poc/index.ts @@ -9,3 +9,4 @@ export { default as Ucs } from './ucs'; export { default as Columns2D } from './columns-2d'; export { default as ColumnSystem } from './column-system'; export { default as ColumnGroup } from './column-group'; +export { default as ColumnSelect } from './column-select'; diff --git a/src/renderer/pages/modelling-ui-poc/modelling-ui-poc.tsx b/src/renderer/pages/modelling-ui-poc/modelling-ui-poc.tsx index 78bd639..1c8dfdc 100644 --- a/src/renderer/pages/modelling-ui-poc/modelling-ui-poc.tsx +++ b/src/renderer/pages/modelling-ui-poc/modelling-ui-poc.tsx @@ -59,6 +59,12 @@ const ModellingUiPoc = () => { > Columns Group + + Columns Select +
); diff --git a/src/renderer/routes/app-router/app-router.tsx b/src/renderer/routes/app-router/app-router.tsx index 2117362..87e4acd 100644 --- a/src/renderer/routes/app-router/app-router.tsx +++ b/src/renderer/routes/app-router/app-router.tsx @@ -9,6 +9,7 @@ import { GridSystem, ColumnSystem, ColumnGroup, + ColumnSelect, Ucs, Columns2D, } from 'renderer/pages/modelling-ui-poc'; @@ -52,6 +53,10 @@ const AppRouter = () => { path={ROUTES.MODELLING_UI_POC.COLUMN_GROUP} element={} /> + } + /> ); diff --git a/src/renderer/three/components/column/column.ts b/src/renderer/three/components/column/column.ts index 19da257..915b9ff 100644 --- a/src/renderer/three/components/column/column.ts +++ b/src/renderer/three/components/column/column.ts @@ -7,6 +7,7 @@ const Column = ({ width, height, coorX, coorY, color }: ColumnOptions) => { const geometry = new BoxGeometry(width, height, 0); const material = new MeshBasicMaterial({ color }); const square = new Mesh(geometry, material); + square.name = 'column'; square.position.set(coorX, coorY, 0); return square;