3D 포트폴리오
이 사람에게만 속할 수 있는 원페이지 포트폴리오를 만드세요. 이 스킬을 생성한 사이트는 DJ의 레코드 크레이트를 중심으로 구축되었습니다. 모든 프로젝트는 넘겨볼 수 있는 레코드 슬리브이며, 앞에 있을 때 레코드가 회전합니다. 예시: https://alessio-simoya.vercel.app
해당 컨셉을 복사하지 마세요. 프로세스를 따르고 그들만의 컨셉을 찾으세요.
1. 먼저 입력 수집
디자인하기 전에 다음을 요청하세요. 처음부터 실제 콘텐츠로 구축하세요.
- 프로젝트: 각 프로젝트에 대해 간략한 사실: 무엇인지, 역할, 날짜, 성과, 스택, 라이브 링크, 주장해서는 안 되는 것들의 목록.
- 경력: 회사, 직책, 날짜, 장소, 각 직무당 하나의 결과.
- 기술: 그룹화하고, 각 기술이 입증된 위치.
- 직장 외 삶: 취미, 팀, 요리하는 것, 가본 곳. 컨셉이 여기서 나오므로, 그들이 제시하는 것보다 더 많이 요청하세요.
- 에셋: 로고, 제품 스크린샷, 비디오, Rive 또는 Lottie 파일. 프로젝트 폴더가 어디에 있는지 묻고 검색하세요.
- 링크: LinkedIn, GitHub 등. 그들이 허락하지 않는 한 이메일 주소를 공개하지 마세요.
2. 하나의 컨셉 찾기
그 사람의 세계에서 가장 특징적인 것을 골라 히어로로 삼고, 사람들이 가지고 놀 수 있는 실제 3D 객체로 만드세요. DJ는 레코드 크레이트를, 클라이머는 홀드 벽을, 제빵사는 빵 트레이를 얻을 수 있습니다. 각 프로젝트는 그 객체의 한 항목이 됩니다.
거기서 대담함을 사용하세요. 페이지의 나머지는 조용하게 유지하세요: 평평한 색상 필드, 개성이 있는 하나의 디스플레이 서체, 하나의 평범한 본문 서체, 4~5개의 명명된 색상.
3. 스택
- 엄격 모드의 Vite, React 및 TypeScript
- 3D용 three.js, 직접 작성(씬 프레임워크 불필요)
- 사용자가 이미
.riv파일을 가지고 있는 경우에만 Rive 사용; wasm을 지연 로드 - API용 tRPC 및 zod,
api/trpc/[trpc].ts의 Vercel 함수로 - 이메일용 Resend, 스팸 방지용 Cloudflare Turnstile, 레코드용 Neon Postgres
@fontsource-variable/*를 통한 자체 호스팅 가변 폰트
4. 3D 구성 방법
하나의 고정된 전체 화면 WebGL 캔버스를 pointer-events: none과 함께 사용하고, 모든 3D 뷰를 DOM 플레이스홀더의 사각형에 그립니다:
const r = el.getBoundingClientRect();
renderer.setViewport(r.left, innerHeight - r.bottom, r.width, r.height);
renderer.setScissor(r.left, innerHeight - r.bottom, r.width, r.height);
renderer.render(scene, camera);
프레임당 한 번 지우고, 시저 테스트를 켜고, 화면 밖의 요소는 건너뜁니다. 이렇게 하면 하나의 컨텍스트 비용으로 페이지 아래에 많은 3D 객체를 얻을 수 있으며, 레이아웃과 함께 스크롤됩니다.
각 작은 객체에 "리그"를 제공하세요: 그룹, 카메라 위치, 응시 지점, 하나의 공유 클럭으로 구동되는 tick(t) 함수. 리그를 지연 생성하고 한 번에 하나씩 표시하세요. 2D 캔버스(로고, 레이블, 패턴)에 텍스처를 그리면 로드할 모델 파일이 없습니다.
잘못된 점과 해결 방법:
- 요소보다 큰 지면 그림자 평면은 딱딱한 사각형으로 나타납니다. 뷰 안에 맞게 크기를 조정하세요.
- "자체 축을 중심으로 회전"이 필요할 때 그룹을 회전시킨 다음 자식을 회전시키세요.
- 스프라이트와 투명 평면은 솔리드 메시 뒤에 그려집니다. 객체 아래의 광선은 카메라를 향하는 스프라이트가 아닌 그 아래의 평평한 평면이어야 합니다.
5. 효과가 있었던 섹션
- 히어로: 이름을 매우 크게 설정하고, 역할을 순환하는 스티커, 한 문장, 대화형 객체. 뒤에 있는 색상 디스크는 초점 대상에 따라 변경됩니다.
- 작업: 각 케이스 스터디는 해당 브랜드 색상의 밴드에서 실제 로고와 함께 열리고, 그 다음 이미지, 비디오 및 애니메이션의 가로 릴, 세 가지 짧은 하이라이트, 몇 개의 큰 수치 및 칩으로 된 스택이 이어집니다. 긴 텍스트는 "전체 스토리 읽기" 뒤에 있습니다.
- 경력: 각 직무당 한 행, 각각 하나의 큰 숫자.
- 여정: 학교 또는 이정표, 각각 자체 애니메이션 객체.
- 기술: 표가 아닌 움직이는 텍스트 행.
- 업무 외 시간: 관심사당 하나의 애니메이션 객체.
- 여행: 냉장고 자석처럼 쇠문에 배치하여 드래그할 수 있는 장소.
- 연락하기: 문의 폼.
IntersectionObserver를 사용하는 떠다니는 알약 헤더가 현재 섹션을 표시합니다.
6. 규칙
- 사실만. 사용자가 제공한 것을 사용하세요. 섹션에 제공되지 않은 것이 필요하면 생략하세요. 각 프로젝트의 "주장 금지" 목록을 콘텐츠 파일에 주석으로 유지하세요.
- 허영 카운트 금지. 커밋, 코드 줄 수, 페이지 수 또는 모델 수는 미성숙해 보입니다. 제품과 그 성과를 보여주세요.
- 적은 텍스트 표시. 화면이 대부분 단락이면 시각적인 것으로 바꾸세요.
- 타인의 작업 존중. 유료 템플릿을 미리보기에서 재구축하지 말고, 브랜드의 제품 디자인(예: 명명된 경기 공)을 복사하지 마세요. 동일한 정신으로 독창적인 것을 그리세요. 자유롭게 라이선스된 이미지만 사용하고 페이지에 출처를 표시하세요.
- 스크린샷에는 실제 고객 이름, 금액 또는 얼굴이 표시되어서는 안 됩니다.
- 모션에는 끄기 스위치가 있습니다.
prefers-reduced-motion을 존중하고, "모션 일시 중지" 버튼을 추가하고, WebGL이 없을 때 평면적인 대체를 제공하세요. - 모든 콘텐츠를 하나의 타입 파일 (
src/content/portfolio.ts)에 넣어 사용자가 구성 요소를 건드리지 않고 단어를 편집할 수 있도록 하세요.
7. 문의 폼
하나의 tRPC 프로시저 contact.send, zod 입력 포함. 순서대로:
- 숨겨진 허니팟 필드가 채워지면 자동으로 성공을 반환합니다.
- 주소별 작은 속도 제한을 적용합니다.
- Cloudflare로 Turnstile 토큰을 확인하고 실패하면 거부합니다.
reply_to로 발신자를 설정하여 Resend를 통해 소유자에게 이메일을 보냅니다.- 모든 메시지를
messages테이블에 저장합니다. - 방문자가 기본적으로 선택되지 않은 "계속 알려주세요" 상자를 체크한 경우에만,
subscribers테이블(동의 문구 및 시간 포함)과 Resend 대상에 저장합니다.
해당 체크 없이 메일링 리스트에 사람을 추가하지 마세요.
환경 변수: RESEND_API_KEY, ENQUIRY_TO_EMAIL, ENQUIRY_FROM_EMAIL, RESEND_AUDIENCE_ID, DATABASE_URL, TURNSTILE_SECRET, 브라우저용 공개 사이트 키.
잘못된 점:
from값은 이미Name <address>형식일 수 있습니다. 다시 래핑하면 Resend가 422로 응답합니다.<가 포함된 경우 그대로 사용하세요.- Vite는
envPrefix의 접두사로 시작하는 변수만 노출합니다. 사이트 키가 다른 이름으로 도착하면 해당 접두사를 추가하세요. - Turnstile 위젯은 Cloudflare에 나열된 호스트 이름에서만 작동합니다.
- 프로덕션에서 Turnstile 시크릿이 없으면 전송을 거부하세요. 로컬 개발에서만 Cloudflare의 공개 테스트 키를 사용하세요.
CONTACT_DRY_RUN=1스위치를 추가하세요. 프로덕션에서는 무시되며, 이메일을 보내지 않고 전체 경로를 테스트할 수 있습니다.vite dev에서 동일한 핸들러를 실행하려면,server.ssrLoadModule으로 함수를 로드하고Request를 전달하는 작은 플러그인을 추가하세요.- 테이블과 인라인 스타일로 이메일 HTML을 구축하고 모든 필드를 이스케이프하세요.
8. 진행하면서 작업 확인
변경 사항이 있을 때마다:
- 빌드를 실행합니다.
- 1440px 및 390px 너비에서 모든 섹션의 Playwright 스크린샷을 찍습니다(WebGL이 헤드리스로 렌더링되도록
--use-gl=swiftshader로 Chromium 실행). document.documentElement.scrollWidth - innerWidth가 0인지 확인합니다.- 완료되었다고 말하기 전에 직접 스크린샷을 확인하세요.
확인되지 않은 것을 명확히 말하세요: 실제 휴대폰, Safari, 모션의 느낌, 실제 이메일 전달.
9. 배포
git init,.env*및.vercel은 무시됩니다. 첫 커밋 전에 스테이징된 파일에서 키를 스캔하세요.vercel link, 환경 변수 추가,vercel --prod.- 라이브 페이지가 실패한 요청 없이 로드되고 API가 Turnstile 토큰 없는 요청을 거부하는지 확인하세요.
- 소유자에게 라이브 폼을 통해 실제 메시지를 하나 보내도록 요청하세요.
시작 프롬프트
사용자에게 다음을 작성하도록 제공하세요:
3d-portfolio 스킬을 사용하여 내 3D 포트폴리오를 만들어 주세요.
내 이름과 한 줄 설명:
히어로에서 순환할 역할(4~6개):
프로젝트(각각: 사실, 내 역할, 날짜, 링크, 주장하지 말아야 할 것):
경력(회사, 직책, 날짜, 각각 하나의 결과):
기술, 그룹화:
학교 또는 이정표:
직장 외 관심사(구체적으로):
내가 가본 곳:
내 컴퓨터에서 로고, 스크린샷 및 애니메이션이 있는 위치:
표시할 링크(LinkedIn, GitHub 등):
사이트에 절대 원하지 않는 것: