PerfectVector
Oleh Irene Kim8 menit baca

Impor SVG Fabric.js: Jaga Artwork Tetap Dapat Diedit pada Canvas

Impor SVG ke Fabric.js sebagai objek yang dapat diedit, warnai ulang satu bagian, dan ekspor salinan SVG yang telah diperiksa. Ikuti contoh yang diuji dan pisahkan masalah sumber dari bug API.

Di halaman ini

Untuk mengimpor SVG yang dapat diedit ke Fabric.js, tunggu loadSVGFromString() atau loadSVGFromURL(), lalu tambahkan objek yang dikembalikan ke canvas. Simpan referensi ke bagian yang ingin Anda edit, ubah isiannya, dan ekspor dengan canvas.toSVG(). Memuat artwork sebagai gambar memberi Anda model pengeditan berbeda: memilih gambar itu tidak mengekspos setiap wilayah berwarna sebagai bentuk terpisah.

Perbedaan itu penting untuk konfigurator produk, editor lencana, atau ikon yang dapat diwarnai ulang. Anda membutuhkan objek yang sesuai dengan bagian yang dapat diubah pengguna. File berakhiran .svg tidak menjamin struktur tersebut.

Panduan ini menggunakan Fabric.js 7.4.0 dan lampu kecil buatan tangan. Panduan menguji tiga bentuk melalui impor, pewarnaan ulang, dan ekspor. Ini adalah fixture kode orisinal, bukan konversi PerfectVector atau klaim bahwa setiap fitur SVG bertahan melalui proses yang sama.

Pilih model objek sebelum loader

Fabric.js mengurai SVG menjadi objek canvas-nya sendiri. Anda mengedit objek tersebut melalui API Fabric; objek itu bukan elemen DOM SVG aktif di dalam canvas. Referensi loadSVGFromString saat ini mendokumentasikan promise yang menghasilkan hasil penguraian dan reviver yang menerima setiap elemen sumber serta objek yang dibuatnya.

Tugas AndaTitik awal yang bergunaPeriksa sebelum melanjutkan
Mengubah bentuk terpisahUrai SVG menjadi objek FabricWilayah target ada sebagai objeknya sendiri
Memindahkan artwork sebagai satu kesatuanKelompokkan objek yang diurai secara sengajaPengeditan dan seleksi anak berfungsi sesuai tujuan
Menempatkan ilustrasi tanpa mengedit bagiannyaGunakan alur kerja gambarSatu gambar yang dapat dipilih sudah cukup
Mewarnai ulang artwork yang hanya tersedia sebagai PNG atau JPGSiapkan geometri vektor terlebih dahuluWilayah hasil penelusuran sesuai dengan pengeditan yang Anda perlukan

Jangan menyimpulkan struktur objek dari tampilannya. Dua warna dapat berasal dari path terpisah, sementara beberapa bagian terputus dapat berasal dari satu path. Panduan ungroup SVG menjelaskan diagnosis file sumber tersebut.

Jalankan contoh kecil impor, pewarnaan ulang, dan ekspor

Mulailah dalam folder kosong. Instal dependensi dengan versi yang dikunci:

npm install --save-exact fabric@7.4.0

Simpan ini sebagai 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>

Simpan ini sebagai main.js. Path module relatif memungkinkan contoh kecil ini berjalan tanpa bundler. Dalam aplikasi dengan bundler, impor nama yang sama dari 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());

Sajikan folder melalui HTTP alih-alih membuka file HTML langsung. Sebagai contoh, jika Python terinstal, jalankan python3 -m http.server 8000 dan buka http://localhost:8000. Klik Recolor shade, lalu Export SVG. Tombol merender string hasil ekspor di bawah canvas; tombol tidak mengunduh file.

Demo ini hanya menyisipkan ekspor fixture tetapnya sendiri ke dalam pratinjau. Jangan menggunakan ulang pratinjau innerHTML itu sebagai handler unggahan umum untuk SVG yang tidak tepercaya. Contoh juga mengabaikan penanganan error tingkat aplikasi dan validasi file.

