PerfectVector
Yazan Irene Kim8 dk okuma

Fabric.js SVG içe aktarma: Canvas'ta düzenleyin

SVG'yi Fabric.js'e düzenlenebilir nesneler olarak aktarın, bir parçayı yeniden renklendirin ve kontrol edilmiş SVG kopyasını dışa aktarın. Test edilmiş örnekle kaynak dosya sorunlarını API hatalarından ayırın.

Bu sayfada

Fabric.js'e düzenlenebilir SVG aktarmak için loadSVGFromString() veya loadSVGFromURL() sonucunu await ile bekleyin, ardından dönen nesneleri bir canvas'a ekleyin. Düzenlemek istediğiniz parçanın referansını saklayın, dolgusunu değiştirin ve canvas.toSVG() ile dışa aktarın. Çizimi görsel olarak yüklemek farklı bir düzenleme modeli sunar: o görseli seçmek, her renkli bölgeyi ayrı bir şekil olarak erişilebilir hâle getirmez.

Bu ayrım bir ürün yapılandırıcısı, rozet düzenleyicisi veya yeniden renklendirilebilir simge için önemlidir. Kullanıcınızın değiştirebileceği parçalara karşılık gelen nesnelere ihtiyacınız vardır. .svg ile biten bir dosya bu yapıyı garanti etmez.

Bu uygulamalı anlatımda Fabric.js 7.4.0 ve elle kodlanmış küçük bir lamba kullanılıyor. Üç şekli içe aktarma, yeniden renklendirme ve dışa aktarma boyunca test ediyoruz. Bu, özgün bir kod test örneğidir; PerfectVector dönüştürmesi veya her SVG özelliğinin aynı süreçte korunduğu iddiası değildir.

Yükleyiciden önce nesne modelini seçin

Fabric.js, SVG'yi ayrıştırarak kendi canvas nesnelerine dönüştürür. Bu nesneleri Fabric API'si üzerinden düzenlersiniz; canvas içinde canlı SVG DOM öğeleri değildirler. Güncel loadSVGFromString başvuru belgesi, ayrıştırma sonucuyla tamamlanan bir promise'i ve her kaynak öğesini ve ondan oluşturulan nesneyi alan bir reviver işlevini belgeler.

GörevinizKullanışlı başlangıç noktasıDevam etmeden önce kontrol edin
Ayrı şekilleri değiştirmekSVG'yi Fabric nesnelerine ayrıştırmakHedef bölgenin ayrı bir nesne olarak bulunması
Çizimi tek bir bütün olarak taşımakAyrıştırılan nesneleri bilinçli olarak gruplamakAlt öğelerin düzenlenmesi ve seçimin beklendiği gibi çalışması
Parçalarını düzenlemeden bir illüstrasyon yerleştirmekGörsel iş akışı kullanmakTek bir seçilebilir görselin yeterli olması
Yalnızca PNG veya JPG olarak bulunan çizimi yeniden renklendirmekÖnce vektör geometrisini hazırlamakVektörleştirilen bölgelerin ihtiyaç duyduğunuz düzenlemelerle eşleşmesi

Nesne yapısını görünümden çıkarsamayın. İki renk ayrı yollara ait olabilirken birbirinden kopuk birkaç alan tek bir yola ait olabilir. SVG gruplarını çözme kılavuzu, kaynak dosyada bunu nasıl teşhis edeceğinizi açıklar.

Küçük bir içe aktarma, renklendirme ve dışa aktarma örneği çalıştırın

Boş bir klasörde başlayın. Sürümü sabitlenmiş bağımlılığı yükleyin:

npm install --save-exact fabric@7.4.0

Bunu index.html olarak kaydedin:

<!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>

Bunu main.js olarak kaydedin. Göreli modül yolu, bu küçük örneğin bir paketleyici olmadan çalışmasını sağlar. Paketlenen bir uygulamada aynı adları fabric üzerinden içe aktarın.

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 dosyasını doğrudan açmak yerine klasörü HTTP üzerinden sunun. Örneğin Python yüklüyse python3 -m http.server 8000 komutunu çalıştırın ve http://localhost:8000 adresini açın. Recolor shade, ardından Export SVG düğmesine tıklayın. Düğme, dışa aktarılan SVG metnini canvas'ın altında görüntüler; dosya indirmez.

