1. Component 설계를 통한 SVG 아이콘 사용
웹 개발에서 SVG 파일은 아이콘, 로고 등의 그래픽 요소로 널리 사용됩니다. 전통적으로, 이러한 SVG 파일들을 각각의 파일로 관리하며 아래와 같이 img 태그를 통해 웹페이지에 통합하는 방법이 일반적입니다.
<img src="/heart.svg"/>
이 방식은 편리해 보일 수 있지만, 파일의 수가 늘어나고 SVG의 스타일링(색상, 크기 조정 등)이 필요할 때 여러 한계를 드러냅니다. SVG가 외부 파일로 분리되어 있기 때문에, CSS를 통한 스타일 관리가 어렵고 재사용성이 떨어지는 문제가 있죠.
이를 해결하기 위해, Blazor 컴포넌트를 이용할수 잇습니다 . 이 방식은 SVG 요소들을 효율적으로 재사용하며, 직접적인 속성과 CSS 등으로 유연하게 관리하는 것이 가능해집니다. 이러 한 방식은 WPF와도 매우 유사해 보입니다.
Blazor Component로 SVG 관리
JamesIcon이라는 Blazor 컴포넌트를 통해 SVG 아이콘을 관리합니다. 이 컴포넌트는 다양한 파라미터를 통해 SVG의 속성을 쉽게 정의할 수 있게 정의할수 있게 됩니다.
JamesIcon 컴포넌트 설계
@using System.Net.Http
@using Jamesnet.Shared.Local.Helpers
@using Jamesnet.Shared.Local.Models
@inject HttpClient Http
@inject SvgImageRepository SvgImage
<svg class="@Class" @attributes="BuildSvgAttributes()"
xmlns="http://www.w3.org/2000/svg">
<path d="@GetImageData()" fill="@Fill"></path>
</svg>
@code {
[Parameter] public string Class { get; set; }
[Parameter] public string Width { get; set; } = "24";
[Parameter] public string Height { get; set; } = "24";
[Parameter] public string Fill { get; set; } = "#000000";
[Parameter] public string ViewBox { get; set; } = "0 0 24 24";
[Parameter] public string Data { get; set; }
[Parameter] public ImageType ImageType { get; set; }
private Dictionary<string, object> BuildSvgAttributes() => new()
{
{"width", Width},
{"height", Height},
{"viewBox", ViewBox},
{"fill", Fill}
};
private string GetImageData()
{
return !string.IsNullOrEmpty(Data)
? Data : SvgImage.GetImageData(ImageType);
}
}
JamesIcon 컴포넌트는 외부에서 제공하는 파라미터를 통해 SVG의 스타일을 정의합니다. 이렇게 함으로써, SVG 파일을 직접 수정하지 않고도 원하는 스타일을 적용할 수 있게 됩니다. 심지어WPF의 DependencyProperty 속성처럼 Binding 방식도 가능해집니다.
확장성 있는 데이터 관리
svg 파일을 사용하는 대신, SvgImageRepository 클래스를 통해 SVG 데이터를 ImageType
열거형을 키로 하는 Dictionary
에 저장하여 관리합니다. 이 방식은 새로운 SVG 아이콘을 추가할 때 손쉽게 할 수 있고, 기능적으로도 유연한 확장성을 확보할 수 있습니다.
using Jamesnet.Shared.Local.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jamesnet.Shared.Local.Helpers
{
public class SvgImageRepository
{
private const string ACCOUNT_CIRCLE = "M12,19.2C9....";
private const string ACCOUNT_BOX = "M6,17C6,15 10,...";
private const string EARTH = "M17.9,17.39C17.64...";
private const string HEART_MULTIPLE = "M13.5,20C6.9,...";
private const string HEART = "M12,21...";
private const string HEART_CIRCLE = "M12,2C6.47,...";
private const string STAR = "M12,17.27...";
private const string STAR_CIRCLE = "M16.23,...";
private Dictionary<ImageType, string> svgData = new()
{
{ ImageType.AccountCircle, ACCOUNT_CIRCLE },
{ ImageType.AccountBox, ACCOUNT_BOX },
{ ImageType.Earth, EARTH },
{ ImageType.HeartMultiple, HEART_MULTIPLE},
{ ImageType.Heart, HEART},
{ ImageType.HeartCircle, HEART_CIRCLE},
{ ImageType.Star, STAR},
{ ImageType.StarCircle, STAR_CIRCLE},
};
public string GetImageData(ImageType imageType)
{
if (svgData.TryGetValue(imageType, out string data))
{
return data;
}
return null;
}
}
}
Static 클래스로 사용할 수도 있지만, 이 클래스는 인스턴스 방식으로 설계했기 때문에 Blazor에서 이 클래스를 싱글톤으로 등록하면 @Injection
등록을 통해 어디서든 사용할 수 있게 됩니다.
지금은 직접 클래스에서 SVG 데이터를 관리하도록 했지만, .yml 파일을 두고 데이터를 관리하는 것이 더 효과적으로 보입니다.
CSS를 통한 스타일링
JamesIcon 컴포넌트의 Class 파라미터를 활용하여, 외부 CSS에서 SVG의 시각적 속성을 관리할 수 있습니다. 이는 width, height, margin 등의 속성을 svg 태그에, fill 같은 속성을 path 태그에 적용할 수 있게 합니다.
그리고 공통적인 스타일은 .james-icon 클래스로 정의하고, 아이콘별 개별 스타일은 .earth-icon, .heart-icon 등과 같이 세분화하여 관리할 수 있습니다.
.james-icon {
width: 40px;
height: 40px;
}
.heart-icon path {
fill: red;
}
.earth-icon path {
fill: blue;
}
이렇게 Blazor 컴포넌트와 CSS를 활용하면, SVG 파일을 효율적으로 관리하며, 스타일링의 유연성을 극대화할 수 있습니다.
Component 사용하기
이제 SVG 아이콘을 더욱 유연하게 웹 페이지에 통합하고, 다양한 스타일링 옵션을 적용할 수 있습니다. 컴포넌트 사용의 특징은 파라미터를 통해 간편하게 SVG의 모양, 크기, 색상 등을 조정할 수 있고, 손쉽게 속성들을 확장할 수 있습니다.
JamesIcon 컴포넌트의 기본 사용법
@page "/example"
@inject SvgImageRepository SvgImage
<JamesIcon Class="james-icon heart-icon" ImageType="Heart" Fill="red"/>
<JamesIcon Class="james-icon earth-icon" ImageType="Earth" Fill="blue"/>
이처럼 Class를 통해 디자인을 정의하거나, ImageType을 통해 아이콘을 선택하는 것이 가능해집니다.
SVG 데이터를 직접 제공하는 경우
<JamesIcon Class="custom-icon" Data="M12,21.35..." Fill="green"/>
SvgImageRepository를 통해 관리되고 있지 않는 데이터를 직접 지정할 수도 있습니다. 이는 테스트를 통해 먼저 확인이 필요한 경우 유용하게 사용할 수 있습니다.
이제 Component를 통해 SVG 기반의 아이콘 요소들을 더욱 효과적으로 제어할 수 있게 해줍니다.
아이콘 마구 쓰기…
(샘플 프로젝트는 추후에 GitHub와 누겟을 통해 공유 예정입니다.)