docs: 캐릭터 디자인 가이드, 색상 시스템, UI 에셋 가이드 및 스크립트 추가
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
260
docs/character-design-guide.md
Normal file
260
docs/character-design-guide.md
Normal file
@@ -0,0 +1,260 @@
|
||||
# Archetype-FirstSpark 캐릭터 디자인 가이드
|
||||
|
||||
## 1. 기준 스타일 (Ember_Origin.jpg 기반)
|
||||
|
||||
### 아트 디렉션
|
||||
- **스타일**: 카와이(Kawaii) 치비 + 판타지 원소 마스코트
|
||||
- **라인아트**: 2~3px 두께 다크 아웃라인 (원소 메인 컬러보다 30~40% 어두운 색)
|
||||
- **몸체 형태**: 둥글고 통통한 blob 형태, 중력을 무시하는 유체 느낌
|
||||
- **눈**: 크고 둥근 두 개의 눈 (흰 하이라이트 포함), 눈의 크기가 몸 대비 1/4~1/5
|
||||
- **표정**: 작은 미소 또는 O자 입, 귀엽고 친근한 느낌
|
||||
- **이펙트**: 원소 특성에 맞는 파티클/아우라 효과 (Ember처럼 불꽃 파편이 주변에 떠다님)
|
||||
- **패턴**: 몸체 내부에 소용돌이(swirl) 또는 원소 특성 무늬
|
||||
|
||||
### 캔버스 규격
|
||||
| 사용처 | 해상도 | 파일 형식 |
|
||||
|--------|--------|---------|
|
||||
| 원소 카드 (in-game) | 120×120px | PNG (투명 배경) |
|
||||
| 캐릭터 상세 패널 | 240×240px | PNG (투명 배경) |
|
||||
| 도감 썸네일 | 80×80px | PNG (투명 배경) |
|
||||
| 스플래시/상점 이미지 | 480×480px | PNG (흰 배경 가능) |
|
||||
|
||||
---
|
||||
|
||||
## 2. Tier별 시각적 복잡도 가이드
|
||||
|
||||
### Tier 1 — 기본 원소 (Common)
|
||||
- **원칙**: 단순하고 깨끗한 실루엣, 파티클 최소 (2~3개)
|
||||
- **색상**: 단색 또는 2~3색 그라디언트
|
||||
- **아웃라인**: 단일 컬러 아웃라인
|
||||
- **이펙트**: 없거나 아주 작은 파티클
|
||||
|
||||
### Tier 2 — 2차 원소 (Uncommon)
|
||||
- **원칙**: 복합 원소 특성이 혼합된 실루엣, 파티클 5~7개
|
||||
- **색상**: 두 부모 원소 색을 섞은 듀얼 그라디언트
|
||||
- **아웃라인**: 메인 컬러 아웃라인 + 서브 컬러 글로우 (낮은 강도)
|
||||
- **이펙트**: 부모 원소 파티클이 혼합
|
||||
|
||||
### Tier 3 — 희귀 원소 (Rare)
|
||||
- **원칙**: 독특한 실루엣, 주변 환경 이펙트 추가
|
||||
- **색상**: 풍부한 채도, 3색 그라디언트
|
||||
- **아웃라인**: 빛나는(glow) 아웃라인
|
||||
- **이펙트**: 지속적인 파티클 루프, 환경 효과 (번개, 파도 등)
|
||||
|
||||
### Tier 4 — 에픽 원소 (Epic)
|
||||
- **원칙**: 강렬하고 웅장한 존재감, 후광 효과
|
||||
- **색상**: 채도 높고 어두운 컬러, 밝은 하이라이트 대비
|
||||
- **아웃라인**: 듀얼 레이어 아웃라인 (다크 + 컬러 글로우)
|
||||
- **이펙트**: 풍부한 파티클, 회전하는 오브, 에너지 링
|
||||
|
||||
### Tier 5 — 전설 원소 (Legendary)
|
||||
- **원칙**: 압도적인 화려함, 화면을 가득 채우는 이펙트
|
||||
- **색상**: 무지개/홀로그래픽 또는 순수한 빛(흰색/금색)
|
||||
- **아웃라인**: 무지개 또는 골든 글로우
|
||||
- **이펙트**: 레인보우 파티클, 별/성좌 이펙트, 오로라
|
||||
|
||||
---
|
||||
|
||||
## 3. 원소별 캐릭터 시트
|
||||
|
||||
### Tier 1 — 기본 4원소
|
||||
|
||||
#### 🔥 불 (Fire) — "엠버"
|
||||
- **몸체**: 역삼각형 불꽃 실루엣, 주황~노랑 그라디언트
|
||||
- **컬러**: Primary `#FF4500`, Glow `#FFAA00`, Dark `#8B2000`
|
||||
- **파티클**: 불씨 3개 (랜덤 떠다니는 작은 불꽃)
|
||||
- **패턴**: 몸 중앙 스월 패턴
|
||||
- **표정 기본**: 활기차고 자신감 있는 눈매
|
||||
|
||||
#### 💧 물 (Water) — "아쿠아"
|
||||
- **몸체**: 물방울/눈물 형태, 투명도 있는 청색 계열
|
||||
- **컬러**: Primary `#1E90FF`, Glow `#87CEEB`, Dark `#00008B`
|
||||
- **파티클**: 작은 물방울 3~4개 주변에 떠다님
|
||||
- **패턴**: 몸체 내부 파문 링 패턴
|
||||
- **표정 기본**: 차분하고 맑은 눈
|
||||
|
||||
#### 🌪️ 바람 (Wind) — "브리즈"
|
||||
- **몸체**: 와류형, 투명도 있는 연한 하늘색, 가장자리가 흐릿한 느낌
|
||||
- **컬러**: Primary `#87CEEB`, Glow `#FFFFFF`, Dark `#4682B4`
|
||||
- **파티클**: 작은 선형 바람 스트로크 4~5개
|
||||
- **패턴**: 나선형 기류 패턴
|
||||
- **표정 기본**: 장난기 있고 자유로운 눈
|
||||
|
||||
#### 🌱 흙 (Earth) — "테라"
|
||||
- **몸체**: 구형, 단단하고 묵직한 느낌, 갈색 계열
|
||||
- **컬러**: Primary `#8B4513`, Glow `#D2691E`, Dark `#4B2806`
|
||||
- **파티클**: 작은 흙먼지/돌멩이 3개
|
||||
- **패턴**: 나뭇결 또는 대지 균열 패턴
|
||||
- **표정 기본**: 믿음직하고 온화한 눈
|
||||
|
||||
---
|
||||
|
||||
### Tier 2 — 주요 2차 원소 (선발)
|
||||
|
||||
#### 💨 수증기 (Steam) — "미스티"
|
||||
- **몸체**: 불과 물 중간 형태, 반투명 흰/회색 구름 느낌
|
||||
- **컬러**: Primary `#C0C0C0`, Glow `#FFFFFF`, Dark `#808080`
|
||||
- **파티클**: 위로 올라가는 수증기 6~8개
|
||||
- **패턴**: 안개처럼 흐릿한 경계
|
||||
|
||||
#### 🌋 용암 (Lava) — "마그마"
|
||||
- **몸체**: 불에 녹아내리는 구형, 갈라진 틈에서 빛이 새어나옴
|
||||
- **컬러**: Primary `#FF2200`, Glow `#FF6600`, Dark `#8B0000`, Crack `#FFAA00`
|
||||
- **파티클**: 용암 방울 4~5개 (무겁게 아래로 떨어지는 느낌)
|
||||
- **패턴**: 몸 전체에 용암 균열 라인
|
||||
|
||||
#### ⛈️ 폭풍 (Storm) — "스콜"
|
||||
- **몸체**: 물+바람 혼합, 어두운 구름 형태에 번개 흔적
|
||||
- **컬러**: Primary `#4169E1`, Glow `#6495ED`, Dark `#191970`
|
||||
- **파티클**: 비/번개 파티클 5~6개
|
||||
|
||||
#### ❄️ 얼음 (Ice) — "크리스탈린"
|
||||
- **레시피**: 물 + 물 (같은 원소 합성)
|
||||
- **몸체**: 납작한 결정체 형태, 반투명 하늘색 계열
|
||||
- **컬러**: Primary `#87CEEB`, Glow `#FFFFFF`, Dark `#5B9BD5`
|
||||
- **파티클**: 수정 파편 5~6개 (천천히 회전)
|
||||
- **패턴**: 결정 내부의 다이아몬드 문양
|
||||
|
||||
#### 🌫️ 연기 (Smoke) — "스모기"
|
||||
- **레시피**: 불 + 불 (같은 원소 합성)
|
||||
- **몸체**: 흐릿한 구름형, 회색 반투명
|
||||
- **컬러**: Primary `#808080`, Glow `#A9A9A9`, Dark `#505050`
|
||||
- **파티클**: 연기 동그라미 5~6개 (위로 흩어지는 느낌)
|
||||
- **패턴**: 소용돌이 패턴
|
||||
|
||||
---
|
||||
|
||||
### Tier 3 — 주요 희귀 원소 (선발)
|
||||
|
||||
#### ⚡ 번개 (Lightning) — "볼트"
|
||||
- **몸체**: 전기 에너지 형태, 지그재그 실루엣
|
||||
- **컬러**: Primary `#FFD700`, Glow `#FFFFFF`, Dark `#B8860B`
|
||||
- **파티클**: 전기 스파크 7~8개, 회전하는 전류링
|
||||
- **특수 이펙트**: 주기적인 방전 플래시
|
||||
|
||||
#### 🌈 무지개 (Rainbow) — "프리즘"
|
||||
- **몸체**: 아치형 또는 구형 + 7색 선형 무늬
|
||||
- **컬러**: 7색 순환 그라디언트
|
||||
- **파티클**: 무지개 빛 가루 8~10개
|
||||
|
||||
#### 💎 수정 (Crystal, Tier 4) — "크리스탈"
|
||||
- **몸체**: 다각형 결정체 형태, 빛을 굴절하는 느낌
|
||||
- **컬러**: Primary `#9400D3`, Glow `#DA70D6`, Dark `#4B0082`
|
||||
- **파티클**: 결정 파편 6~7개, 내부에서 빛나는 느낌
|
||||
|
||||
---
|
||||
|
||||
### Tier 4 — 신규 에픽 원소 (10종)
|
||||
|
||||
#### 🏔️ 빙하 (Glacier) — "글레이시아"
|
||||
- **레시피**: 구름 + 안개
|
||||
- **몸체**: 납작한 산 실루엣, 차가운 청빙색
|
||||
- **컬러**: Primary `#B8D8E8`, Glow `#AADDFF`, Dark `#7EB8D8`
|
||||
- **파티클**: 결정 파편 6~8개 (천천히 떠다님)
|
||||
|
||||
#### 🌴 정글 (Jungle) — "정글리"
|
||||
- **레시피**: 안개 + 오아시스
|
||||
- **몸체**: 풍성한 구형, 짙은 녹색
|
||||
- **컬러**: Primary `#1A6B1A`, Glow `#44BB44`, Dark `#0D3D0D`
|
||||
- **파티클**: 잎사귀 6~8개 (흩날리는 느낌)
|
||||
|
||||
#### 🏜️ 황무지 (Wasteland) — "웨이스트"
|
||||
- **레시피**: 화산재 + 먼지
|
||||
- **몸체**: 넓고 낮은 형태, 갈색 계열
|
||||
- **컬러**: Primary `#8B7355`, Glow `#A08060`, Dark `#5A4A35`
|
||||
- **파티클**: 흙먼지 입자 6~8개
|
||||
|
||||
#### 🌀 대소용돌이 (Maelstrom) — "말스트롬"
|
||||
- **레시피**: 번개 + 쓰나미
|
||||
- **몸체**: 회오리 형태, 진남색
|
||||
- **컬러**: Primary `#1E3A8A`, Glow `#4488FF`, Dark `#0A1E50`
|
||||
- **파티클**: 바람 선 + 물방울 혼합 6~8개
|
||||
|
||||
#### 💠 원석 (Gemstone) — "젬스톤"
|
||||
- **레시피**: 흑요석 + 유리
|
||||
- **몸체**: 다각형 결정체, 짙은 보라
|
||||
- **컬러**: Primary `#6B21A8`, Glow `#AA66FF`, Dark `#3D0D6B`
|
||||
- **파티클**: 수정 파편 6~8개 (회전)
|
||||
|
||||
#### 🔮 프리즘 (Prism) — "프리즈미"
|
||||
- **레시피**: 무지개 + 유리
|
||||
- **몸체**: 구형에 무지개 빛 산란 효과
|
||||
- **컬러**: Primary `#EC4899`, Glow `#FF88CC`, Rainbow 산란
|
||||
- **파티클**: 무지개 빛 입자 6~8개
|
||||
|
||||
#### 🏛️ 고대 유적 (Ruins) — "루인즈"
|
||||
- **레시피**: 화산 + 도자기
|
||||
- **몸체**: 기둥 실루엣, 바랜 갈색
|
||||
- **컬러**: Primary `#92400E`, Glow `#B8793A`, Dark `#5A2506`
|
||||
- **파티클**: 흙먼지 입자 + 균열 파편 6~8개
|
||||
|
||||
#### 🌪️ 사이클론 (Cyclone) — "사이클러"
|
||||
- **레시피**: 먼지 + 폭풍
|
||||
- **몸체**: 회오리 형태, 황금빛 갈색
|
||||
- **컬러**: Primary `#D97706`, Glow `#FFB84D`, Dark `#8B4A00`
|
||||
- **파티클**: 바람 선 + 먼지 입자 6~8개
|
||||
|
||||
#### 🌊 심해 (Deep Sea) — "아비스"
|
||||
- **레시피**: 쓰나미 + 흑요석
|
||||
- **몸체**: 구형 + 어두운 수심 느낌
|
||||
- **컬러**: Primary `#1E3A5F`, Glow `#4488BB`, Dark `#0A1828`
|
||||
- **파티클**: 물방울 6~8개 (천천히 가라앉는 느낌)
|
||||
|
||||
#### 🌾 초원 (Prairie) — "프레리"
|
||||
- **레시피**: 오아시스 + 도자기
|
||||
- **몸체**: 넓고 부드러운 구형, 황록색
|
||||
- **컬러**: Primary `#84CC16`, Glow `#AAFE44`, Dark `#4A7A0A`
|
||||
- **파티클**: 잎사귀 6~8개 (바람에 흩날림)
|
||||
|
||||
---
|
||||
|
||||
## 4. 감정 표현 가이드 (Emotion States)
|
||||
|
||||
### Idle (대기 상태)
|
||||
- 가벼운 위아래 호버링 애니메이션 (약 2초 주기)
|
||||
- 눈 깜빡임 (약 4~6초 간격)
|
||||
- 파티클 낮은 빈도로 방출
|
||||
|
||||
### 합성 시 (Fusion)
|
||||
- 눈이 반짝임 (별/☆ 형태로 변환)
|
||||
- 몸이 팽창했다가 줄어드는 pulse 효과
|
||||
- 파티클 폭발적으로 방출 (2~3배 밀도)
|
||||
- 입이 O자로 벌어짐 (놀란 표정)
|
||||
|
||||
### 강화 시 (Enhancement)
|
||||
- 눈이 활기차게 빛남 (하이라이트 증가)
|
||||
- 몸 주위에 에너지 링 회전
|
||||
- 위 방향으로 성장하는 느낌
|
||||
- 파티클이 나선형으로 올라감
|
||||
|
||||
### 잠금 해제 시 (Unlock)
|
||||
- 어두운 상태에서 점점 밝아지는 reveal 효과
|
||||
- 빛나는 aura 순간 폭발
|
||||
- 행복한 표정으로 전환
|
||||
|
||||
### 잠금 상태 (Locked)
|
||||
- 흑백 또는 낮은 채도
|
||||
- 파티클 없음
|
||||
- 눈을 가린 실루엣
|
||||
|
||||
---
|
||||
|
||||
## 5. 반응형 카드 상태별 비주얼
|
||||
|
||||
| 상태 | 배경 | 아웃라인 | 투명도 | 이펙트 |
|
||||
|------|------|---------|--------|--------|
|
||||
| obtained | 화이트 | `grey200` 1.5px solid | 100% | idle 파티클 |
|
||||
| locked | `greyBackground` | `grey200` 1.5px solid | 75% | 없음 |
|
||||
| undiscovered | `greyBackground` | `grey300` 1.5px dashed | 40% | 없음 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 등급(Rarity) 배지 컬러
|
||||
|
||||
| 등급 | 배지 컬러 | 텍스트 | 예시 |
|
||||
|------|---------|--------|------|
|
||||
| common | `#9E9E9E` | COMMON | 기본 4원소 |
|
||||
| uncommon | `#4CAF50` | UNCOMMON | Tier 2 원소 |
|
||||
| rare | `#2196F3` | RARE | Tier 3 원소 |
|
||||
| epic | `#9C27B0` | EPIC | Tier 4 원소 |
|
||||
| legendary | `#FF9800` 금색 글로우 | LEGENDARY | Tier 5 원소 |
|
||||
247
docs/color-system.md
Normal file
247
docs/color-system.md
Normal file
@@ -0,0 +1,247 @@
|
||||
# Archetype-FirstSpark 색상 시스템
|
||||
|
||||
## 1. 기반 패키지
|
||||
|
||||
```bash
|
||||
yarn add @toss/tds-colors
|
||||
```
|
||||
|
||||
`@toss/tds-colors`의 `adaptive` 네임스페이스를 기반으로, 게임 전용 시맨틱 토큰을 추가로 정의합니다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 게임 시맨틱 색상 토큰
|
||||
|
||||
### 2-A. CSS 변수 정의
|
||||
|
||||
```css
|
||||
/* src/styles/game-tokens.css */
|
||||
|
||||
/* ===== 라이트 모드 ===== */
|
||||
:root {
|
||||
/* 골드 / 재화 */
|
||||
--color-gold-primary: #FFD700;
|
||||
--color-gold-secondary: #FFAA00;
|
||||
--color-gold-bg: #FFF8E1;
|
||||
--color-gold-text: #5A3200;
|
||||
|
||||
/* 원소 등급 (Rarity) */
|
||||
--color-rarity-common: #9E9E9E;
|
||||
--color-rarity-uncommon: #4CAF50;
|
||||
--color-rarity-rare: #2196F3;
|
||||
--color-rarity-epic: #9C27B0;
|
||||
--color-rarity-legendary: #FF9800;
|
||||
|
||||
/* 합성 / 이벤트 */
|
||||
--color-fusion-primary: #7C4DFF;
|
||||
--color-fusion-glow: #B388FF;
|
||||
--color-enhance-primary: #3182F6;
|
||||
--color-enhance-glow: #90CAF9;
|
||||
|
||||
/* 원소 — Tier 1 */
|
||||
--color-element-fire: #FF4500;
|
||||
--color-element-water: #1E90FF;
|
||||
--color-element-wind: #87CEEB;
|
||||
--color-element-earth: #8B4513;
|
||||
|
||||
/* 원소 — Tier 2 */
|
||||
--color-element-steam: #C0C0C0;
|
||||
--color-element-firestorm: #FF6347;
|
||||
--color-element-lava: #FF2200;
|
||||
--color-element-storm: #4169E1;
|
||||
--color-element-mud: #8B6914;
|
||||
--color-element-desert: #DEB887;
|
||||
|
||||
/* 원소 — Tier 3 */
|
||||
--color-element-cloud: #87CEEB;
|
||||
--color-element-lightning: #FFD700;
|
||||
--color-element-volcano: #CC2200;
|
||||
--color-element-rainbow: #FF69B4;
|
||||
--color-element-obsidian: #1C1C1C;
|
||||
|
||||
/* 원소 — Tier 4 */
|
||||
--color-element-thunderstorm: #191970;
|
||||
--color-element-crystal: #9400D3;
|
||||
--color-element-life: #00FF7F;
|
||||
--color-element-aurora: #7DF9FF;
|
||||
|
||||
/* 원소 — Tier 5 */
|
||||
--color-element-creation: #FFFFFF;
|
||||
--color-element-spirit: #FFD700;
|
||||
|
||||
/* 카드 상태 */
|
||||
--color-card-bg-obtained: #FFFFFF;
|
||||
--color-card-bg-locked: var(--tds-adaptive-greyBackground);
|
||||
--color-card-border-obtained: var(--tds-adaptive-grey200);
|
||||
--color-card-border-locked: var(--tds-adaptive-grey200);
|
||||
|
||||
/* 오프라인 보상 */
|
||||
--color-offline-bg: #FFFFFF;
|
||||
--color-offline-overlay: rgba(0, 0, 0, 0.55);
|
||||
--color-offline-reward-bg: #F7F8FA;
|
||||
--color-offline-btn-from: #3182F6;
|
||||
--color-offline-btn-to: #6C4DE6;
|
||||
}
|
||||
|
||||
/* ===== 다크 모드 ===== */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* 골드 / 재화 */
|
||||
--color-gold-bg: #2A2000;
|
||||
--color-gold-text: #FFD97A;
|
||||
|
||||
/* 원소 등급 (채도 약간 낮춤, 다크에서 과도한 채도 방지) */
|
||||
--color-rarity-common: #BDBDBD;
|
||||
--color-rarity-uncommon: #66BB6A;
|
||||
--color-rarity-rare: #42A5F5;
|
||||
--color-rarity-epic: #BA68C8;
|
||||
--color-rarity-legendary: #FFA726;
|
||||
|
||||
/* 합성 / 이벤트 */
|
||||
--color-fusion-primary: #9575CD;
|
||||
--color-fusion-glow: #D1C4E9;
|
||||
--color-enhance-primary: #5C9EE8;
|
||||
--color-enhance-glow: #BBDEFB;
|
||||
|
||||
/* 카드 상태 */
|
||||
--color-card-bg-obtained: #1E1E1E;
|
||||
--color-card-bg-locked: #2A2A2A;
|
||||
|
||||
/* 오프라인 보상 */
|
||||
--color-offline-bg: #1E1E1E;
|
||||
--color-offline-overlay: rgba(0, 0, 0, 0.72);
|
||||
--color-offline-reward-bg: #2A2A2A;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. TypeScript 토큰 상수
|
||||
|
||||
```ts
|
||||
// src/styles/gameColors.ts
|
||||
import { adaptive } from '@toss/tds-colors';
|
||||
|
||||
/** 게임 전용 시맨틱 색상 상수 */
|
||||
export const gameColors = {
|
||||
// ── 재화 ──────────────────────────────────────────────
|
||||
goldPrimary: '#FFD700',
|
||||
goldSecondary: '#FFAA00',
|
||||
goldBg: '#FFF8E1', // 다크: var(--color-gold-bg) 사용
|
||||
goldText: '#5A3200',
|
||||
|
||||
// ── 등급 ──────────────────────────────────────────────
|
||||
rarityCommon: '#9E9E9E',
|
||||
rarityUncommon: '#4CAF50',
|
||||
rarityRare: '#2196F3',
|
||||
rarityEpic: '#9C27B0',
|
||||
rarityLegendary: '#FF9800',
|
||||
|
||||
// ── 이벤트 ────────────────────────────────────────────
|
||||
fusionPrimary: '#7C4DFF',
|
||||
fusionGlow: '#B388FF',
|
||||
enhancePrimary: '#3182F6',
|
||||
enhanceGlow: '#90CAF9',
|
||||
|
||||
// ── 원소별 주요 색 ─────────────────────────────────────
|
||||
elements: {
|
||||
fire: '#FF4500',
|
||||
water: '#1E90FF',
|
||||
wind: '#87CEEB',
|
||||
earth: '#8B4513',
|
||||
steam: '#C0C0C0',
|
||||
firestorm: '#FF6347',
|
||||
lava: '#FF2200',
|
||||
storm: '#4169E1',
|
||||
mud: '#8B6914',
|
||||
desert: '#DEB887',
|
||||
cloud: '#87CEEB',
|
||||
fog: '#DCDCDC',
|
||||
volcano: '#CC2200',
|
||||
rainbow: '#FF69B4',
|
||||
obsidian: '#1C1C1C',
|
||||
ash: '#696969',
|
||||
lightning: '#FFD700',
|
||||
tsunami: '#006994',
|
||||
ceramic: '#D2691E',
|
||||
dust: '#BC8F5F',
|
||||
oasis: '#228B22',
|
||||
glass: '#E0FFFF',
|
||||
thunderstorm: '#191970',
|
||||
island: '#3CB371',
|
||||
crystal: '#9400D3',
|
||||
life: '#00FF7F',
|
||||
magnet: '#A9A9A9',
|
||||
aurora: '#7DF9FF',
|
||||
creation: '#FFFFFF',
|
||||
spirit: '#FFD700',
|
||||
},
|
||||
|
||||
// ── TDS Adaptive 색 (자주 쓰는 것만 재노출) ─────────────
|
||||
bg: adaptive.background,
|
||||
greyBg: adaptive.greyBackground,
|
||||
grey200: adaptive.grey200,
|
||||
grey400: adaptive.grey400,
|
||||
grey500: adaptive.grey500,
|
||||
grey900: adaptive.grey900,
|
||||
blue500: adaptive.blue500,
|
||||
} as const;
|
||||
|
||||
/** 등급 → 색상 매핑 헬퍼 */
|
||||
export function rarityColor(rarity: string): string {
|
||||
return {
|
||||
common: gameColors.rarityCommon,
|
||||
uncommon: gameColors.rarityUncommon,
|
||||
rare: gameColors.rarityRare,
|
||||
epic: gameColors.rarityEpic,
|
||||
legendary: gameColors.rarityLegendary,
|
||||
}[rarity] ?? gameColors.rarityCommon;
|
||||
}
|
||||
|
||||
/** 원소 ID → 주요 색상 헬퍼 */
|
||||
export function elementColor(id: string): string {
|
||||
return gameColors.elements[id as keyof typeof gameColors.elements] ?? '#888888';
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 다크모드 대응 규칙
|
||||
|
||||
| 규칙 | 설명 |
|
||||
|------|------|
|
||||
| 배경/텍스트 | `adaptive.*` 사용 (자동 대응) |
|
||||
| 원소 고유 컬러 | 다크모드에서 그대로 사용 (원소 아이덴티티 유지) |
|
||||
| 골드/재화 | CSS 변수 `--color-gold-*` 사용 (다크에서 어두운 배경) |
|
||||
| 이펙트/글로우 | 다크에서 밝기 70~80%로 감소 (눈부심 방지) |
|
||||
| 오버레이 | 다크에서 `rgba(0,0,0,0.72)` (라이트보다 진하게) |
|
||||
|
||||
### emotion/css에서 다크모드 처리 패턴
|
||||
|
||||
```tsx
|
||||
import { css } from '@emotion/react';
|
||||
import { adaptive } from '@toss/tds-colors';
|
||||
|
||||
// adaptive를 사용하면 다크모드 자동 대응
|
||||
const cardStyle = css`
|
||||
background: ${adaptive.background};
|
||||
color: ${adaptive.grey900};
|
||||
border: 1px solid ${adaptive.grey200};
|
||||
`;
|
||||
|
||||
// 게임 전용 색은 CSS 변수 사용
|
||||
const goldBadgeStyle = css`
|
||||
background: linear-gradient(135deg, var(--color-gold-primary), var(--color-gold-secondary));
|
||||
color: var(--color-gold-text);
|
||||
`;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 색상 접근성 체크리스트
|
||||
|
||||
- [ ] 텍스트 대비비 4.5:1 이상 (WCAG AA)
|
||||
- [ ] 색 외 다른 시각적 단서 병행 (아이콘, 패턴)
|
||||
- [ ] 등급 구분: 색 + 배지 텍스트 병행
|
||||
- [ ] 원소 카드: 색 + 이모지 병행
|
||||
279
docs/ui-asset-guide.md
Normal file
279
docs/ui-asset-guide.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# Archetype-FirstSpark UI 에셋 가이드
|
||||
|
||||
## 1. 상점 아이템 아이콘 디자인 스펙
|
||||
|
||||
### 아이콘 규격
|
||||
- **크기**: 64×64px (in-game), 36px (리스트 뷰)
|
||||
- **배경**: 투명 또는 반경 12px 라운드 박스
|
||||
- **스타일**: Ember_Origin 캐릭터와 동일한 카와이 치비 스타일
|
||||
|
||||
### 현재 상점 아이템 → 디자인 스펙
|
||||
|
||||
| 아이템 ID | 이름 | 이모지 | 아이콘 컨셉 | 주 색상 |
|
||||
|-----------|------|--------|-----------|--------|
|
||||
| `fire_boost` | 불꽃 강화석 | 🔥 | 불꽃 문양이 새겨진 붉은 보석 | `#FF4500` → `#FFAA00` 그라디언트 |
|
||||
| `water_boost` | 물방울 강화석 | 💧 | 물결 문양 파란 보석 | `#1E90FF` → `#87CEEB` 그라디언트 |
|
||||
| `fusion_scroll` | 합성 두루마리 | 📜 | 원소 문양이 빛나는 양피지 | `#DEB887`, `#FFD700` 잉크 |
|
||||
| `gold_bag` | 골드 주머니 | 👝 | 빵빵하게 부푼 황금 주머니 | `#FFD700`, `#FF8C00` |
|
||||
|
||||
### 추가 예정 상점 아이템 (기획 확장용)
|
||||
|
||||
| 아이템 ID | 이름 | 아이콘 컨셉 | 설명 |
|
||||
|-----------|------|-----------|------|
|
||||
| `exp_crystal` | 경험치 수정 | 빛나는 보라 결정체 | 원소 EXP +100 |
|
||||
| `speed_potion` | 속도 물약 | 회오리치는 파란 약병 | 생산 속도 2배 (30분) |
|
||||
| `offline_booster` | 오프라인 부스터 | 달과 별이 새겨진 아이템 | 오프라인 보상 2배 |
|
||||
| `discovery_ticket` | 발견 티켓 | 빛나는 황금 입장권 | 랜덤 Tier 3 원소 즉시 해금 |
|
||||
| `legendary_shard` | 전설 파편 | 홀로그래픽 보석 조각 | 전설 원소 합성 확률 +5% |
|
||||
|
||||
### 상점 아이콘 박스 스펙 (컴포넌트 레벨)
|
||||
|
||||
```tsx
|
||||
// 상점 아이콘 래퍼 (아이템 등급에 따른 배경 글로우)
|
||||
const shopIconBoxStyle = (rarity: string) => css`
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36px;
|
||||
background: ${
|
||||
rarity === 'legendary' ? 'linear-gradient(135deg, #FF9800, #FFD700)' :
|
||||
rarity === 'epic' ? 'linear-gradient(135deg, #7B1FA2, #9C27B0)' :
|
||||
rarity === 'rare' ? 'linear-gradient(135deg, #1565C0, #2196F3)' :
|
||||
rarity === 'uncommon' ? 'linear-gradient(135deg, #2E7D32, #4CAF50)' :
|
||||
'linear-gradient(135deg, #616161, #9E9E9E)'
|
||||
};
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
`;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 도감 뱃지 디자인 (발견율 마일스톤)
|
||||
|
||||
### 뱃지 규격
|
||||
- **크기**: 48×48px (도감 화면 내), 24×24px (프로필 미니 뱃지)
|
||||
- **형태**: 육각형 또는 방패 형태 (수집/달성의 느낌)
|
||||
- **스타일**: 금속성 질감, 원소 문양 새김
|
||||
|
||||
### 마일스톤 뱃지 목록
|
||||
|
||||
| 달성 조건 | 뱃지 이름 | 디자인 | 색상 |
|
||||
|----------|----------|--------|------|
|
||||
| 원소 1개 획득 | 첫 번째 불꽃 | 불꽃 모양 동판 뱃지 | Bronze `#CD7F32` |
|
||||
| 원소 5개 획득 | 원소 탐험가 | 나침반 모양 은판 뱃지 | Silver `#C0C0C0` |
|
||||
| 원소 10개 획득 | 중급 연금술사 | 플라스크 + 별 뱃지 | Silver `#C0C0C0` |
|
||||
| 원소 15개 획득 | 고급 연금술사 | 빛나는 금판 + 원소기호 | Gold `#FFD700` |
|
||||
| 원소 20개 획득 | 원소 마스터 | 왕관 + 4원소 합체 뱃지 | Gold `#FFD700` 글로우 |
|
||||
| 원소 25개 획득 | 대현자 | 크리스탈 구슬 뱃지 | Purple `#9C27B0` |
|
||||
| 원소 30개 전부 획득 | 세계의 창조자 | 무지개 오로라 뱃지 | Rainbow 홀로그래픽 |
|
||||
|
||||
### 뱃지 미획득/획득 상태
|
||||
|
||||
```tsx
|
||||
const badgeContainerStyle = (achieved: boolean) => css`
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 28px;
|
||||
background: ${achieved ? 'linear-gradient(135deg, #FFF8E1, #FFE082)' : adaptive.greyBackground};
|
||||
border: 2px solid ${achieved ? '#FFD700' : adaptive.grey300};
|
||||
opacity: ${achieved ? 1 : 0.4};
|
||||
filter: ${achieved ? 'none' : 'grayscale(100%)'};
|
||||
box-shadow: ${achieved ? '0 0 8px rgba(255, 215, 0, 0.4)' : 'none'};
|
||||
`;
|
||||
```
|
||||
|
||||
### 도감 화면 발견률 시각화
|
||||
|
||||
```
|
||||
발견 진행 바:
|
||||
[████████░░░░░░░░░░░] 8/30 (26.7%)
|
||||
|
||||
색상 구간:
|
||||
0~33% → grey gradient (초보)
|
||||
34~66% → blue gradient (중급)
|
||||
67~99% → purple gradient (고급)
|
||||
100% → rainbow gradient (전설)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 오프라인 보상 모달 비주얼 개선
|
||||
|
||||
### 현재 구현의 개선 포인트
|
||||
1. 흰 배경 모달 → **배경에 밤하늘 + 별 이미지 또는 달 모티프 추가**
|
||||
2. 단색 버튼 → **그라디언트 유지하되 별/달 아이콘 추가**
|
||||
3. 보상 아이템 배경 `#F7F8FA` → **adaptive 색상으로 다크모드 대응**
|
||||
4. 타이틀 이모지만 → **달과 별이 조합된 헤더 비주얼 추가**
|
||||
|
||||
### 개선된 스타일 스펙
|
||||
|
||||
```tsx
|
||||
// 모달 헤더 영역
|
||||
const offlineHeaderStyle = css`
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
// 달 아이콘 + 별 파티클 영역
|
||||
const moonIconWrapStyle = css`
|
||||
font-size: 48px;
|
||||
line-height: 1;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
/* 별 파티클은 CSS animation으로 처리 */
|
||||
position: relative;
|
||||
|
||||
&::before, &::after {
|
||||
content: '✦';
|
||||
position: absolute;
|
||||
font-size: 14px;
|
||||
color: #FFD700;
|
||||
animation: starTwinkle 2s ease-in-out infinite alternate;
|
||||
}
|
||||
&::before { top: 0; left: 20%; }
|
||||
&::after { top: 10%; right: 15%; animation-delay: 0.7s; }
|
||||
`;
|
||||
|
||||
// 개선된 모달 배경
|
||||
const modalStyle = css`
|
||||
background: ${adaptive.background};
|
||||
border-radius: 24px;
|
||||
padding: 28px 24px 24px;
|
||||
width: 100%;
|
||||
max-width: 340px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
|
||||
/* 상단 별밤 느낌 장식 */
|
||||
background-image: radial-gradient(
|
||||
circle at 50% 0%,
|
||||
rgba(124, 77, 255, 0.08) 0%,
|
||||
transparent 60%
|
||||
);
|
||||
`;
|
||||
|
||||
// 보상 아이템 배경 (다크 대응)
|
||||
const rewardItemStyle = css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background: ${adaptive.greyBackground};
|
||||
border-radius: 12px;
|
||||
padding: 10px 14px;
|
||||
`;
|
||||
|
||||
// 수령 버튼 개선
|
||||
const claimButtonStyle = css`
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
background: linear-gradient(135deg, #3182F6, #7C4DFF);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
/* 버튼 내부 반짝임 효과 */
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -50%;
|
||||
left: -50%;
|
||||
width: 200%;
|
||||
height: 200%;
|
||||
background: linear-gradient(
|
||||
45deg,
|
||||
transparent 40%,
|
||||
rgba(255,255,255,0.15) 50%,
|
||||
transparent 60%
|
||||
);
|
||||
animation: shimmer 2.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.97);
|
||||
}
|
||||
`;
|
||||
|
||||
// 골드 보상 행 (다크 대응)
|
||||
const goldRowStyle = css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
background: linear-gradient(135deg, var(--color-gold-bg, #FFF8E1), #FFF3CD);
|
||||
border-radius: 12px;
|
||||
padding: 10px 14px;
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
```
|
||||
|
||||
### 타이틀 섹션 개선 (JSX)
|
||||
|
||||
```tsx
|
||||
// 개선된 모달 상단부
|
||||
<div css={offlineHeaderStyle}>
|
||||
<span css={moonIconWrapStyle}>🌙</span>
|
||||
<h2 css={titleStyle}>오프라인 보상</h2>
|
||||
<p css={subtitleStyle}>
|
||||
{formatDuration(pendingOfflineReward.offlineSec)} 동안<br/>
|
||||
원소가 자동 수집되었습니다!
|
||||
</p>
|
||||
</div>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 화면별 UI 에셋 요약
|
||||
|
||||
| 화면 | 주요 에셋 | 우선순위 |
|
||||
|------|----------|---------|
|
||||
| ShopScreen | 상점 아이템 아이콘 (고화질 PNG) | High |
|
||||
| ElementsScreen | 도감 뱃지 시스템 | Medium |
|
||||
| OfflineRewardModal | 달/별 헤더 이미지, 개선된 버튼 | Medium |
|
||||
| FusionScreen | 합성 이펙트 파티클 | High |
|
||||
| EvolutionScreen | 강화 에너지 링 이펙트 | Medium |
|
||||
|
||||
---
|
||||
|
||||
## 5. 애니메이션 스펙 (CSS Keyframes)
|
||||
|
||||
```css
|
||||
@keyframes starTwinkle {
|
||||
from { opacity: 0.3; transform: scale(0.8); }
|
||||
to { opacity: 1.0; transform: scale(1.2); }
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { transform: translateX(-100%) rotate(45deg); }
|
||||
100% { transform: translateX(100%) rotate(45deg); }
|
||||
}
|
||||
|
||||
@keyframes elementIdle {
|
||||
0%, 100% { transform: translateY(0px); }
|
||||
50% { transform: translateY(-4px); }
|
||||
}
|
||||
|
||||
@keyframes fusionPulse {
|
||||
0% { transform: scale(1); }
|
||||
50% { transform: scale(1.12); }
|
||||
100% { transform: scale(1); }
|
||||
}
|
||||
|
||||
@keyframes enhanceRing {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes rarityGlow {
|
||||
0%, 100% { box-shadow: 0 0 6px currentColor; }
|
||||
50% { box-shadow: 0 0 16px currentColor, 0 0 32px currentColor; }
|
||||
}
|
||||
```
|
||||
207
scripts/generate_icon.py
Normal file
207
scripts/generate_icon.py
Normal file
@@ -0,0 +1,207 @@
|
||||
"""
|
||||
Archetype: First Spark - App Icon Generator
|
||||
1024x1024 PNG 앱 아이콘 생성 스크립트
|
||||
주 색상: #FF6B35 (불꽃-주황)
|
||||
"""
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFilter
|
||||
import math
|
||||
|
||||
def hex_to_rgb(hex_color):
|
||||
hex_color = hex_color.lstrip('#')
|
||||
return tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
|
||||
|
||||
def create_app_icon(size=1024, output_path="app-icon.png"):
|
||||
img = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# === 배경: 깊은 다크 네이비 → 다크 퍼플 그라디언트 ===
|
||||
bg = Image.new('RGBA', (size, size))
|
||||
bg_draw = ImageDraw.Draw(bg)
|
||||
for y in range(size):
|
||||
t = y / size
|
||||
# #0D0D1A (top) → #1A0A2E (bottom)
|
||||
r = int(13 + (26 - 13) * t)
|
||||
g = int(13 + (10 - 13) * t)
|
||||
b = int(26 + (46 - 26) * t)
|
||||
bg_draw.line([(0, y), (size, y)], fill=(r, g, b, 255))
|
||||
img = Image.alpha_composite(img, bg)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
cx, cy = size // 2, size // 2
|
||||
|
||||
# === 외곽 글로우 링 (주황빛 오라) ===
|
||||
glow_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
glow_draw = ImageDraw.Draw(glow_layer)
|
||||
for i in range(12, 0, -1):
|
||||
alpha = int(15 * (i / 12))
|
||||
radius = int(size * 0.42) + i * 8
|
||||
glow_draw.ellipse(
|
||||
[cx - radius, cy - radius, cx + radius, cy + radius],
|
||||
fill=(255, 107, 53, alpha)
|
||||
)
|
||||
img = Image.alpha_composite(img, glow_layer)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# === 메인 원형 배경 (진한 그라디언트 구체) ===
|
||||
circle_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
circle_draw = ImageDraw.Draw(circle_layer)
|
||||
base_r = int(size * 0.42)
|
||||
for i in range(base_r, 0, -1):
|
||||
t = 1 - (i / base_r)
|
||||
# 어두운 중심부에서 불꽃 주황으로
|
||||
r = int(20 + (120 - 20) * (1 - t**2))
|
||||
g = int(8 + (40 - 8) * (1 - t**2))
|
||||
b = int(35 + (15 - 35) * (1 - t**2))
|
||||
circle_draw.ellipse(
|
||||
[cx - i, cy - i, cx + i, cy + i],
|
||||
fill=(r, g, b, 255)
|
||||
)
|
||||
img = Image.alpha_composite(img, circle_layer)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# === 불꽃 파티클 (배경 장식) ===
|
||||
spark_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
spark_draw = ImageDraw.Draw(spark_layer)
|
||||
sparks = [
|
||||
(cx - 180, cy - 200, 6, 180),
|
||||
(cx + 200, cy - 160, 5, 160),
|
||||
(cx - 220, cy + 100, 4, 140),
|
||||
(cx + 180, cy + 180, 5, 150),
|
||||
(cx - 60, cy - 280, 7, 200),
|
||||
(cx + 80, cy - 260, 6, 180),
|
||||
(cx - 260, cy - 40, 4, 130),
|
||||
(cx + 260, cy - 60, 5, 150),
|
||||
(cx - 100, cy + 270, 6, 160),
|
||||
(cx + 120, cy + 260, 4, 140),
|
||||
]
|
||||
for sx, sy, sr, alpha in sparks:
|
||||
for gi in range(sr, 0, -1):
|
||||
ga = int(alpha * (gi / sr) ** 2)
|
||||
spark_draw.ellipse(
|
||||
[sx - gi, sy - gi, sx + gi, sy + gi],
|
||||
fill=(255, 180, 80, ga)
|
||||
)
|
||||
img = Image.alpha_composite(img, spark_layer)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# === 중앙 불꽃 형상 (메인 심볼) ===
|
||||
flame_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
flame_draw = ImageDraw.Draw(flame_layer)
|
||||
|
||||
# 불꽃 외형 (여러 레이어로 깊이 표현)
|
||||
# 레이어 1: 큰 불꽃 (오렌지-레드)
|
||||
flame1 = [
|
||||
(cx, cy - 270), # 꼭대기
|
||||
(cx + 120, cy - 140), # 오른쪽 상단
|
||||
(cx + 160, cy + 30), # 오른쪽 중간
|
||||
(cx + 90, cy + 200), # 오른쪽 하단
|
||||
(cx, cy + 240), # 바닥 중앙
|
||||
(cx - 90, cy + 200), # 왼쪽 하단
|
||||
(cx - 160, cy + 30), # 왼쪽 중간
|
||||
(cx - 120, cy - 140), # 왼쪽 상단
|
||||
]
|
||||
flame_draw.polygon(flame1, fill=(255, 90, 20, 230))
|
||||
|
||||
# 레이어 2: 중간 불꽃 (밝은 오렌지)
|
||||
flame2 = [
|
||||
(cx, cy - 220),
|
||||
(cx + 90, cy - 100),
|
||||
(cx + 120, cy + 40),
|
||||
(cx + 60, cy + 180),
|
||||
(cx, cy + 200),
|
||||
(cx - 60, cy + 180),
|
||||
(cx - 120, cy + 40),
|
||||
(cx - 90, cy - 100),
|
||||
]
|
||||
flame_draw.polygon(flame2, fill=(255, 140, 40, 220))
|
||||
|
||||
# 레이어 3: 내부 불꽃 (밝은 노란 오렌지)
|
||||
flame3 = [
|
||||
(cx, cy - 160),
|
||||
(cx + 60, cy - 60),
|
||||
(cx + 80, cy + 60),
|
||||
(cx + 35, cy + 150),
|
||||
(cx, cy + 160),
|
||||
(cx - 35, cy + 150),
|
||||
(cx - 80, cy + 60),
|
||||
(cx - 60, cy - 60),
|
||||
]
|
||||
flame_draw.polygon(flame3, fill=(255, 200, 80, 210))
|
||||
|
||||
# 레이어 4: 핵심 (흰색-노란색 빛)
|
||||
flame4 = [
|
||||
(cx, cy - 80),
|
||||
(cx + 30, cy - 20),
|
||||
(cx + 40, cy + 50),
|
||||
(cx, cy + 80),
|
||||
(cx - 40, cy + 50),
|
||||
(cx - 30, cy - 20),
|
||||
]
|
||||
flame_draw.polygon(flame4, fill=(255, 240, 180, 200))
|
||||
|
||||
# 중심 빛 (흰색 글로우)
|
||||
for i in range(30, 0, -1):
|
||||
alpha = int(180 * (i / 30) ** 2)
|
||||
flame_draw.ellipse(
|
||||
[cx - i, cy + 10 - i, cx + i, cy + 10 + i],
|
||||
fill=(255, 255, 240, alpha)
|
||||
)
|
||||
|
||||
# 불꽃 블러 (부드럽게)
|
||||
flame_blurred = flame_layer.filter(ImageFilter.GaussianBlur(radius=3))
|
||||
img = Image.alpha_composite(img, flame_blurred)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# === 원소 심볼 (아크 형태의 빛나는 링) ===
|
||||
arc_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
arc_draw = ImageDraw.Draw(arc_layer)
|
||||
|
||||
# 4개의 원소 호 (불, 물, 바람, 땅 의미)
|
||||
ring_r = int(size * 0.35)
|
||||
element_colors = [
|
||||
(255, 80, 20, 180), # 불
|
||||
(60, 160, 255, 160), # 물
|
||||
(160, 240, 120, 140), # 바람
|
||||
(200, 160, 60, 150), # 땅
|
||||
]
|
||||
for i, color in enumerate(element_colors):
|
||||
start_angle = i * 90 - 30
|
||||
end_angle = start_angle + 60
|
||||
for w in range(6, 0, -1):
|
||||
arc_draw.arc(
|
||||
[cx - ring_r - w, cy - ring_r - w, cx + ring_r + w, cy + ring_r + w],
|
||||
start=start_angle, end=end_angle,
|
||||
fill=(*color[:3], int(color[3] * w / 6)),
|
||||
width=w * 2
|
||||
)
|
||||
|
||||
arc_blurred = arc_layer.filter(ImageFilter.GaussianBlur(radius=2))
|
||||
img = Image.alpha_composite(img, arc_blurred)
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# === 상단 광택 효과 (입체감) ===
|
||||
gloss_layer = Image.new('RGBA', (size, size), (0, 0, 0, 0))
|
||||
gloss_draw = ImageDraw.Draw(gloss_layer)
|
||||
gloss_r = int(size * 0.38)
|
||||
gloss_draw.ellipse(
|
||||
[cx - gloss_r, cy - gloss_r, cx + gloss_r, cy - gloss_r // 3],
|
||||
fill=(255, 255, 255, 25)
|
||||
)
|
||||
gloss_blurred = gloss_layer.filter(ImageFilter.GaussianBlur(radius=20))
|
||||
img = Image.alpha_composite(img, gloss_blurred)
|
||||
|
||||
# === 저장 ===
|
||||
final = img.convert('RGBA')
|
||||
final.save(output_path, 'PNG', optimize=True)
|
||||
print(f"[OK] 아이콘 저장: {output_path} ({size}x{size}px)")
|
||||
return final
|
||||
|
||||
# 1024x1024 메인 아이콘
|
||||
create_app_icon(1024, "C:/Users/jaeoh/Desktop/workspace/Archetype-FirstSpark/app-icon.png")
|
||||
|
||||
# 512x512 앱스토어용
|
||||
icon_1024 = Image.open("C:/Users/jaeoh/Desktop/workspace/Archetype-FirstSpark/app-icon.png")
|
||||
icon_512 = icon_1024.resize((512, 512), Image.LANCZOS)
|
||||
icon_512.save("C:/Users/jaeoh/Desktop/workspace/Archetype-FirstSpark/app-icon-512.png", 'PNG', optimize=True)
|
||||
print("[OK] 512x512 앱스토어용 저장 완료")
|
||||
Reference in New Issue
Block a user