SVG를 texture로 쓸지 vector로 유지할지
SVG import는 선택이 필요합니다. texture로 굽는지, vector path로 유지하는지에 따라 편집성과 렌더링 비용이 달라집니다.
import 정책을 코드로 고정하기
SVG마다 편집 가능한 vector로 유지할지, texture preview로 굽는지 결정합니다.
function chooseSvgImportMode(svgInfo, userIntent) {
if (userIntent === "edit-path") return "vector";
if (svgInfo.pathCount > 200 || svgInfo.hasFilters || svgInfo.hasForeignObject) {
return "raster-texture";
}
if (svgInfo.isIcon && !svgInfo.needsEditing) {
return "raster-texture";
}
return "vector";
}
function importSvg(svgText, mode) {
if (mode === "vector") return parseSvgToVectorNodes(svgText);
return rasterizeSvgToTextureAsset(svgText);
}
두 가지 길
SVG -> raster texture: 빠른 표시, 낮은 편집성
SVG -> vector path: 높은 편집성, 높은 구현 비용
아이콘처럼 편집하지 않는 asset은 texture가 단순합니다. path 편집이 목표라면 vector model을 유지해야 합니다.
unsupported SVG 기능을 기록한다
function analyzeSvgForImport(svgDocument) {
return {
pathCount: svgDocument.querySelectorAll("path").length,
hasFilters: !!svgDocument.querySelector("filter"),
hasForeignObject: !!svgDocument.querySelector("foreignObject"),
hasMasks: !!svgDocument.querySelector("mask"),
hasText: !!svgDocument.querySelector("text")
};
}
function importSvgAsset(svgText, userIntent) {
const svg = new DOMParser().parseFromString(svgText, "image/svg+xml");
const info = analyzeSvgForImport(svg);
const mode = chooseSvgImportMode(info, userIntent);
return { mode, info, nodesOrTexture: importSvg(svgText, mode) };
}
SVG import는 실패를 조용히 넘기면 안 됩니다. 어떤 기능 때문에 raster fallback이 됐는지 남겨야 사용자가 편집성 손실을 이해할 수 있습니다.
오늘의 핵심
SVG 정책은 import 순간에 정해야 합니다. “보이기만 하면 되는가, 편집해야 하는가”가 기준입니다.