# Figma → HTML 블록 변환 프로세스 > 2026-04-07 확립. Figma 디자인을 design_agent 블록으로 변환하는 정확한 방법론. --- ## 1. 전체 워크플로우 ``` [Step 1] Figma API로 파일 구조 추출 ↓ [Step 2] 프레임별 렌더링 이미지(PNG) 다운로드 ↓ [Step 3] 노드별 상세 데이터 추출 (좌표, 색상, 폰트, 크기) ↓ [Step 4] 디자인 언어 분석 (공통 패턴 vs 콘텐츠 전용 구분) ↓ [Step 5] 블록 설계 (슬롯, 동적 규칙, schema) ↓ [Step 6] 수학적 계산 (Figma 좌표 → 스케일 → CSS값) ↓ [Step 7] HTML/CSS 구현 ↓ [Step 8] 비교 리뷰 (Figma PNG vs HTML, 같은 폭으로 위/아래 배치) ↓ [Step 9] 피드백 반영 → Step 6~8 반복 ↓ [Step 10] Jinja2 템플릿화 + catalog.yaml 등록 ``` --- ## 2. Figma API 사용법 ### 2.1 파일 구조 가져오기 ```bash curl -s -H "X-Figma-Token: {TOKEN}" \ "https://api.figma.com/v1/files/{FILE_KEY}" \ | python -m json.tool ``` ### 2.2 특정 노드 상세 데이터 ```bash curl -s -H "X-Figma-Token: {TOKEN}" \ "https://api.figma.com/v1/files/{FILE_KEY}/nodes?ids={NODE_IDS}&geometry=paths" ``` ### 2.3 노드 이미지 렌더링 (PNG) ```bash curl -s -H "X-Figma-Token: {TOKEN}" \ "https://api.figma.com/v1/images/{FILE_KEY}?ids={NODE_IDS}&format=png&scale=2" ``` - `scale=2`: 2배 해상도로 다운로드 (선명도 확보) - 응답의 `images` 객체에 각 노드 ID별 S3 URL 제공 ### 2.4 추출해야 하는 핵심 데이터 | 데이터 | API 필드 | 용도 | |-------|---------|------| | 위치 | `absoluteBoundingBox.x, .y` | 요소 간 관계 계산 | | 크기 | `absoluteBoundingBox.width, .height` | 스케일 계산 | | 텍스트 | `characters` | 콘텐츠 확인 | | 폰트 | `style.fontFamily, .fontSize, .fontWeight` | 타이포그래피 | | 색상 | `fills[].color` | 색상 팔레트 | | 테두리 | `strokes[], strokeWeight` | 박스 스타일 | | 라운드 | `cornerRadius` | border-radius | | 이미지 | `fills[].imageRef` | 이미지 자산 식별 | --- ## 3. 수학적 계산 (핵심) ### 3.1 스케일 팩터 ``` 슬라이드 콘텐츠 폭 = 1280px - padding(40px × 2) = 1200px scale = 1200 / figma_frame_width ``` | Figma 프레임 | 폭 | 스케일 | |-------------|-----|--------| | Frame 2 | 1808px | 0.6637 | | Frame 3 | 1807px | 0.6641 | | Frame 4 | 3848px | 0.3118 | ### 3.2 요소 간 정렬 계산 **절대 원칙: Figma 좌표 차이값 → 스케일 적용 → CSS값** ```python # 예: 리본 접힘선과 박스 테두리 정렬 badge_y = 1431 # Figma에서 badge 이미지 top Y box_y = 1449 # Figma에서 box top Y fold_offset = box_y - badge_y # = 18px (Figma 기준) # 스케일 적용 fold_offset_css = round(fold_offset * scale) # = 12px (CSS) ``` **금지: "좀 더 올려볼게요" 식의 시행착오 px 조정** ### 3.3 이미지 자산 크기 계산 ```python # Figma 원본 크기에 스케일 적용 ribbon_width_css = round(badge_img_width * scale) ribbon_height_css = round(badge_img_height * scale) # 비율 계산 (CSS에서 width만 지정하면 height는 자동) aspect_ratio = badge_img_width / badge_img_height ``` ### 3.4 패딩/여백 계산 ```python # 리본이 박스 안에 들어오는 높이 = 리본 전체 높이 - 접힘선 오프셋 ribbon_inside_box = ribbon_height_css - fold_offset_css # 박스 상단 패딩 = 리본 침입 높이 + 여유 box_padding_top = ribbon_inside_box + 6 # 6px 여유 ``` ### 3.5 실제 계산 예시 (Frame 2) ``` 입력 (Figma 원본): badge 이미지: 508×94px, y=1431 box: y=1449 frame width: 1808px 계산: scale = 1200/1808 = 0.6637 ribbon_w = 508 × 0.6637 = 337px ribbon_h = 94 × 0.6637 = 62px fold_offset = (1449-1431) × 0.6637 = 12px ribbon_below_fold = 62 - 12 = 50px box_padding_top = 50 + 6 = 56px CSS 출력: .ribbon { width: 337px; top: -12px; } .box { padding-top: 56px; } ``` --- ## 4. 이미지 자산 처리 ### 4.1 CSS로 만들면 안 되는 것 | 요소 | 이유 | 처리 | |------|------|------| | 3D 리본/두루마리 | 입체감, 그림자, 곡면 → CSS 불가 | Figma에서 PNG 추출 | | 복잡한 그라디언트 배경 | 다중 정지점, 비선형 → CSS 근사 불가 | 이미지 사용 | | 아이콘 이미지 | 디자이너가 만든 고유 자산 | 원본 이미지 사용 | ### 4.2 CSS로 만들 수 있는 것 | 요소 | CSS 구현 | |------|---------| | 단색/2색 그라디언트 배경 | `linear-gradient()` | | 둥근 모서리 테두리 박스 | `border + border-radius` | | 텍스트 스타일 | `font-size, font-weight, color` | | 그리드/플렉스 레이아웃 | `display: grid / flex` | | 구분선 | `border` or `background` | ### 4.3 이미지 추출 및 저장 ```bash # Figma API로 특정 노드 이미지 추출 curl -s -H "X-Figma-Token: {TOKEN}" \ "https://api.figma.com/v1/images/{FILE_KEY}?ids={NODE_ID}&format=png&scale=2" # 다운로드 → static/figma-assets/ 에 저장 curl -s -o static/figma-assets/{name}.png "{S3_URL}" ``` 저장 위치: `static/figma-assets/` --- ## 5. 비교 리뷰 페이지 작성법 ### 5.1 레이아웃 ``` 같은 폭으로 위/아래 배치 (좌/우 아님 — 크기 차이 문제) ┌─ 빨간 테두리 ──────────────┐ │ Figma Original (PNG) │ └─────────────────────────────┘ ─ 구분선 ─ ┌─ 초록 테두리 ──────────────┐ │ HTML Block │ └─────────────────────────────┘ ``` ### 5.2 HTML 스케일링 ```css .html-inner { width: 1280px; /* 슬라이드 원본 크기 */ transform-origin: top left; transform: scale(0.74); /* 960px 컨테이너에 맞춤: 960/1280 */ } ``` ### 5.3 비교 리뷰 파일 위치 `data/figma_ref/comparison.html` --- ## 6. Jinja2 템플릿 변환 규칙 ### 6.1 고정값 → 변수 ```html 정책 달성 → {{ badge_title }} Engn. Solution → {{ left_title }} ``` ### 6.2 반복 요소 → 루프 ```html {% for card in cards %}
```
### 6.4 계산된 CSS → CSS 변수
```html