Map menangkap ID sumber selama penguraian. Pewarnaan ulang mengakses kap lampu melalui referensi eksplisit tersebut, alih-alih menganggap objek pertama yang dikembalikan selalu merupakan bagian yang diinginkan. Dalam editor produksi, tentukan bagaimana identifier dan referensi tersebut disimpan ketika menyimpan dan membuka kembali dokumen.

Apa yang ditunjukkan pengujian

Fixture kami diimpor sebagai tiga objek: path, rect, dan path. Setelah kap lampu berubah dari #e6a23c menjadi #397e86, pratinjau hasil ekspor menunjukkan kap lampu baru sementara tangkai dan dasar mempertahankan isian gelap aslinya. Ekspor berisi dua path, satu persegi panjang, dan tidak ada elemen gambar.

Demo Fabric.js lokal sebenarnya menunjukkan lampu yang diwarnai ulang pada canvas, pratinjau SVG hasil ekspor yang sesuai, dan laporan tiga objek impor dengan nol gambar hasil ekspor
Tangkapan autentik fixture buatan tangan dalam Fabric.js 7.4.0 setelah pewarnaan ulang dan ekspor. Pengamatan ini berlaku untuk tiga bentuk sederhana yang diuji di sini.

Pemeriksaan itu membuktikan bahwa contoh ini tetap berupa geometri vektor setelah ekspor. Pemeriksaan tidak membuktikan pelestarian XML asli, pengelompokan, aturan CSS, atau setiap fitur yang digunakan file lain. Simpan master asli dan bandingkan salinan penyerahan dalam aplikasi yang akan menerimanya.

Hindari mencampurkan tutorial callback dengan API promise

Contoh lama sering memanggil fabric.loadSVGFromString(svg, callback) dan mengharapkan callback menerima seluruh array objek. Itu bukan peran argumen kedua dalam API saat ini: argumen itu merupakan reviver per objek. Tunggu hasil penguraian untuk memperoleh kumpulan lengkap.

Panduan migrasi 6.0 Fabric menjelaskan perubahan ke named import dan API berbasis promise. Periksa versi paket terinstal sebelum mengadaptasi cuplikan lama; mengganti hanya pernyataan impor membiarkan logika pemuatan tetap salah.

Untuk file SVG same-origin, titik awal setaranya adalah:

import { loadSVGFromURL } from 'fabric';
const parsed = await loadSVGFromURL('/artwork.svg');
canvas.add(...parsed.objects.filter(Boolean));
canvas.requestRenderAll();

Dokumentasi loadSVGFromURL mencatat bahwa metode mengambil SVG dan harus mematuhi kebijakan same-origin. Jika host jarak jauh tidak mengizinkan origin Anda, mengubah kode pengelompokan tidak akan memperbaiki kegagalan jaringan. Uji file yang disajikan aplikasi Anda sendiri terlebih dahulu, lalu periksa permintaan yang gagal dan konfigurasi CORS server jarak jauh.

Periksa kemampuan pengeditan secara terpisah dari tampilan

Render yang berhasil menjawab satu pertanyaan: apakah sesuatu muncul? Editor membutuhkan pemeriksaan lebih banyak.

  1. Pilih wilayah yang seharusnya berubah. Pastikan bagian lain tidak berubah bersamanya.
  2. Warnai ulang melalui metode set objek dan minta render, seperti yang dilakukan contoh.
  3. Ekspor dan buka hasil secara mandiri. API Canvas.toSVG Fabric menghasilkan markup SVG dari keadaan canvas.
  4. Periksa apa pun yang menjadi ketergantungan artwork Anda sebenarnya, seperti stroke, clipping, gradien, teks, atau transformasi bersarang. Fixture sederhana di atas tidak menguji fitur tersebut.
  5. Simpan, buka kembali, dan ulangi pengeditan yang dimaksudkan dalam editor Anda sendiri sebelum menganggap alur kerja selesai.

