111 lines
2.7 KiB
TypeScript
111 lines
2.7 KiB
TypeScript
|
import { create } from "zustand";
|
||
|
import { models } from "@/constant/models.ts";
|
||
|
import { Vector3 } from "three";
|
||
|
import { devtools } from "zustand/middleware";
|
||
|
import { v4 as uuidv4 } from "uuid";
|
||
|
export enum StickerType {
|
||
|
text,
|
||
|
logo,
|
||
|
}
|
||
|
|
||
|
export interface DecalSticker {
|
||
|
id: string;
|
||
|
postion: Vector3;
|
||
|
text?: string;
|
||
|
url: string;
|
||
|
type: StickerType;
|
||
|
}
|
||
|
|
||
|
interface ModelState {
|
||
|
modelLoading: number;
|
||
|
setModelLoading: (progress: number) => void;
|
||
|
|
||
|
activeModel: number;
|
||
|
setActiveModel: (index: number) => void;
|
||
|
|
||
|
activeArea: number;
|
||
|
setActiveArea: (index: number) => void;
|
||
|
|
||
|
activeTextures: number[];
|
||
|
setActiveTextures: (activeArea: number, activeTexture: number) => void;
|
||
|
|
||
|
decalDragging: boolean;
|
||
|
setDecalDragging: (enable: boolean) => void;
|
||
|
|
||
|
decals: DecalSticker[];
|
||
|
activeDecal?: string;
|
||
|
setDecalPositon: (id: string, postion: Vector3) => void;
|
||
|
setDecals: (decals: DecalSticker[]) => void;
|
||
|
setActiveDecal: (decalId: string) => void;
|
||
|
}
|
||
|
|
||
|
const useModelStore = create<ModelState>()(
|
||
|
devtools((set) => ({
|
||
|
modelLoading: 0,
|
||
|
setModelLoading: (progress: number) =>
|
||
|
set(() => ({ modelLoading: progress })),
|
||
|
|
||
|
activeModel: 0,
|
||
|
setActiveModel: (index: number) =>
|
||
|
set(() => ({
|
||
|
activeModel: index,
|
||
|
activeArea: 0,
|
||
|
activeTextures: Array(models[index].mesh.length).fill(0),
|
||
|
})),
|
||
|
|
||
|
activeArea: 0,
|
||
|
setActiveArea: (index: number) => set(() => ({ activeArea: index })),
|
||
|
|
||
|
activeTextures: Array(models[0].mesh.length).fill(0),
|
||
|
setActiveTextures: (activeArea: number, activeTexture: number) =>
|
||
|
set((state) => ({
|
||
|
activeTextures: state.activeTextures.length
|
||
|
? state.activeTextures.map((item, index) =>
|
||
|
index === activeArea ? activeTexture : item,
|
||
|
)
|
||
|
: Array(state.activeTextures.length).fill(0),
|
||
|
})),
|
||
|
|
||
|
// 是否正在拖拽sticker
|
||
|
decalDragging: false,
|
||
|
setDecalDragging: (enable: boolean) =>
|
||
|
set(() => ({ decalDragging: enable })),
|
||
|
|
||
|
decals: [
|
||
|
{
|
||
|
id: uuidv4(),
|
||
|
url: "/textures/archlogo.png",
|
||
|
postion: new Vector3(0, 0, 0),
|
||
|
type: StickerType.logo,
|
||
|
},
|
||
|
],
|
||
|
activeDecal: undefined,
|
||
|
setDecalPositon: (id: string, postion: Vector3) =>
|
||
|
set((state) => {
|
||
|
const _decals = state.decals.map((el) => {
|
||
|
if (el.id === id) {
|
||
|
return {
|
||
|
...el,
|
||
|
postion,
|
||
|
};
|
||
|
} else {
|
||
|
return el;
|
||
|
}
|
||
|
});
|
||
|
return {
|
||
|
decals: _decals,
|
||
|
};
|
||
|
}),
|
||
|
setDecals: (decals: DecalSticker[]) =>
|
||
|
set(() => ({
|
||
|
decals,
|
||
|
})),
|
||
|
setActiveDecal: (decalId: string) =>
|
||
|
set(() => ({
|
||
|
activeDecal: decalId,
|
||
|
})),
|
||
|
})),
|
||
|
);
|
||
|
|
||
|
export default useModelStore;
|