Skip to content

Commit

Permalink
refactor: canvas optimize
Browse files Browse the repository at this point in the history
  • Loading branch information
kcwww committed Nov 19, 2024
1 parent d9d87d9 commit 212d5a5
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 30 deletions.
44 changes: 16 additions & 28 deletions app/(protected)/make/_components/DecoDrawer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState, useEffect } from 'react';
import { useState, useCallback } from 'react';

import { ArrowLeftRight } from 'lucide-react';

import {
Expand All @@ -10,7 +11,7 @@ import {
DrawerTrigger,
} from '@/components/ui/drawer';

import DecorationSelect from '@/app/(protected)/make/_components/DecorationSelect';
import DecorationsViewer from '@/app/(protected)/make/_components/DecorationViewer';
import { BOTTOM, DECO_TYPE, MAIN_DECORATION } from '@/shared/constants/3dModel';

import dynamic from 'next/dynamic';
Expand All @@ -23,14 +24,12 @@ const ColorButton = dynamic(
);

const DecoDrawer = ({ step, userData }: { step: number; userData: User }) => {
const [isMounted, setIsMounted] = useState(false);
const [isOpened, setIsOpened] = useState(false);

useEffect(() => {
setIsMounted(true);
const drawerClose = useCallback(() => {
setIsOpened(false);
}, []);

if (!isMounted) return null;

if (
step === STEP.MAIN_DECORATION_COLOR ||
step === STEP.BOTTOM_DECORATION_COLOR
Expand All @@ -50,10 +49,13 @@ const DecoDrawer = ({ step, userData }: { step: number; userData: User }) => {
const mainDecorationArray = Object.values(MAIN_DECORATION);
const bottomDecorationArray = Object.values(BOTTOM);

const isMain = step === STEP.MAIN_DECORATION;
const decorations = isMain ? mainDecorationArray : bottomDecorationArray;

return (
<Drawer>
<Drawer open={isOpened} onOpenChange={setIsOpened}>
<DrawerTrigger className="pointer-events-auto transform rounded-lg bg-white p-2 px-4 transition duration-200 hover:bg-gray-300">
{step === STEP.MAIN_DECORATION ? '장식 선택하기' : '바닥 장식 선택하기'}
{isMain ? '장식 선택하기' : '바닥 장식 선택하기'}
</DrawerTrigger>
<DrawerContent className="flex flex-col items-center justify-center gap-8 border-none bg-primary pb-10">
<DrawerHeader className="flex flex-col items-center gap-2">
Expand All @@ -65,25 +67,11 @@ const DecoDrawer = ({ step, userData }: { step: number; userData: User }) => {
</DrawerDescription>
</DrawerHeader>

<div className="flex w-full overflow-auto">
{step === STEP.MAIN_DECORATION &&
mainDecorationArray.map((deco, index) => (
<DecorationSelect
key={index}
path={deco.path}
type={DECO_TYPE.MAIN}
/>
))}

{step === STEP.BOTTOM_DECORATION &&
bottomDecorationArray.map((deco, index) => (
<DecorationSelect
key={index}
path={deco.path}
type={DECO_TYPE.BOTTOM}
/>
))}
</div>
<DecorationsViewer
onClose={drawerClose}
decorations={decorations}
type={isMain ? DECO_TYPE.MAIN : DECO_TYPE.BOTTOM}
/>
</DrawerContent>
</Drawer>
);
Expand Down
91 changes: 91 additions & 0 deletions app/(protected)/make/_components/DecorationViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
'use client';

import { useLayoutEffect, useCallback, useState } from 'react';
import { Canvas } from '@react-three/fiber';
import { Scroll, ScrollControls } from '@react-three/drei';
import { Suspense } from 'react';
import { use3DModel } from '@/app/(protected)/make/store/modelStore';
import InitializeDecoration from '@/app/(protected)/make/_components/InitializeDecoration';
import { DECO_TYPE } from '@/shared/constants/3dModel';
import { DecorationType } from '@/shared/types/model';
import Loading from '@/app/loading';

const DecorationsViewer = ({
onClose,
decorations,
type,
}: {
onClose: () => void;
decorations: Array<{ path: string }>;
type: DecorationType;
}) => {
const { setModel, setBottom } = use3DModel();
const [pages, setPages] = useState(1);

const ITEM_WIDTH = 200;
const ITEM_GAP = type === DECO_TYPE.MAIN ? 100 : 150;

const handleModel = useCallback(
(path: string) => {
if (type === DECO_TYPE.MAIN) {
setModel({ model: path });
} else if (type === DECO_TYPE.BOTTOM) {
setBottom({ bottom: path });
}
onClose();
},
[onClose, setBottom, setModel, type]
);

useLayoutEffect(() => {
const handleScrollSize = () => {
const screenWidth = window.innerWidth;
const minWidth =
decorations.length * ITEM_WIDTH + ITEM_GAP + screenWidth / 2;
const newPages = Math.ceil(minWidth / screenWidth);
setPages(newPages);
};

handleScrollSize();
window.addEventListener('resize', handleScrollSize);

return () => {
window.removeEventListener('resize', handleScrollSize);
};
}, [decorations]);

return (
<div style={{ width: '100%', height: '400px' }}>
<Suspense fallback={Loading()}>
<Canvas style={{ width: '100%', height: '100%' }}>
<ambientLight intensity={1} color={'#ffffff'} />
<directionalLight
position={[10, 20, 10]}
intensity={0.7}
color={'#ffffff'}
/>
<ScrollControls horizontal damping={0.3} pages={pages}>
<Scroll>
{/* 장식들을 렌더링 */}
{decorations.map((deco, index) => (
<group
key={index}
onClick={() => handleModel(deco.path)}
position={[
index * (type === DECO_TYPE.MAIN ? 4.5 : 6.5),
0,
0,
]} // 장식 간격 조정
>
<InitializeDecoration path={deco.path} type={type} />
</group>
))}
</Scroll>
</ScrollControls>
</Canvas>
</Suspense>
</div>
);
};

export default DecorationsViewer;
3 changes: 1 addition & 2 deletions app/(public)/visit/_components/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ const Visit = ({ userData }: { userData: UserData }) => {
}}
>
<Link
href="/visit/[userId]/message"
className="w-full"
as={ROUTES.MESSAGE(userData.user.uuid, String(current))}
href={ROUTES.MESSAGE(userData.user.uuid, String(current))}
>
{userData.user.username} 님의 수정구슬 꾸미고 메세지 남기기
</Link>
Expand Down

0 comments on commit 212d5a5

Please sign in to comment.