Bu demo, önizlemeye yalnızca kendi sabit test örneğinin dışa aktarımını ekler. Bu innerHTML önizlemesini güvenilmeyen SVG'ler için genel bir yükleme işleyicisi olarak yeniden kullanmayın. Örnekte uygulama düzeyinde hata işleme ve dosya doğrulama da yer almıyor.

Map, ayrıştırma sırasında kaynak kimliklerini kaydeder. Yeniden renklendirme, dönen ilk nesnenin her zaman istenen parça olduğunu varsaymak yerine bu açık referansla abajur bölümüne erişir. Üretimde kullanılan bir düzenleyicide, belgeyi kaydederken ve yeniden açarken bu tanımlayıcıların ve referansların nasıl saklanacağına karar verin.

Test ne gösterdi?

Test örneğimiz üç nesne olarak içe aktarıldı: path, rect ve path. Abajur rengi #e6a23c değerinden #397e86 değerine değiştikten sonra dışa aktarılan önizleme yeni rengi gösterirken gövde ve taban, başlangıçtaki koyu dolgularını korudu. Dışa aktarımda iki yol, bir dikdörtgen ve sıfır image öğesi vardı.

Canvas üzerinde yeniden renklendirilmiş lambayı, onunla eşleşen dışa aktarılmış SVG önizlemesini ve üç içe aktarılmış nesne ile sıfır dışa aktarılmış görsel raporunu gösteren gerçek yerel Fabric.js demosu
Elle kodlanmış test örneğinin Fabric.js 7.4.0'da yeniden renklendirme ve dışa aktarma sonrasındaki gerçek ekran görüntüsü. Bu gözlemler burada test edilen üç basit şekil için geçerlidir.

Bu kontroller, örneğin dışa aktarım sonrasında vektör geometrisi olarak kaldığını gösterir. Özgün XML'in, gruplamanın, CSS kurallarının veya başka bir dosyadaki her özelliğin korunduğunu göstermez. Özgün ana dosyayı saklayın ve teslim kopyasını onu alacak uygulamada karşılaştırın.

Callback anlatımlarını promise API'siyle karıştırmayın

Eski örneklerde sıklıkla fabric.loadSVGFromString(svg, callback) çağrılır ve callback'in tüm nesne dizisini alması beklenir. Güncel API'de ikinci argümanın görevi bu değildir: her nesne için çalışan bir reviver'dır. Koleksiyonun tamamı için ayrıştırma sonucunu await ile bekleyin.

Fabric'in 6.0 geçiş kılavuzu, adlandırılmış içe aktarımlara ve promise tabanlı API'lere geçişi açıklar. Eski bir kod parçasını uyarlamadan önce yüklü paket sürümünü kontrol edin; yalnızca import ifadesini değiştirmek yükleme mantığını yanlış bırakır.

Aynı kökenden sunulan bir SVG dosyası için eşdeğer başlangıç noktası şöyledir:

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

loadSVGFromURL belgeleri, SVG'nin getirildiğini ve aynı köken politikasına uyulması gerektiğini belirtir. Uzak sunucu sizin kökeninize izin vermiyorsa gruplama kodunu değiştirmek ağ hatasını düzeltmez. Önce kendi uygulamanızın sunduğu bir dosyayı test edin, ardından başarısız isteği ve uzak sunucunun CORS yapılandırmasını inceleyin.

Düzenlenebilirliği görünümden ayrı kontrol edin

Başarılı bir görüntüleme tek bir soruyu yanıtlar: ekranda bir şey göründü mü? Bir düzenleyici için daha fazla kontrol gerekir.

  1. Değişmesi gereken bölgeyi seçin. Başka bir parçanın onunla birlikte değişmediğini doğrulayın.
  2. Örnekteki gibi nesnenin set yöntemiyle yeniden renklendirin ve yeniden çizim isteyin.
  3. Dışa aktarın ve sonucu bağımsız olarak açın. Fabric'in Canvas.toSVG API'si, canvas durumundan SVG kodu üretir.
  4. Gerçek çiziminizin dayandığı konturları, kırpmayı, renk geçişlerini, metni veya iç içe dönüşümleri inceleyin. Yukarıdaki basit test örneği bu özellikleri test etmez.
  5. İş akışını tamamlanmış saymadan önce kendi düzenleyicinizde kaydedin, yeniden açın ve amaçlanan düzenlemeyi tekrarlayın.

