This commit is contained in:
quantulr
2024-01-02 09:40:02 +08:00
parent e54a837654
commit 44284fdd62
10 changed files with 382 additions and 576 deletions

View File

@ -33,12 +33,12 @@
}, },
"devDependencies": { "devDependencies": {
"@types/fabric": "^5.3.6", "@types/fabric": "^5.3.6",
"@types/node": "^20.10.5", "@types/node": "^20.10.6",
"@types/react": "^18.2.45", "@types/react": "^18.2.46",
"@types/react-dom": "^18.2.18", "@types/react-dom": "^18.2.18",
"@types/three": "^0.159.0", "@types/three": "^0.159.0",
"@typescript-eslint/eslint-plugin": "^6.16.0", "@typescript-eslint/eslint-plugin": "^6.17.0",
"@typescript-eslint/parser": "^6.16.0", "@typescript-eslint/parser": "^6.17.0",
"@vitejs/plugin-react-swc": "^3.5.0", "@vitejs/plugin-react-swc": "^3.5.0",
"autoprefixer": "^10.4.16", "autoprefixer": "^10.4.16",
"eslint": "^8.56.0", "eslint": "^8.56.0",
@ -46,8 +46,8 @@
"eslint-plugin-react-refresh": "^0.4.5", "eslint-plugin-react-refresh": "^0.4.5",
"postcss": "^8.4.32", "postcss": "^8.4.32",
"prettier": "^3.1.1", "prettier": "^3.1.1",
"prettier-plugin-tailwindcss": "^0.5.9", "prettier-plugin-tailwindcss": "^0.5.10",
"sass": "^1.69.5", "sass": "^1.69.6",
"tailwindcss": "^3.4.0", "tailwindcss": "^3.4.0",
"typescript": "^5.3.3", "typescript": "^5.3.3",
"vite": "^5.0.10" "vite": "^5.0.10"

748
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
.modelAreaItem {
&:not(:first-child) {
margin-top: 8px;
}
}
.modelItem {
&:not(:first-child) {
margin-top: 8px;
}
}

View File

@ -1,36 +0,0 @@
import { models } from "@/constant/models.ts";
import useModelStore from "@/store/useModelStore.ts";
import styles from "./AreaIndicator.module.scss";
const AreaIndicator = () => {
const activeModel = useModelStore((state) => state.activeModel);
const activeArea = useModelStore((state) => state.activeArea);
const setActiveArea = useModelStore((state) => state.setActiveArea);
return (
<div
className={
"absolute left-2 top-1/2 flex -translate-y-1/2 flex-col items-center justify-center rounded bg-red-200 p-2 shadow-lg transition-shadow hover:shadow-2xl"
}
>
{models[activeModel].mesh.map((item, index) => (
<div
onClick={() => {
setActiveArea(index);
}}
className={`${styles.modelAreaItem} ${
activeArea === index ? "border-2 border-green-300" : ""
} h-12 w-12 overflow-hidden rounded transition-all`}
key={item.name}
>
<img
src={item.icon}
className={"h-full w-full object-cover"}
alt={""}
/>
</div>
))}
</div>
);
};
export default AreaIndicator;

View File

@ -1,57 +0,0 @@
import {
Button,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
} from "@chakra-ui/react";
import { useEffect, useRef } from "react";
import { fabric } from "fabric";
import { ICanvasOptions } from "fabric/fabric-impl"; // v6
const CanvasTexturesEditor = ({
open,
onClose,
}: {
open: boolean;
onClose: () => void;
}) => {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
useEffect(() => {
const options: ICanvasOptions = {
backgroundImage: "/",
};
const canvas = new fabric.Canvas(canvasRef.current, options);
// make the fabric.Canvas instance available to your app
// updateCanvasContext(canvas);
return () => {
// updateCanvasContext(null);
canvas.dispose();
};
}, []);
return (
<Modal isOpen={open} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Modal Title</ModalHeader>
<ModalCloseButton />
<ModalBody>
<canvas className={"w-full"} height={300} ref={canvasRef}></canvas>
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mr={3} onClick={() => {}}>
Close
</Button>
<Button variant="ghost">Secondary Action</Button>
</ModalFooter>
</ModalContent>
</Modal>
);
};
export default CanvasTexturesEditor;

View File

@ -1,5 +0,0 @@
const DebugPanel = () => {
return <div>DebugPanel</div>;
};
export default DebugPanel;

View File

@ -1,57 +0,0 @@
import useModelStore from "@/store/useModelStore.ts";
import { textures } from "@/constant/textures.ts";
// import CanvasTexturesEditor from "@/components/CanvasTexturesEditor.tsx";
import { useState } from "react";
import { Divider, IconButton } from "@chakra-ui/react";
import { AddIcon } from "@chakra-ui/icons";
import TexturesEditor from "@/components/TexturesEditor.tsx";
const TextureSelector = () => {
const { activeTextures, setActiveTextures, activeArea } = useModelStore();
// eslint-disable-next-line no-empty-pattern
const [showEditor, setShowEditor] = useState(false);
return (
<>
<div
className={
"absolute bottom-2 left-1/2 flex -translate-x-1/2 items-center rounded-lg bg-red-200 px-4 py-2"
}
>
<span className={"text-xs"}></span>
{textures.map((item, index) => (
<div
onClick={() => {
// setActiveTexture(index);
setActiveTextures(activeArea, index);
}}
className={`${
activeTextures[activeArea] === index
? "border-2 border-green-300"
: ""
} mx-1 h-12 w-12 origin-bottom overflow-hidden rounded transition-all hover:mx-4 hover:scale-150`}
key={item.path}
>
<img className={"object-cover"} src={item.path} alt={""} />
</div>
))}
<Divider orientation="vertical" />
<IconButton
className={"ml-4"}
aria-label={""}
icon={<AddIcon />}
onClick={() => {
setShowEditor(() => true);
}}
></IconButton>
</div>
<TexturesEditor
isOpen={showEditor}
onClose={() => {
setShowEditor(() => false);
}}
/>
</>
);
};
export default TextureSelector;

View File

@ -40,7 +40,7 @@ function TextureSelectorPanel() {
: "" : ""
} cursor-pointer overflow-hidden rounded`} } cursor-pointer overflow-hidden rounded`}
> >
<img className={"h-full w-full object-cover"} src={texture.path} /> <img className={"h-full w-full object-cover"} src={texture.path} alt={""} />
</div> </div>
))} ))}
</div> </div>

View File

@ -1,27 +0,0 @@
import {
Modal,
ModalBody,
ModalContent,
ModalHeader,
ModalOverlay,
} from "@chakra-ui/react";
const TexturesEditor = ({
isOpen,
onClose,
}: {
isOpen: boolean;
onClose: () => void;
}) => {
return (
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader></ModalHeader>
<ModalBody></ModalBody>
</ModalContent>
</Modal>
);
};
export default TexturesEditor;

View File

@ -14,8 +14,7 @@ export const pickFile = (options: {
const fileList = []; const fileList = [];
if (files) { if (files) {
for (const file of files) { for (const file of files) {
const customFile = file; fileList.push(file);
fileList.push(customFile);
} }
resolve(fileList); resolve(fileList);
} else { } else {