updates UI
This commit is contained in:
Generated
+343
-9
@@ -1,16 +1,19 @@
|
||||
{
|
||||
"name": "new",
|
||||
"name": "lego-builder",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "new",
|
||||
"name": "lego-builder",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@radix-ui/colors": "^0.1.8",
|
||||
"@radix-ui/colors": "^2.0.1",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-slider": "^1.1.2",
|
||||
"@radix-ui/react-toggle-group": "^1.0.4",
|
||||
"@react-three/drei": "^9.80.2",
|
||||
"@react-three/fiber": "^8.13.6",
|
||||
"framer-motion": "^10.15.1",
|
||||
@@ -18,6 +21,7 @@
|
||||
"leva": "^0.9.35",
|
||||
"r3f-perf": "^7.1.2",
|
||||
"react": "^18.2.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"three": "^0.155.0",
|
||||
"use-keyboard-shortcut": "^1.1.6",
|
||||
@@ -1017,9 +1021,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/colors": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-0.1.8.tgz",
|
||||
"integrity": "sha512-jwRMXYwC0hUo0mv6wGpuw254Pd9p/R6Td5xsRpOmaWkUHlooNWqVcadgyzlRumMq3xfOTXwJReU0Jv+EIy4Jbw=="
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-2.0.1.tgz",
|
||||
"integrity": "sha512-EhWky2oSIf5y+BDfrAY+Rykrkh7m2/M/bgCVRr3M+Hnr4JOh+mtFZLHUS1j/WzaPw1uvd0vwhK3cbxsR0QnCgw=="
|
||||
},
|
||||
"node_modules/@radix-ui/number": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz",
|
||||
"integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/primitive": {
|
||||
"version": "1.0.1",
|
||||
@@ -1052,6 +1064,62 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-checkbox": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz",
|
||||
"integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-presence": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||
"@radix-ui/react-use-previous": "1.0.1",
|
||||
"@radix-ui/react-use-size": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-collection": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
|
||||
"integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-slot": "1.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-compose-refs": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
|
||||
@@ -1122,6 +1190,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-direction": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
|
||||
"integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-dismissable-layer": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz",
|
||||
@@ -1319,6 +1404,70 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-roving-focus": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
|
||||
"integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-collection": "1.0.3",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-direction": "1.0.1",
|
||||
"@radix-ui/react-id": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-callback-ref": "1.0.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-slider": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.1.2.tgz",
|
||||
"integrity": "sha512-NKs15MJylfzVsCagVSWKhGGLNR1W9qWs+HtgbmjjVUB3B9+lb3PYoXxVju3kOrpf0VKyVCtZp+iTwVoqpa1Chw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/number": "1.0.1",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-collection": "1.0.3",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-direction": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.0.1",
|
||||
"@radix-ui/react-use-previous": "1.0.1",
|
||||
"@radix-ui/react-use-size": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-slot": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
|
||||
@@ -1337,6 +1486,60 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-toggle": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz",
|
||||
"integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-toggle-group": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz",
|
||||
"integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-direction": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-roving-focus": "1.0.4",
|
||||
"@radix-ui/react-toggle": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-tooltip": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.6.tgz",
|
||||
@@ -1441,6 +1644,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-previous": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz",
|
||||
"integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-rect": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
|
||||
@@ -5902,9 +6122,17 @@
|
||||
}
|
||||
},
|
||||
"@radix-ui/colors": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-0.1.8.tgz",
|
||||
"integrity": "sha512-jwRMXYwC0hUo0mv6wGpuw254Pd9p/R6Td5xsRpOmaWkUHlooNWqVcadgyzlRumMq3xfOTXwJReU0Jv+EIy4Jbw=="
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-2.0.1.tgz",
|
||||
"integrity": "sha512-EhWky2oSIf5y+BDfrAY+Rykrkh7m2/M/bgCVRr3M+Hnr4JOh+mtFZLHUS1j/WzaPw1uvd0vwhK3cbxsR0QnCgw=="
|
||||
},
|
||||
"@radix-ui/number": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz",
|
||||
"integrity": "sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
}
|
||||
},
|
||||
"@radix-ui/primitive": {
|
||||
"version": "1.0.1",
|
||||
@@ -5923,6 +6151,34 @@
|
||||
"@radix-ui/react-primitive": "1.0.3"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-checkbox": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.0.4.tgz",
|
||||
"integrity": "sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-presence": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||
"@radix-ui/react-use-previous": "1.0.1",
|
||||
"@radix-ui/react-use-size": "1.0.1"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-collection": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.3.tgz",
|
||||
"integrity": "sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-slot": "1.0.2"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-compose-refs": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz",
|
||||
@@ -5961,6 +6217,14 @@
|
||||
"react-remove-scroll": "2.5.5"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-direction": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
|
||||
"integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-dismissable-layer": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.4.tgz",
|
||||
@@ -6054,6 +6318,42 @@
|
||||
"@radix-ui/react-slot": "1.0.2"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-roving-focus": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.4.tgz",
|
||||
"integrity": "sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-collection": "1.0.3",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-direction": "1.0.1",
|
||||
"@radix-ui/react-id": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-callback-ref": "1.0.1",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-slider": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.1.2.tgz",
|
||||
"integrity": "sha512-NKs15MJylfzVsCagVSWKhGGLNR1W9qWs+HtgbmjjVUB3B9+lb3PYoXxVju3kOrpf0VKyVCtZp+iTwVoqpa1Chw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/number": "1.0.1",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-collection": "1.0.3",
|
||||
"@radix-ui/react-compose-refs": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-direction": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1",
|
||||
"@radix-ui/react-use-layout-effect": "1.0.1",
|
||||
"@radix-ui/react-use-previous": "1.0.1",
|
||||
"@radix-ui/react-use-size": "1.0.1"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-slot": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz",
|
||||
@@ -6063,6 +6363,32 @@
|
||||
"@radix-ui/react-compose-refs": "1.0.1"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-toggle": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.0.3.tgz",
|
||||
"integrity": "sha512-Pkqg3+Bc98ftZGsl60CLANXQBBQ4W3mTFS9EJvNxKMZ7magklKV69/id1mlAlOFDDfHvlCms0fx8fA4CMKDJHg==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-toggle-group": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.0.4.tgz",
|
||||
"integrity": "sha512-Uaj/M/cMyiyT9Bx6fOZO0SAG4Cls0GptBWiBmBxofmDbNVnYYoyRWj/2M/6VCi/7qcXFWnHhRUfdfZFvvkuu8A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10",
|
||||
"@radix-ui/primitive": "1.0.1",
|
||||
"@radix-ui/react-context": "1.0.1",
|
||||
"@radix-ui/react-direction": "1.0.1",
|
||||
"@radix-ui/react-primitive": "1.0.3",
|
||||
"@radix-ui/react-roving-focus": "1.0.4",
|
||||
"@radix-ui/react-toggle": "1.0.3",
|
||||
"@radix-ui/react-use-controllable-state": "1.0.1"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-tooltip": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.6.tgz",
|
||||
@@ -6117,6 +6443,14 @@
|
||||
"@babel/runtime": "^7.13.10"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-use-previous": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz",
|
||||
"integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.13.10"
|
||||
}
|
||||
},
|
||||
"@radix-ui/react-use-rect": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz",
|
||||
|
||||
+6
-2
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "new",
|
||||
"name": "lego-builder",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
@@ -10,9 +10,12 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/colors": "^0.1.8",
|
||||
"@radix-ui/colors": "^2.0.1",
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-dialog": "^1.0.4",
|
||||
"@radix-ui/react-icons": "^1.3.0",
|
||||
"@radix-ui/react-slider": "^1.1.2",
|
||||
"@radix-ui/react-toggle-group": "^1.0.4",
|
||||
"@react-three/drei": "^9.80.2",
|
||||
"@react-three/fiber": "^8.13.6",
|
||||
"framer-motion": "^10.15.1",
|
||||
@@ -20,6 +23,7 @@
|
||||
"leva": "^0.9.35",
|
||||
"r3f-perf": "^7.1.2",
|
||||
"react": "^18.2.0",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"three": "^0.155.0",
|
||||
"use-keyboard-shortcut": "^1.1.6",
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
/* eslint-disable react/display-name */
|
||||
import React, { forwardRef, useMemo } from "react";
|
||||
import { Vector3 } from "three";
|
||||
import { getMeasurementsFromDimensions, base } from "../../utils";
|
||||
import { getMeasurementsFromDimensions, base, CREATE_MODE } from "../../utils";
|
||||
import { useStore } from "../../store";
|
||||
|
||||
export const BrickCursor = forwardRef(
|
||||
(
|
||||
@@ -16,10 +17,13 @@ export const BrickCursor = forwardRef(
|
||||
dimensions = { x: 1, z: 1 },
|
||||
rotation = 0,
|
||||
translation = { x: 0, z: 0 },
|
||||
visible = true,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const mode = useStore((state) => state.mode);
|
||||
|
||||
const visible = mode === CREATE_MODE;
|
||||
|
||||
const { height, width, depth } = getMeasurementsFromDimensions(dimensions);
|
||||
|
||||
const position = useMemo(() => {
|
||||
|
||||
@@ -8,18 +8,7 @@ import { useControls } from "leva";
|
||||
import { OrbitControls } from "@react-three/drei";
|
||||
|
||||
export const ControlsWrapper = () => {
|
||||
const { setEvents, camera } = useThree();
|
||||
|
||||
const [{ MultiSelect }, set] = useControls(() => ({
|
||||
MultiSelect: false,
|
||||
}));
|
||||
|
||||
useEffect(() => {
|
||||
if (MultiSelect) {
|
||||
camera.position.set(0, 1000, 0);
|
||||
camera.lookAt(0, 0, 0);
|
||||
}
|
||||
}, [MultiSelect, camera]);
|
||||
const { setEvents } = useThree();
|
||||
|
||||
const startTimeoutID = useRef();
|
||||
const endTimeoutID = useRef();
|
||||
@@ -37,12 +26,5 @@ export const ControlsWrapper = () => {
|
||||
endTimeoutID.current = setTimeout(() => setEvents({ enabled: true }), 500);
|
||||
};
|
||||
|
||||
return (
|
||||
<OrbitControls
|
||||
enabled={!MultiSelect}
|
||||
makeDefault
|
||||
onEnd={onEnd}
|
||||
onStart={onStart}
|
||||
/>
|
||||
);
|
||||
return <OrbitControls makeDefault onEnd={onEnd} onStart={onStart} />;
|
||||
};
|
||||
|
||||
@@ -8,10 +8,15 @@ import { LinearToneMapping } from "three";
|
||||
import { ControlsWrapper, Scene } from ".";
|
||||
import { DialogBox } from "../UI";
|
||||
import { Perf } from "r3f-perf";
|
||||
import { ModeToggleBar } from "../UI/ModeToggleBar";
|
||||
import { Panel } from "../UI/Panel";
|
||||
|
||||
export const LegoRoom = () => {
|
||||
return (
|
||||
<>
|
||||
<DialogBox />
|
||||
<ModeToggleBar />
|
||||
<Panel />
|
||||
<Canvas
|
||||
gl={{
|
||||
alpha: false,
|
||||
@@ -32,9 +37,8 @@ export const LegoRoom = () => {
|
||||
<Scene />
|
||||
<ControlsWrapper />
|
||||
</Suspense>
|
||||
<Perf position="bottom-left" />
|
||||
{/* <Perf position="bottom-left" matrixUpdate={true} /> */}
|
||||
</Canvas>
|
||||
<DialogBox />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
+16
-84
@@ -18,58 +18,29 @@ import {
|
||||
base,
|
||||
useAnchorShorcuts,
|
||||
minWorkSpaceSize,
|
||||
EDIT_MODE,
|
||||
} from "../../utils";
|
||||
import { button, useControls } from "leva";
|
||||
import { ChangeColor } from "./ChangeColor";
|
||||
import { useStore } from "../../store";
|
||||
|
||||
export const Scene = () => {
|
||||
const [bricks, setBricks] = useState([]);
|
||||
|
||||
const minWorkSpaceSizeRef = useRef(minWorkSpaceSize);
|
||||
|
||||
const [workspaceSize, setWorkspaceSize] = useState(minWorkSpaceSize);
|
||||
|
||||
const bricksBoundBox = useRef([]);
|
||||
|
||||
const brickCursorRef = useRef();
|
||||
|
||||
const box = useMemo(() => new Box3(), []);
|
||||
const mode = useStore((state) => state.mode);
|
||||
|
||||
const [{ width, depth, rotate, color, anchorX, anchorZ, Edit }, set] =
|
||||
useControls(() => ({
|
||||
width: {
|
||||
value: 1,
|
||||
min: 1,
|
||||
max: 5,
|
||||
step: 1,
|
||||
},
|
||||
depth: {
|
||||
value: 1,
|
||||
min: 1,
|
||||
max: 5,
|
||||
step: 1,
|
||||
},
|
||||
rotate: false,
|
||||
color: "#ff0",
|
||||
anchorX: {
|
||||
value: 0,
|
||||
min: -2,
|
||||
max: 2,
|
||||
step: 1,
|
||||
},
|
||||
anchorZ: {
|
||||
value: 0,
|
||||
min: -2,
|
||||
max: 2,
|
||||
step: 1,
|
||||
},
|
||||
Undo: button((get) => {
|
||||
undoAddedBrick();
|
||||
}),
|
||||
Edit: false,
|
||||
}));
|
||||
const isEditMode = mode === EDIT_MODE;
|
||||
|
||||
useAnchorShorcuts(anchorX, anchorZ, set);
|
||||
const width = useStore((state) => state.width);
|
||||
const depth = useStore((state) => state.depth);
|
||||
const anchorX = useStore((state) => state.anchorX);
|
||||
const anchorZ = useStore((state) => state.anchorZ);
|
||||
const rotate = useStore((state) => state.rotate);
|
||||
const color = useStore((state) => state.color);
|
||||
// useAnchorShorcuts(anchorX, anchorZ, set);
|
||||
|
||||
const setSelection = useSetSelection();
|
||||
|
||||
@@ -84,7 +55,7 @@ export const Scene = () => {
|
||||
const addBrick = (e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (Edit) return;
|
||||
if (isEditMode) return;
|
||||
|
||||
if (!e.face?.normal || !e.point) return;
|
||||
|
||||
@@ -99,26 +70,6 @@ export const Scene = () => {
|
||||
brickCursorRef.current
|
||||
);
|
||||
|
||||
const maxMax = Math.max(
|
||||
Math.abs(boundingBoxOfBrickToBeAdded.max.x * 2),
|
||||
Math.abs(boundingBoxOfBrickToBeAdded.max.z * 2)
|
||||
);
|
||||
const maxMin = Math.max(
|
||||
Math.abs(boundingBoxOfBrickToBeAdded.min.x * 2),
|
||||
Math.abs(boundingBoxOfBrickToBeAdded.min.z * 2)
|
||||
);
|
||||
|
||||
const max = Math.max(maxMax, maxMin);
|
||||
|
||||
minWorkSpaceSizeRef.current = Math.max(max, minWorkSpaceSizeRef.current);
|
||||
|
||||
setWorkspaceSize((currentSize) => {
|
||||
if (currentSize <= max) {
|
||||
return max;
|
||||
}
|
||||
return currentSize;
|
||||
});
|
||||
|
||||
let canCreate = true;
|
||||
|
||||
for (let index = 0; index < bricksBoundBox.current.length; index++) {
|
||||
@@ -165,9 +116,8 @@ export const Scene = () => {
|
||||
|
||||
const setBrickCursorPosition = (e) => {
|
||||
e.stopPropagation();
|
||||
if (Edit) return;
|
||||
if (isEditMode) return;
|
||||
if (!brickCursorRef.current) return;
|
||||
|
||||
const { height } = getMeasurementsFromDimensions({
|
||||
x: width,
|
||||
z: depth,
|
||||
@@ -191,27 +141,10 @@ export const Scene = () => {
|
||||
evenDepth ? base : base / 2
|
||||
)
|
||||
);
|
||||
|
||||
const bb = box.setFromObject(brickCursorRef.current);
|
||||
const max = bb.max.multiplyScalar(1 / base);
|
||||
const min = bb.min.multiplyScalar(1 / base);
|
||||
const brickXEnd = brickCursorRef.current.position.x > 0 ? max.x : min.x;
|
||||
const brickZEnd = brickCursorRef.current.position.z > 0 ? max.z : min.z;
|
||||
|
||||
setWorkspaceSize((currentSize) => {
|
||||
const sizeDiff = Math.max(
|
||||
Math.abs(brickXEnd + anchorX) * base * 2 - currentSize,
|
||||
Math.abs(brickZEnd + anchorZ) * base * 2 - currentSize
|
||||
);
|
||||
if (sizeDiff > 0 || currentSize > minWorkSpaceSizeRef.current) {
|
||||
return currentSize + sizeDiff;
|
||||
}
|
||||
return currentSize;
|
||||
});
|
||||
};
|
||||
|
||||
const onClick = (e) => {
|
||||
if (!Edit) addBrick(e);
|
||||
if (!isEditMode) addBrick(e);
|
||||
};
|
||||
|
||||
const mouseMove = (e) => {
|
||||
@@ -245,7 +178,7 @@ export const Scene = () => {
|
||||
return (
|
||||
<>
|
||||
<color attach="background" args={["#202025"]} />
|
||||
<Select enable={Edit} box multiple onChange={console.log}>
|
||||
<Select box multiple onChange={console.log}>
|
||||
{bricks.map((b, i) => {
|
||||
return (
|
||||
<Brick
|
||||
@@ -265,10 +198,9 @@ export const Scene = () => {
|
||||
<Workspace
|
||||
onClick={onClick}
|
||||
mouseMove={mouseMove}
|
||||
workspaceSize={workspaceSize}
|
||||
workspaceSize={minWorkSpaceSize}
|
||||
/>
|
||||
<BrickCursor
|
||||
visible={Edit ? false : true}
|
||||
ref={brickCursorRef}
|
||||
rotation={rotate ? Math.PI / 2 : 0}
|
||||
dimensions={{ x: width, z: depth }}
|
||||
|
||||
@@ -6,21 +6,8 @@ import * as THREE from "three";
|
||||
import { SelectionBox } from "three-stdlib";
|
||||
import { useThree } from "@react-three/fiber";
|
||||
import { shallow } from "zustand/shallow";
|
||||
import { useControls } from "leva";
|
||||
|
||||
const useEventControl = () => {
|
||||
const { setEvents } = useThree();
|
||||
|
||||
const [{ events }, set] = useControls(() => ({
|
||||
events: true,
|
||||
}));
|
||||
|
||||
React.useEffect(() => {
|
||||
setEvents({ enabled: events });
|
||||
}, [events, setEvents]);
|
||||
|
||||
return null;
|
||||
};
|
||||
import { useStore } from "../../../store";
|
||||
import { EDIT_MODE } from "../../../utils";
|
||||
|
||||
const context = React.createContext([]);
|
||||
const dispatchContext = React.createContext(() => {});
|
||||
@@ -34,13 +21,14 @@ export function Select({
|
||||
border = "1px solid #55aaff",
|
||||
backgroundColor = "rgba(75, 160, 255, 0.1)",
|
||||
filter: customFilter = (item) => item,
|
||||
enable,
|
||||
...props
|
||||
}) {
|
||||
const [downed, down] = React.useState(false);
|
||||
const { setEvents, camera, raycaster, gl, controls, size, get } = useThree();
|
||||
|
||||
useEventControl();
|
||||
const mode = useStore((state) => state.mode);
|
||||
|
||||
const enable = mode === EDIT_MODE;
|
||||
|
||||
const [active, dispatch] = React.useReducer((state, { object, shift }) => {
|
||||
if (object === undefined) return [];
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from "react";
|
||||
import * as ToggleGroup from "@radix-ui/react-toggle-group";
|
||||
import "./styles.css";
|
||||
import { CREATE_MODE, EDIT_MODE } from "../../../utils";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
export const ModeToggleBar = () => {
|
||||
const setMode = useStore((state) => state.setMode);
|
||||
|
||||
return (
|
||||
<ToggleGroup.Root
|
||||
className="ToggleGroup"
|
||||
type="single"
|
||||
defaultValue={CREATE_MODE}
|
||||
aria-label="Text alignment"
|
||||
>
|
||||
<ToggleGroup.Item
|
||||
className="ToggleGroupItem"
|
||||
value={CREATE_MODE}
|
||||
aria-label={CREATE_MODE}
|
||||
onClick={() => setMode(CREATE_MODE)}
|
||||
>
|
||||
{CREATE_MODE}
|
||||
</ToggleGroup.Item>
|
||||
<ToggleGroup.Item
|
||||
className="ToggleGroupItem"
|
||||
value={EDIT_MODE}
|
||||
aria-label={EDIT_MODE}
|
||||
onClick={() => setMode(EDIT_MODE)}
|
||||
>
|
||||
{EDIT_MODE}
|
||||
</ToggleGroup.Item>
|
||||
</ToggleGroup.Root>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,47 @@
|
||||
@import "@radix-ui/colors/black-alpha.css";
|
||||
@import "@radix-ui/colors/mauve.css";
|
||||
@import "@radix-ui/colors/violet.css";
|
||||
|
||||
/* reset */
|
||||
button {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.ToggleGroup {
|
||||
display: inline-flex;
|
||||
background-color: white;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 10px var(--black-a7);
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 15px;
|
||||
transform: translateX(-50%);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.ToggleGroupItem {
|
||||
background-color: white;
|
||||
color: var(--mauve-11);
|
||||
height: 35px;
|
||||
display: flex;
|
||||
font-size: 15px;
|
||||
line-height: 1;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 6px;
|
||||
padding: 0 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.ToggleGroupItem:hover {
|
||||
background-color: var(--violet-3);
|
||||
cursor: pointer;
|
||||
}
|
||||
.ToggleGroupItem[data-state="on"] {
|
||||
background-color: var(--violet-5);
|
||||
color: var(--violet-11);
|
||||
}
|
||||
.ToggleGroupItem:focus {
|
||||
position: relative;
|
||||
box-shadow: 0 0 0 2px black;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from "react";
|
||||
import * as CheckboxRadix from "@radix-ui/react-checkbox";
|
||||
import { CheckIcon } from "@radix-ui/react-icons";
|
||||
import "./styles.css";
|
||||
import { useStore } from "../../../../store";
|
||||
|
||||
const stateMap = {
|
||||
rotate: "rotate",
|
||||
};
|
||||
|
||||
const setterMap = {
|
||||
rotate: "setRotate",
|
||||
};
|
||||
|
||||
export const Checkbox = ({ label = "rotate" }) => {
|
||||
const setValue = useStore((state) => state[setterMap[label]]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="SliderInputContainer"
|
||||
style={{ display: "flex", alignItems: "center" }}
|
||||
>
|
||||
<label className="SliderLabel" htmlFor={label}>
|
||||
{label}
|
||||
</label>
|
||||
<CheckboxRadix.Root
|
||||
className="CheckboxRoot"
|
||||
id={label}
|
||||
onCheckedChange={(bool) => setValue(bool)}
|
||||
>
|
||||
<CheckboxRadix.Indicator className="CheckboxIndicator">
|
||||
<CheckIcon />
|
||||
</CheckboxRadix.Indicator>
|
||||
</CheckboxRadix.Root>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
@import "@radix-ui/colors/black-alpha.css";
|
||||
@import "@radix-ui/colors/violet.css";
|
||||
|
||||
/* reset */
|
||||
button {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
.CheckboxRoot {
|
||||
background-color: var(--black-a7);
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 10px var(--black-a7);
|
||||
}
|
||||
.CheckboxRoot:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.CheckboxRoot:focus {
|
||||
box-shadow: 0 0 0 2px black;
|
||||
}
|
||||
|
||||
.CheckboxIndicator {
|
||||
color: var(--violet-11);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from "react";
|
||||
import { HexColorPicker } from "react-colorful";
|
||||
import "./styles.css";
|
||||
import { useStore } from "../../../../store";
|
||||
|
||||
export const ColorInput = () => {
|
||||
const setColor = useStore((state) => state.setColor);
|
||||
|
||||
return (
|
||||
<div className="SliderInputContainer">
|
||||
<label className="SliderLabel">Color</label>
|
||||
<HexColorPicker color="#000000" onChange={(color) => setColor(color)} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
@import "@radix-ui/colors/black-alpha.css";
|
||||
|
||||
.SliderInputContainer .react-colorful__saturation-pointer {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.SliderInputContainer .react-colorful__saturation {
|
||||
border-bottom: none;
|
||||
margin: 10px 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.SliderInputContainer .react-colorful__hue-pointer {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.SliderInputContainer .react-colorful__hue {
|
||||
height: 8px;
|
||||
/* padding: 8px; */
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.SliderInputContainer .react-colorful {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
background-color: var(--black-a7);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React, { useState } from "react";
|
||||
import * as Slider from "@radix-ui/react-slider";
|
||||
import "./styles.css";
|
||||
import { useStore } from "../../../../store";
|
||||
|
||||
const stateMap = {
|
||||
width: "width",
|
||||
depth: "depth",
|
||||
"anchor X": "anchorX",
|
||||
"anchor Z": "anchorZ",
|
||||
};
|
||||
|
||||
const setterMap = {
|
||||
width: "setWidth",
|
||||
depth: "setDepth",
|
||||
"anchor X": "setAnchorX",
|
||||
"anchor Z": "setAnchorZ",
|
||||
};
|
||||
|
||||
export const SliderWithLabel = ({
|
||||
label = "width",
|
||||
defaultValue = 1,
|
||||
...props
|
||||
}) => {
|
||||
const value = useStore((state) => state[stateMap[label]]);
|
||||
const setValue = useStore((state) => state[setterMap[label]]);
|
||||
|
||||
return (
|
||||
<div className="SliderInputContainer">
|
||||
<label className="SliderLabel">{label}</label>
|
||||
<Slider.Root
|
||||
className="SliderRoot"
|
||||
defaultValue={[defaultValue]}
|
||||
max={4}
|
||||
step={1}
|
||||
min={1}
|
||||
onValueChange={(newVal) => setValue(newVal)}
|
||||
{...props}
|
||||
>
|
||||
<Slider.Track className="SliderTrack">
|
||||
<Slider.Range className="SliderRange" />
|
||||
</Slider.Track>
|
||||
<Slider.Thumb className="SliderThumb" aria-label={label}>
|
||||
{value}
|
||||
</Slider.Thumb>
|
||||
</Slider.Root>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
@import "@radix-ui/colors/black-alpha.css";
|
||||
@import "@radix-ui/colors/violet.css";
|
||||
|
||||
.SliderInputContainer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 14px 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.SliderRoot {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
touch-action: none;
|
||||
width: 150px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.SliderTrack {
|
||||
background-color: var(--black-a7);
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
border-radius: 9999px;
|
||||
height: 3px;
|
||||
}
|
||||
|
||||
.SliderRange {
|
||||
position: absolute;
|
||||
background-color: var(--black-a12);
|
||||
border-radius: 9999px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.SliderThumb {
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: black;
|
||||
box-shadow: 0 2px 10px var(--black-a7);
|
||||
border-radius: 10px;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.SliderThumb:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.SliderThumb:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 5px var(--black-a8);
|
||||
}
|
||||
|
||||
.SliderLabel {
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
line-height: 35px;
|
||||
color: var(--black-a12);
|
||||
text-transform: capitalize;
|
||||
font-weight: 600;
|
||||
min-width: 75px;
|
||||
font-size: 14px;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
/* eslint-disable no-unused-vars */
|
||||
import React from "react";
|
||||
import "./styles.css";
|
||||
import { SliderWithLabel } from "./Slider";
|
||||
import { Checkbox } from "./Checkbox";
|
||||
import { ColorInput } from "./ColorInput";
|
||||
|
||||
export const Panel = () => {
|
||||
return (
|
||||
<div className="Panel">
|
||||
<SliderWithLabel label="width" />
|
||||
<SliderWithLabel label="depth" />
|
||||
<SliderWithLabel label="anchor X" min={-2} defaultValue={0} max={2} />
|
||||
<SliderWithLabel label="anchor Z" min={-2} defaultValue={0} max={2} />
|
||||
<Checkbox />
|
||||
<ColorInput />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
.Panel {
|
||||
position: fixed;
|
||||
left: 20px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 10000;
|
||||
background: white;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
:root {
|
||||
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5;
|
||||
font-weight: 400;
|
||||
|
||||
color-scheme: light dark;
|
||||
color: rgba(255, 255, 255, 0.87);
|
||||
background-color: #242424;
|
||||
|
||||
font-synthesis: none;
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
a {
|
||||
font-weight: 500;
|
||||
color: #646cff;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
a:hover {
|
||||
color: #535bf2;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
place-items: center;
|
||||
min-width: 320px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3.2em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
button {
|
||||
border-radius: 8px;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.6em 1.2em;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
font-family: inherit;
|
||||
background-color: #1a1a1a;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.25s;
|
||||
}
|
||||
button:hover {
|
||||
border-color: #646cff;
|
||||
}
|
||||
button:focus,
|
||||
button:focus-visible {
|
||||
outline: 4px auto -webkit-focus-ring-color;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
color: #213547;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
a:hover {
|
||||
color: #747bff;
|
||||
}
|
||||
button {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
}
|
||||
+6
-7
@@ -1,10 +1,9 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import App from './App.jsx'
|
||||
import './index.css'
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import App from "./App.jsx";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
)
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { create } from "zustand";
|
||||
import { CREATE_MODE, defaultAnchor, defaultWidth } from "../utils";
|
||||
|
||||
export const useStore = create((set) => ({
|
||||
mode: CREATE_MODE,
|
||||
setMode: (newMode) => set({ mode: newMode }),
|
||||
|
||||
width: defaultWidth,
|
||||
setWidth: (newWidth) => set({ width: newWidth }),
|
||||
|
||||
depth: defaultWidth,
|
||||
setDepth: (newDepth) => set({ depth: newDepth }),
|
||||
|
||||
anchorX: defaultAnchor,
|
||||
setAnchorX: (newAnchorPoint) => set({ anchorX: newAnchorPoint }),
|
||||
|
||||
anchorZ: defaultAnchor,
|
||||
setAnchorZ: (newAnchorPoint) => set({ anchorZ: newAnchorPoint }),
|
||||
|
||||
rotate: false,
|
||||
setRotate: (bool) => set({ rotate: bool }),
|
||||
|
||||
color: "#ff0000",
|
||||
setColor: (newColor) => set({ color: newColor }),
|
||||
}));
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
export const base = 25;
|
||||
export const knobSize = 7;
|
||||
export const outlineWidth = 1.3;
|
||||
export const minWorkSpaceSize = 500;
|
||||
export const minWorkSpaceSize = 1000;
|
||||
|
||||
export const CREATE_MODE = "Create Mode";
|
||||
export const EDIT_MODE = "Edit Mode";
|
||||
|
||||
export const defaultWidth = 1;
|
||||
export const defaultAnchor = 0;
|
||||
|
||||
export const bricks = [
|
||||
{ x: 1, z: 1 },
|
||||
|
||||
@@ -9,7 +9,7 @@ export function CSSToHex(cssColor) {
|
||||
export function getMeasurementsFromDimensions({ x, y, z }) {
|
||||
return {
|
||||
width: base * x,
|
||||
height: base * y || (base * 2) / 1.5,
|
||||
height: base * y || base,
|
||||
depth: base * z,
|
||||
};
|
||||
}
|
||||
@@ -34,7 +34,7 @@ export function createGeometry({
|
||||
for (let j = 0; j < dimensions.z; j++) {
|
||||
const cylinder = new CylinderGeometry(knobDim, knobDim, knobDim, 20);
|
||||
const x = base * i - ((dimensions.x - 1) * base) / 2;
|
||||
const y = base / 1.5;
|
||||
const y = base - 12.5;
|
||||
const z = base * j - ((dimensions.z - 1) * base) / 2;
|
||||
cylinder.translate(x, y, z);
|
||||
geometries.push(cylinder);
|
||||
|
||||
Reference in New Issue
Block a user