İçe aktarma bir görsel nesnesi üretiyorsa kaynakta gömülü raster olup olmadığını inceleyin. SVG içindeki raster içerik kılavuzu, SVG kapsayıcısının neden piksellere düzenlenebilir yollar kazandırmadığını gösterir. Kaynakta zaten kullanılabilir vektör şekilleri varsa onu yeniden vektörleştirmek yerine içe aktarma ve nesne düzeni üzerinde çalışın.

Raster çizim önce dönüştürülmek zorundaysa

Tek kaynağınız tek katmanlı bir PNG veya JPG ise ve kullanıcıların renkli bölgelerini düzenlemesi gerekiyorsa PerfectVector'ın görselden vektöre iş akışı, bir SVG adayı hazırlamanıza yardımcı olabilir. Sonucu özgün görselle karşılaştırın, yolları inceleyin ve Fabric.js'e aktarmadan önce ihtiyaç duyduğunuz bölgelerin bağımsız olarak düzenlenebildiğini kontrol edin.

Vektörleştirme, abajur, gövde veya taban gibi uygulamaya özgü anlamlar atamaz. Test örneğimizin adları bilinçli olarak verilmiştir. Dönüştürülen geometriyi inceledikten sonra kendi parça eşleştirmenizi ve düzenleme kurallarınızı ekleyin. Yeniden kullanılabilir bir simge kümesi için PNG'den SVG'ye UI kiti iş akışı, kaynak hazırlığını ve tutarlılık kontrollerini ele alır.

Fotoğraf olarak kalması gereken fotoğrafları raster olarak koruyun. İhtiyacınız olan şekilleri zaten içeriyorsa uygun özgün SVG'yi saklayın. Vektörleştirmeye genel bakış, vektörleştirmeye iş akışında gerçekten ihtiyaç olup olmadığına karar vermenize yardımcı olabilir.

Sık sorulan sorular

Fabric.js, SVG'yi düzenlenebilir yollar olarak içe aktarır mı? Desteklenen SVG içeriğini Fabric nesnelerine ayrıştırabilir. Düzenlenebilirlik kaynak yapısına bağlıdır: bir yol, bir şekil grubu ve gömülü raster aynı düzenleme seçeneklerini sunmaz. Dönen nesneleri inceleyin ve ihtiyacınız olan değişikliği özellikle test edin.

Eski bir loadSVGFromString örneği neden çalışmıyor? Eski anlatımlar ikinci argüman olarak tamamlanma callback'i bekleyebilir. Güncel API bir promise döndürür ve o argümanı her nesne için çalışan bir reviver olarak kullanır. Kodunuzu yüklü sürüme uygun hâle getirin ve ayrıştırma sonucunu await ile bekleyin.

toSVG, özgün dosyayı tam olarak korur mu? Kaynak belgeyle birebir aynı sonuç beklemeyin. Fabric canvas durumundan SVG üretir. Özgün ana dosyayı koruyun; dışa aktarılan görünümü ve çıktıyı alacak iş akışının ihtiyaç duyduğu yapıları doğrulayın.

PNG içe aktarmak, tek tek bölgelerini düzenlenebilir yapabilir mi? PNG yerleştirmek, görüntüyü vektörleştirerek ayrı vektör bölgelerine dönüştürmez. Bu düzenlemeler gerekliyse önce uygun vektör geometrisini hazırlayın, oluşan parçaları inceleyin ve uygulamanızda rollerini tanımlayın.

Kaynaklar

  1. Fabric.js — loadSVGFromString — Promise dönüş değeri ve kaynak öğesi/nesnesi reviver sözleşmesi.
  2. Fabric.js — Upgrading to Fabric.js 6.0 — Adlandırılmış içe aktarımlar ve callback'lerden promise'lere geçiş.
  3. Fabric.js — loadSVGFromURL — URL ayrıştırma ve aynı kökenden getirme kısıtlamaları.
  4. Fabric.js — Canvas API — Canvas durumunu SVG kodu olarak dışa aktarma.

Eksik olan parça raster çizimden elde edilecek düzenlenebilir geometriyse PerfectVector ile bir SVG adayı hazırlayın. Önce şekilleri kontrol edin, ardından Fabric.js düzenleyicinizin hedeflenen parçayı yeniden renklendirip sonucu doğru şekilde dışa aktarabildiğini doğrulayın.

Bloga daha fazlası

Düzenlemesi daha kolay,
daha temiz bir SVG ile başlayın