Jika impor menghasilkan objek gambar, periksa apakah sumber memiliki raster tertanam. Panduan konten raster di dalam SVG menunjukkan mengapa pembungkus SVG tidak memberikan path yang dapat diedit kepada piksel. Jika sumber sudah memiliki bentuk vektor yang dapat digunakan, kerjakan impor dan organisasi objek alih-alih menelusurinya kembali.

Ketika artwork raster membutuhkan konversi di tahap awal

Jika satu-satunya sumber Anda adalah PNG atau JPG datar dan pengguna perlu mengedit wilayah berwarnanya, alur kerja gambar-ke-vektor PerfectVector dapat membantu menyiapkan kandidat SVG. Bandingkan hasil dengan sumber asli, periksa path, dan pastikan wilayah yang Anda perlukan dapat diedit secara mandiri sebelum mengimpornya ke Fabric.js.

Penelusuran tidak menetapkan makna khusus aplikasi seperti kap lampu, tangkai, atau dasar. Nama fixture kami ditulis secara sengaja. Tambahkan pemetaan bagian dan aturan pengeditan Anda sendiri setelah memeriksa geometri hasil konversi. Untuk kumpulan ikon yang dapat digunakan ulang, alur kerja kit UI PNG-ke-SVG membahas persiapan sumber dan pemeriksaan konsistensi.

Pertahankan foto sebagai raster ketika memang dimaksudkan tetap berupa foto. Pertahankan SVG asli yang sesuai ketika sudah berisi bentuk yang Anda perlukan. Ikhtisar vektorisasi dapat membantu menentukan apakah penelusuran perlu masuk ke alur kerja sama sekali.

FAQ

Apakah Fabric.js mengimpor SVG sebagai path yang dapat diedit? Fabric.js dapat mengurai konten SVG yang didukung menjadi objek Fabric. Kemampuan pengeditan bergantung pada struktur sumber: path, grup bentuk, dan raster tertanam tidak menyediakan opsi pengeditan yang sama. Periksa objek yang dikembalikan dan uji perubahan khusus yang Anda perlukan.

Mengapa contoh loadSVGFromString lama gagal? Tutorial lama mungkin mengharapkan callback penyelesaian sebagai argumen kedua. API saat ini mengembalikan promise dan menggunakan argumen itu sebagai reviver per objek. Sesuaikan kode dengan versi terinstal dan tunggu hasil penguraian.

Apakah toSVG mempertahankan file asli secara persis? Jangan mengharapkan dokumen sumber identik. Metode ini menghasilkan SVG dari keadaan canvas Fabric. Pertahankan master asli dan verifikasi tampilan hasil ekspor serta struktur yang dibutuhkan alur kerja penerima Anda.

Dapatkah mengimpor PNG membuat wilayahnya dapat diedit satu per satu? Menempatkan PNG tidak menelusurinya menjadi wilayah vektor terpisah. Jika pengeditan itu diperlukan, siapkan geometri vektor yang sesuai terlebih dahulu, periksa bagian yang dihasilkan, dan definisikan perannya dalam aplikasi Anda.

Sources

  1. Fabric.js — loadSVGFromString — Nilai kembalian promise dan kontrak reviver elemen sumber/objek.
  2. Fabric.js — Meningkatkan ke Fabric.js 6.0 — Named import dan migrasi dari callback ke promise.
  3. Fabric.js — loadSVGFromURL — Penguraian URL dan batasan fetch same-origin.
  4. Fabric.js — API Canvas — Mengekspor keadaan canvas menjadi markup SVG.

Jika bagian yang hilang adalah geometri yang dapat diedit dari artwork raster, siapkan kandidat SVG dengan PerfectVector. Periksa bentuk terlebih dahulu, lalu buktikan bahwa editor Fabric.js Anda dapat mewarnai ulang bagian yang dimaksudkan dan mengekspor hasil dengan benar.

Lebih banyak dari blog

Mulai dengan SVG yang lebih rapi
dan lebih mudah diedit