텍스트 커스터마이징 기능을 구현한 과정이다.
주요 기능
- 텍스트 스타일
- 굵게, 이탤릭, 그림자 효과 추가
- 텍스트 색상 변경
- 텍스트 레이아웃
- 정렬 옵션 (왼쪽, 중앙, 오른쪽 정렬)
- 제목과 부제목 크기 조절
- 폰트 선택
- Gmarket Sans, 나눔스퀘어 네오, Pretendard
1. 텍스트 입력과 스타일링
사용자가 입력한 텍스트를 상태로 관리하며 스타일을 바로바로 조정할 수 있도록 했다.
<Input
type="text"
value={text}
onChange={(e) => setText(e.target.value)}
placeholder="Enter text"
className="flex-grow"
/>
<Toggle
pressed={isBold}
onPressedChange={setIsBold}
aria-label="Toggle bold"
>
<Bold className="w-4 h-4" />
</Toggle>
<Toggle
pressed={isItalic}
onPressedChange={setIsItalic}
aria-label="Toggle italic"
>
<Italic className="w-4 h-4" />
</Toggle>
<Input
type="color"
value={textColor}
onChange={(e) => setTextColor(e.target.value)}
className="w-10 h-10 p-1 rounded"
/>- 텍스트 상태를
text로 관리하고, 굵기와 기울임 여부를isBold,isItalic상태로 관리했다. Input컴포넌트로 텍스트와 색상을 입력받고,Toggle컴포넌트로 스타일 옵션을 적용했다.
2. 텍스트 레이아웃
텍스트를 왼쪽, 중앙, 오른쪽으로 정렬할 수 있게 버튼을 구성했다.
<Button
variant={textStyle.align === "left" ? "default" : "outline"}
onClick={() => handleTextStyleChange("align", "left")}
className="flex-1"
>
<AlignLeft className="h-4 w-4" />
</Button>
<Button
variant={textStyle.align === "center" ? "default" : "outline"}
onClick={() => handleTextStyleChange("align", "center")}
className="flex-1"
>
<AlignCenter className="h-4 w-4" />
</Button>
<Button
variant={textStyle.align === "right" ? "default" : "outline"}
onClick={() => handleTextStyleChange("align", "right")}
className="flex-1"
>
<AlignRight className="h-4 w-4" />
</Button>textStyle.align을 기준으로 버튼의 상태를 변경하고, 사용자가 선택한 정렬 옵션을 handleTextStyleChange로 처리한다.

텍스트 커스터마이징 인터페이스
3. 폰트 선택
미리 준비한 폰트 리스트를 선택할 수 있도록 구성했다.
const FONTS = [
{ name: "GmarketSans", label: "Gmarket Sans" },
{ name: "NanumSquareNeo", label: "NanumSquare Neo" },
{ name: "Pretendard", label: "Pretendard" },
];
<Select
value={textStyle.font}
onValueChange={(value) => handleTextStyleChange("font", value)}
>
{FONTS.map((font) => (
<SelectItem key={font.name} value={font.name}>
{font.label}
</SelectItem>
))}
</Select>textStyle.font 상태를 관리하고, 사용자 선택에 따라 폰트를 업데이트한다.

폰트 선택 인터페이스
4. 제목 및 부제목 크기 조절
제목과 부제목의 크기를 사용자가 쉽게 조절할 수 있도록 슬라이더를 추가했다.
<div className="space-y-4">
<div>
<Label>Title Size</Label>
<Slider
value={[textStyle.fontSize]}
onValueChange={([value]) =>
handleTextStyleChange("fontSize", value)
}
min={5}
max={20}
step={1}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="show-subtitle">Show Subtitle</Label>
<Switch
id="show-subtitle"
checked={showSubtitle}
onCheckedChange={setShowSubtitle}
/>
</div>
{showSubtitle && (
<div>
<Label>Subtitle Size</Label>
<Slider
value={[textStyle.subFontSize]}
onValueChange={([value]) =>
handleTextStyleChange("subFontSize", value)
}
min={3}
max={15}
step={1}
disabled={!showSubtitle}
/>
</div>
)}
</div>
텍스트 크기 조절 인터페이스
5. 캔버스에 텍스트 그리기
선택한 스타일과 폰트를 적용해 캔버스에 텍스트를 그린다.
ctx.fillStyle = textStyle.color;
ctx.textAlign = textStyle.align;
ctx.textBaseline = "middle";
ctx.font = `${textStyle.italic ? "italic " : ""}${
textStyle.bold ? "bold" : "normal"
} ${fontSize}px ${textStyle.font}, Arial`;
let x;
switch (textStyle.align) {
**case "left"**:
x = 20;
break;
**case "center"**:
x = canvas.width / 2;
break;
**case "right"**:
x = canvas.width - 20;
break;
**default**:
x = canvas.width / 2;
}
ctx.fillText(text, x, canvas.height / 2);ctx.font를 통해 굵기, 이탤릭 여부, 폰트를 동적으로 설정한다.textAlign과x위치 값을 설정해 텍스트를 정렬한다.
이 프로젝트의 모든 소스 코드는 GitHub에 공개되어 있습니다. 코드 품질 개선이나 새로운 기능 제안에 대한 피드백은 언제나 환영합니다.