키워드 프로필 사진 생성기

간단한 키워드와 배경색 선택만으로 고유한 프로필 사진을 생성할 수 있는 경량 웹 도구입니다. DiceBear API의 다양한 스타일을 활용하여 매번 다른 아바타를 생성하며, 생성된 SVG 이미지를 즉시 다운로드할 수 있습니다. 외부 라이브러리 없이 순수 Vanilla JavaScript와 HTML, CSS만으로 구현되어 있으며, 사용자 데이터를 수집하지 않습니다.

JavaScriptHTML5CSS3DiceBear APIREST APIBlob API
기간

2025.08

⚡ 키워드 프로필 사진 생성기

Micro Project | 키워드와 배경색으로 개성있는 아바타를 생성하고 다운로드하는 경량 웹 도구


🎯 프로젝트 개요

이 프로젝트는 DiceBear API를 활용한 1일 학습 실험입니다.

  • 목적: REST API 활용과 Blob API를 통한 파일 다운로드 기능 학습
  • 특징: 외부 라이브러리 없이 순수 Vanilla JavaScript로만 구현
  • 사용성: 생성된 SVG 아바타를 즉시 다운로드 가능

✨ 주요 기능

1️⃣ 아바타 생성

  • 키워드 입력: 모든 텍스트 입력값이 아바타 생성의 seed가 됨
  • 배경색 선택: 색상 선택기로 원하는 배경색 지정
  • 실시간 생성: "생성하기" 버튼으로 DiceBear API 호출
  • SVG 형식: 해상도 손실 없는 벡터 이미지 생성

2️⃣ 이미지 다운로드

  • SVG 다운로드: 생성된 이미지를 파일로 다운로드
  • Blob API 활용: 브라우저 메모리에서 파일 생성 후 다운로드
  • CORS 처리: 교차 출처 요청 안전하게 처리
  • 폴백 기능: 다운로드 실패 시 새 창에서 이미지 표시

3️⃣ 사용자 친화성

  • 프라이버시: 사용자 입력값을 저장하지 않음
  • 즉시 미리보기: 생성 결과를 바로 확인
  • 자동 초기화: 페이지 로드 시 기본값으로 자동 생성

🛠 기술 스택

분류기술
LanguageVanilla JavaScript (ES6+)
MarkupHTML5
StylingCSS3
APIDiceBear API (REST)
File DownloadBlob API, URL.createObjectURL
DeploymentTistory Blog

📚 학습 포인트

REST API 활용

const svgUrl = () =>
  `https://api.dicebear.com/9.x/${STYLE}/svg?seed=${encodeURIComponent(seed())}&backgroundColor=${hex()}`;
  • 쿼리 파라미터 구성
  • URL 인코딩 (encodeURIComponent)
  • API 응답 (SVG 이미지)

Blob API & 파일 다운로드

const blob = await res.blob();
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = `avatar-${seed()}.svg`;
document.body.appendChild(a);
a.click();
  • Fetch API로 바이너리 데이터(Blob) 수신
  • createObjectURL로 다운로드 가능한 URL 생성
  • 동적 다운로드 링크 생성 및 실행

CORS 처리

const res = await fetch(url, { mode: 'cors', cache: 'no-store' });
  • 교차 출처 요청 안전하게 처리
  • 캐시 비활성화로 항상 최신 이미지 받음
  • 에러 처리: 실패 시 새 창에서 이미지 표시

DOM 조작

const $ = (id) => document.getElementById(id);
$('generate').addEventListener('click', () => {
  // ...
});
  • 간단한 ID 선택자 헬퍼 함수
  • 이벤트 리스너 등록 및 처리
  • 동적 DOM 상태 변경 (display, disabled)

💡 코드 상세 설명

코드/개념설명
encodeURIComponent(seed())특수문자 포함된 문자열을 URL 안전 형식으로 변환
$('bgColor').value.slice(1)"#ffeeaa" → "ffeeaa" (16진수 색상코드에서 # 제거)
mode: 'cors'교차 출처 요청을 CORS 정책에 따라 처리
URL.createObjectURL(blob)메모리 내 바이너리 데이터를 다운로드 가능한 URL로 변환
Date.now() 캐시버스터쿼리문자열에 타임스탬프 추가로 브라우저 캐시 우회
disabled="disabled" 상태 관리아바타 생성 전에 다운로드 버튼 비활성화

📝 핵심 코드

// API URL 생성
const svgUrl = () =>
  `https://api.dicebear.com/9.x/${STYLE}/svg?seed=${encodeURIComponent(seed())}&backgroundColor=${hex()}`;

// 생성 버튼 클릭
$('generate').addEventListener('click', () => {
  $('preview').src = svgUrl();
  $('previewWrap').style.display = 'block';
  $('download').disabled = false;
});

// SVG 다운로드
$('download').addEventListener('click', async () => {
  const url = svgUrl() + `&_=${Date.now()}`;
  try {
    const res = await fetch(url, { mode: 'cors', cache: 'no-store' });
    const blob = await res.blob();
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = `avatar-${seed()}.svg`;
    document.body.appendChild(a);
    a.click();
    a.remove();
    URL.revokeObjectURL(a.href);
  } catch {
    window.open(url, '_blank');
  }
});

🔗 참고 자료