DotCharacter
승인된 3D 캐릭터를 의미 있는 브랜드 순간에 렌더링합니다.
목적
DotCharacter는 학습의 한 고리를 완결하고 다음 배움의 방향을 밝히는 동반자로서 정서적 연결과 브랜드 정체성을 만든다. 기능을 대신 설명하는 장식물이 아니며, 사용자가 불확실하거나 의미 있는 전환을 마주하는 드문 순간에만 등장한다.
현재 package는 승인된 정적 3D character를 제공한다. 제품 안의 답변·처리 맥락을 위한 2D 표현은 정적 character가 아니라 별도 motion entry의 DotMotion으로만 제공된다.
구조
- 2D: 제품 안에서 AI가 답변하거나 데이터를 탐색·생성하는 구체적인 처리 맥락에 사용한다. 현재는
DotMotion의avatar,processing만 제공한다. - 3D: 넓고 드문 브랜드·소개·홍보·온보딩·의미 있는 완료 맥락에 사용한다.
DotCharacter가 이 범위를 담당한다. - 3D를 작은 상태 아이콘이나 반복 행에 축소해서 사용하지 않는다.
- 2D와 3D를 같은 화면에서 동시에 경쟁시키지 않는다.
character를 구성하는 body, 위성 요소, 연결 구조와 Glow는 분리할 수 없는 하나의 시각 구조다. 이미지 요소는 투명 배경을 포함한 승인된 source set을 렌더하며, 설명과 행동은 character 바깥의 제품 구조가 담당한다.
형태 보존
character를 구성하는 body, 위성 요소, 연결 구조, Glow, 지정된 색과 형태는 하나의 정체성이다.
- 요소를 분리, 삭제, 재배치하지 않는다.
- 비율을 왜곡하거나 잘라내지 않는다.
- 임의 색상, 효과, 표정, 소품을 덧붙이지 않는다.
- 기존 자산을 비슷하게 다시 그리거나 생성하지 않는다.
- 화면과 충돌한다는 이유로 gradient를 임의 수정하지 않는다.
변형과 크기
- 기본적으로 gradient treatment를 사용한다.
- gradient가 주변 색과 충돌하거나 단색·흑백 맥락에서 가독성이 떨어질 때만 제공된 White treatment를 선택한다.
- White treatment도 임의 recolor가 아니라 승인된 asset ID를 그대로 사용한다.
- 배경과 character의 경계가 약하면 character 자체를 고치지 말고 주변 surface와 여백을 조정한다.
- 3D character의 최소 렌더 크기는 100px이다.
size에 더 작은 값을 전달해도 컴포넌트가 100px로 보정한다. responsiveSizes는 실제 CSS 배치 폭과 일치시켜 브라우저가 적절한 자산을 선택하게 한다.
선택 기준
적합한 맥락:
- 첫 사용에서 Dot의 역할을 소개할 때
- 넓고 의미 있는 빈 상태에서 다음 학습 행동을 제안할 때
- 긴 여정의 완료를 인정하고 다음 방향을 안내할 때
- 독립된 브랜드·홍보 surface
부적합한 맥락:
- 일반 네트워크 로딩
- 오류와 위험 상태
- table row, 작은 card, navigation의 반복 장식
- 모든 성공 toast
- 사용자의 주 행동보다 먼저 시선을 가져가는 배치
배치
- character의 세부 형태를 이해해야 하는 넓은 맥락에서는 충분한 여백을 제공한다.
- 텍스트와 CTA보다 앞서 의미를 독점하지 않게 한다.
- 투명 배경을 전제로 하되 중요한 UI와 겹치지 않는다.
상태와 동작
DotCharacter는 정적이며 자체 상호작용이 없다.- 로딩 indicator, button 또는 선택 control로 사용하지 않는다.
- 클릭 행동이 필요하면 character 전체를 모호한 trigger로 만들지 말고 인접한 명시적 CTA를 제공한다.
- 기본적으로 lazy loading과 async decoding을 사용한다.
콘텐츠
- character가 순수하게 분위기와 브랜드 정체성을 보조하면 기본
alt=""를 유지한다. - character가 문장에 없는 정보를 실제로 전달한다면 짧은
alt를 제공한다. 외형보다 수행하는 의미를 설명한다. - 동일한 의미가 제목과 설명에 이미 있으면 반복 낭독하지 않는다.
- character만으로 성공, 실패, 처리 중을 전달하지 않는다.
접근성
- 장식적인 character는
alt=""로 접근성 트리에서 제외한다. - character가 전달하는 의미는 제목, 설명과 CTA에서도 이해할 수 있어야 한다.
- 의미 있는
alt가 필요하면 색이나 외형이 아니라 사용자가 알아야 할 역할을 짧게 쓴다. - character 때문에 heading 순서, keyboard 탐색 또는 focus 위치가 달라지지 않게 한다.
- 확대와 고대비 환경에서도 텍스트와 행동을 character에 겹치지 않는다.
좁은 화면과 긴 콘텐츠
- 100px 미만으로 축소하지 않는다. 공간이 부족하면 숨기거나 더 넓은 지점에서 사용한다.
- CTA를 화면 아래로 밀거나 불필요한 scroll을 만들면 character를 우선 제거한다.
- 긴 콘텐츠와 함께 있을 때 텍스트 읽기 폭과 행동 순서를 먼저 보존한다.
- 작은 화면에서 crop하거나 body 일부만 보여주지 않는다.
공개 API
DotCharacterProps는 이미지의 height, sizes, src, srcSet, width를 제외한 React.ImgHTMLAttributes<HTMLImageElement>를 확장한다. 자산 선택과 responsive source는 컴포넌트가 소유한다.
| 속성 | 타입 | 기본값 | 설명 |
|---|---|---|---|
assetId | DotCharacterAssetId | 'ai-dot.character.3d.gradient.base' | 승인된 정적 3D 자산 ID |
size | number | 160 | 렌더 크기. 최소 100px |
responsiveSizes | string | 렌더 크기의 px 값 | responsive image sizes 힌트 |
alt | string | '' | 이미지 대체 텍스트 |
loading | 이미지 loading 속성 | 'lazy' | 이미지 로딩 방식 |
decoding | 이미지 decoding 속성 | 'async' | 이미지 decoding 방식 |
draggable | boolean | false | drag 허용 여부 |
className | string | 없음 | 최종 img class |
현재 공개된 DotCharacterAssetId:
ai-dot.character.3d.gradient.baseai-dot.character.3d.gradient.application-01ai-dot.character.3d.gradient.application-02ai-dot.character.3d.gradient.application-03ai-dot.character.3d.white.baseai-dot.character.3d.white.application-01ai-dot.character.3d.white.application-02
예제
넓고 드문 독립 surface에서 텍스트와 행동의 의미를 보조하도록 직접 배치한다.
DotCharacter는 package root에서 가져오며, 제품 안의 2D 표현은 @classum/dot-design-system/motion의 DotMotion을 사용한다.
import { DotCharacter } from '@classum/dot-design-system';
<div className="grid items-center gap-8 md:grid-cols-[1fr_auto]">
<div>{/* title, description, action */}</div>
<DotCharacter
assetId="ai-dot.character.3d.gradient.application-01"
size={240}
responsiveSizes="(min-width: 768px) 240px, 160px"
alt=""
/>
</div>;피해야 할 사용
- 100px 미만으로 축소하거나 일부를 crop
- body, 위성, 연결, Glow, 지정 색과 형태를 편집
- gradient 충돌을 임의 recolor로 해결
- 반복되는 table row와 card에 장식적으로 배치
- 일반 loading과 error icon으로 사용
- character만 클릭 가능한 모호한 행동 제공
- package 밖의 자산을 추측해 추가 variant로 사용