Fabric.js SVG 가져오기: 캔버스에서 아트워크 편집 가능하게 유지하기
SVG를 Fabric.js의 편집 가능한 객체로 가져와 한 부분의 색을 바꾸고 검증한 SVG 사본을 내보내세요. 테스트된 예제를 따라 소스 문제와 API 오류를 구분하세요.
목차
편집 가능한 SVG를 Fabric.js로 가져오려면 loadSVGFromString() 또는 loadSVGFromURL()를 await한 뒤 반환된 객체를 캔버스에 추가하세요. 편집할 부분의 참조를 보관하고 채우기를 바꾼 다음 canvas.toSVG()로 내보내세요. 아트워크를 이미지로 불러오면 편집 모델이 달라집니다. 이미지를 선택해도 각 색상 영역이 별도의 도형으로 드러나지는 않습니다.
제품 구성 도구, 배지 편집기, 색상을 바꿀 수 있는 아이콘에서는 이 차이가 중요합니다. 사용자가 바꿀 수 있는 부분에 대응하는 객체가 필요합니다. .svg로 끝나는 파일이라고 그 구조가 보장되지는 않습니다.
이 안내는 Fabric.js 7.4.0과 직접 작성한 작은 램프를 사용합니다. 도형 세 개를 가져오기, 색상 변경, 내보내기 과정에서 테스트합니다. 직접 만든 코드 테스트 자료이며 PerfectVector 변환 결과도, 모든 SVG 기능이 같은 과정을 거쳐 보존된다는 주장도 아닙니다.
로더보다 객체 모델을 먼저 선택하기
Fabric.js는 SVG를 자체 캔버스 객체로 파싱합니다. 객체는 Fabric API로 편집하며 캔버스 안에 실제 SVG DOM 요소로 존재하는 것은 아닙니다. 현재 loadSVGFromString 참조는 파싱 결과를 반환하는 Promise와 각 소스 요소 및 생성된 객체를 받는 reviver를 설명합니다.
| 작업 | 유용한 시작 방식 | 계속하기 전에 확인할 사항 |
|---|---|---|
| 개별 도형 변경 | SVG를 Fabric 객체로 파싱 | 대상 영역이 자체 객체로 존재하는지 |
| 아트워크를 하나의 단위로 이동 | 파싱된 객체를 의도적으로 그룹화 | 자식 편집과 선택이 의도대로 작동하는지 |
| 내부 부분을 편집하지 않고 일러스트레이션 배치 | 이미지 작업 흐름 사용 | 선택 가능한 이미지 하나로 충분한지 |
| PNG나 JPG로만 있는 아트워크 색상 변경 | 먼저 벡터 도형 준비 | 추적된 영역이 필요한 편집에 맞는지 |
모양만 보고 객체 구조를 추론하지 마세요. 두 색상이 별도 경로에 속할 수 있고, 여러 떨어진 영역이 하나의 경로에 속할 수도 있습니다. SVG 그룹 해제 안내는 이 소스 파일 진단을 설명합니다.
작은 가져오기, 색상 변경, 내보내기 예제 실행하기
빈 폴더에서 시작하세요. 버전이 고정된 의존성을 설치하세요.
npm install --save-exact fabric@7.4.0다음을 index.html로 저장하세요.
<!doctype html>
<html lang="en">
<meta charset="utf-8">
<title>Fabric SVG import test</title>
<canvas id="editor" width="320" height="240"></canvas>
<button id="recolor">Recolor shade</button>
<button id="export">Export SVG</button>
<div id="output"></div>
<pre id="report"></pre>
<script type="module" src="main.js"></script>
</html>다음을 main.js로 저장하세요. 상대 모듈 경로 덕분에 이 작은 예제는 번들러 없이 실행됩니다. 번들된 애플리케이션에서는 같은 이름을 fabric에서 가져오세요.
import { Canvas, loadSVGFromString } from './node_modules/fabric/dist/index.min.mjs';
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="320" height="240" viewBox="0 0 320 240">
<path id="shade" fill="#e6a23c" d="M115 40 H205 L230 135 H90 Z"/>
<rect id="stem" x="151" y="135" width="18" height="57" fill="#214c54"/>
<path id="base" fill="#214c54" d="M110 192 H210 L220 210 H100 Z"/>
</svg>`;
const canvas = new Canvas('editor', { width: 320, height: 240 });
const parts = new Map();
const parsed = await loadSVGFromString(svg, (element, object) => {
const id = element.getAttribute('id');
if (id) parts.set(id, object);
});
canvas.add(...parsed.objects.filter(Boolean));
canvas.requestRenderAll();
function report(exported) {
const xml = new DOMParser().parseFromString(exported, 'image/svg+xml');
const data = {
version: '7.4.0',
importedObjects: canvas.getObjects().length,
types: canvas.getObjects().map(object => object.type),
shadeFill: parts.get('shade').fill,
exportedPaths: xml.querySelectorAll('path').length,
exportedRects: xml.querySelectorAll('rect').length,
exportedImages: xml.querySelectorAll('image').length,
};
document.querySelector('#report').textContent = JSON.stringify(data, null, 2);
document.querySelector('#output').innerHTML = exported;
}
document.querySelector('#recolor').onclick = () => {
parts.get('shade').set('fill', '#397e86');
canvas.requestRenderAll();
document.querySelector('#report').textContent = 'Shade recolored. Export to check delivery SVG.';
};
document.querySelector('#export').onclick = () => report(canvas.toSVG());
report(canvas.toSVG());HTML 파일을 직접 열지 말고 폴더를 HTTP로 제공하세요. 예를 들어 Python이 설치되어 있다면 python3 -m http.server 8000을 실행하고 http://localhost:8000을 여세요. Recolor shade를 누른 뒤 Export SVG를 누르세요. 버튼은 내보낸 문자열을 캔버스 아래에 렌더링하며 파일을 다운로드하지 않습니다.
이 데모는 자체의 고정된 테스트 자료에서 내보낸 결과만 미리보기에 삽입합니다. 이 innerHTML 미리보기를 신뢰할 수 없는 SVG의 일반적인 업로드 처리기로 재사용하지 마세요. 예제에는 애플리케이션 수준의 오류 처리와 파일 검증도 생략되어 있습니다.
map은 파싱 중 소스 ID를 기록합니다. 색상 변경은 첫 번째 반환 객체가 항상 원하는 부분이라고 가정하지 않고 그 명시적 참조로 갓을 지정합니다. 실제 편집기에서는 문서를 저장하고 다시 열 때 이 식별자와 참조를 어떻게 보관할지 결정하세요.
테스트에서 확인한 내용
이 테스트 자료는 path, rect, path의 세 객체로 가져와졌습니다. 갓의 색을 #e6a23c에서 #397e86으로 바꾼 뒤 내보낸 미리보기에는 새 갓 색상이 나타났으며 기둥과 받침은 원래의 어두운 채우기를 유지했습니다. 내보내기 결과에는 경로 두 개, 사각형 하나가 있었고 이미지 요소는 없었습니다.

이 확인은 예제가 내보내기 후에도 벡터 도형으로 유지됨을 입증합니다. 원본 XML, 그룹 구성, CSS 규칙 또는 다른 파일의 모든 기능 보존을 입증하지는 않습니다. 원본 마스터를 보관하고 파일을 받을 애플리케이션에서 전달용 사본을 비교하세요.
콜백 방식 안내를 promise API와 섞지 않기
오래된 예제는 종종 fabric.loadSVGFromString(svg, callback)을 호출하고 콜백이 전체 객체 배열을 받기를 기대합니다. 현재 API에서 두 번째 인수는 그런 역할이 아니라 객체별 reviver입니다. 전체 모음을 얻으려면 파싱 결과를 await하세요.
Fabric의 6.0 마이그레이션 안내는 이름 있는 가져오기와 promise 기반 API로의 변경을 설명합니다. 오래된 코드를 적용하기 전에 설치된 패키지 버전을 확인하세요. import 문만 바꾸면 로딩 로직은 잘못된 상태로 남습니다.
같은 출처의 SVG 파일에서는 다음이 동등한 시작 방식입니다.
import { loadSVGFromURL } from 'fabric';
const parsed = await loadSVGFromURL('/artwork.svg');
canvas.add(...parsed.objects.filter(Boolean));
canvas.requestRenderAll();loadSVGFromURL 문서는 이 함수가 SVG를 가져오며 동일 출처 정책을 따라야 한다고 설명합니다. 원격 호스트가 애플리케이션의 출처를 허용하지 않는다면 그룹화 코드를 바꿔도 네트워크 오류가 해결되지 않습니다. 먼저 자체 애플리케이션에서 제공하는 파일을 테스트한 뒤 실패한 요청과 원격 서버의 CORS 설정을 확인하세요.
모양과 편집 가능성을 별도로 확인하기
성공한 렌더링은 무언가 나타났는지에만 답합니다. 편집기에는 더 많은 확인이 필요합니다.
- 바뀌어야 하는 영역을 선택하세요. 다른 부분이 함께 바뀌지 않는지 확인하세요.
- 예제처럼 객체의
set메서드로 색상을 바꾸고 렌더링을 요청하세요. - 내보내고 결과를 별도로 여세요. Fabric의
Canvas.toSVGAPI는 캔버스 상태에서 SVG 마크업을 생성합니다. - 스트로크, 클리핑, 그라디언트, 텍스트, 중첩 변환 등 실제 아트워크가 의존하는 기능을 확인하세요. 위의 단순한 테스트 자료는 이 기능들을 테스트하지 않습니다.
- 작업 흐름이 완료되었다고 판단하기 전에 자체 편집기에서 저장하고 다시 열어 원하는 편집을 반복하세요.
가져오기 결과가 이미지 객체라면 소스에 포함된 래스터가 있는지 살펴보세요. SVG 내부 래스터 콘텐츠 안내는 SVG로 감쌌다고 픽셀에 편집 가능한 경로가 생기지 않는 이유를 보여 줍니다. 소스에 이미 사용할 수 있는 벡터 도형이 있다면 다시 추적하는 대신 가져오기와 객체 구성을 다루세요.
래스터 아트워크에 사전 변환이 필요한 경우
단일 이미지로 된 PNG나 JPG만 있고 사용자가 색상 영역을 편집해야 한다면 PerfectVector의 이미지 벡터화 작업 흐름으로 SVG 후보 파일을 준비할 수 있습니다. 원본과 비교하고 경로를 살펴본 뒤 Fabric.js로 가져오기 전에 필요한 영역을 독립적으로 편집할 수 있는지 확인하세요.
추적은 갓, 기둥, 받침처럼 애플리케이션별 의미를 지정하지 않습니다. 이 테스트 자료의 이름은 의도적으로 작성했습니다. 변환된 도형을 살펴본 뒤 자체 부분 매핑과 편집 규칙을 추가하세요. 재사용 가능한 아이콘 세트에는 PNG에서 SVG UI 키트로 만드는 작업 흐름이 소스 준비와 일관성 확인을 다룹니다.
사진으로 유지해야 하는 사진은 래스터로 보관하세요. 필요한 도형이 이미 들어 있는 적절한 원본 SVG가 있다면 유지하세요. 벡터화 개요는 추적이 작업 흐름에 필요한지 판단하는 데 도움이 됩니다.
FAQ
Fabric.js는 SVG를 편집 가능한 경로로 가져오나요? 지원되는 SVG 콘텐츠를 Fabric 객체로 파싱할 수 있습니다. 편집 가능성은 소스 구조에 달려 있습니다. 경로, 도형 그룹, 포함된 래스터는 같은 편집 옵션을 제공하지 않습니다. 반환된 객체를 살펴보고 필요한 변경을 구체적으로 테스트하세요.
오래된 loadSVGFromString 예제가 실패하는 이유는 무엇인가요? 오래된 안내는 두 번째 인수로 완료 콜백을 기대할 수 있습니다. 현재 API는 promise를 반환하고 해당 인수를 객체별 reviver로 사용합니다. 설치된 버전에 코드를 맞추고 파싱 결과를 await하세요.
toSVG는 원본 파일을 정확히 보존하나요? 동일한 소스 문서를 기대하지 마세요. Fabric 캔버스 상태에서 SVG를 생성합니다. 원본 마스터를 보존하고 내보낸 모양과 파일을 받는 작업 흐름에 필요한 구조를 확인하세요.
PNG를 가져오면 개별 영역을 편집할 수 있나요? PNG를 배치해도 별도의 벡터 영역으로 추적되지는 않습니다. 이러한 편집이 필요하다면 먼저 적절한 벡터 도형을 준비하고 결과 부분을 살펴본 뒤 애플리케이션에서 역할을 정의하세요.
Sources
- Fabric.js — loadSVGFromString — promise 반환값과 소스 요소 및 객체 reviver 계약.
- Fabric.js — Fabric.js 6.0으로 업그레이드하기 — 이름 있는 가져오기와 콜백에서 promise로의 전환.
- Fabric.js — loadSVGFromURL — URL 파싱과 동일 출처 fetch 제약.
- Fabric.js — Canvas API — 캔버스 상태를 SVG 마크업으로 내보내기.
빠진 것이 래스터 아트워크의 편집 가능한 도형이라면 PerfectVector로 SVG 후보 파일을 준비하세요. 먼저 도형을 확인하고 Fabric.js 편집기가 원하는 부분의 색을 바꾸고 결과를 올바르게 내보낼 수 있는지 입증하세요.

