Net als bij serialisatie zijn er twee manieren om canvas uit een tekenreeks te laden: vanuit een JSON-representatie of vanuit een SVG-representatie. Bij gebruik van JSON-representatie zijn er fabric.Canvas#loadFromJSON en fabric.Canvas#loadFromDatalessJSON methoden. Wanneer u SVG gebruikt, zijn er fabric.loadSVGFromURL en fabric.loadSVGFromString.
Merk op dat de eerste twee methoden instance-methoden zijn en rechtstreeks op de canvas-instantie worden aangeroepen, terwijl de laatste twee methoden statische methoden zijn en worden aangeroepen op het "fabric"-object in plaats van op het canvas.
Er valt niet veel te zeggen over deze methoden. Ze werken precies zoals je ervan zou verwachten. Laten we bijvoorbeeld eerdere JSON-uitvoer van canvas nemen en deze op een schoon canvas laden:
var canvas = new fabric.Canvas();
Canvas.loadFromJSON('{"objects":[{"type":"rect","left":50,"top":50,"width":20,"height":20,"fill":"green","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"rx":0,"ry":0},{"type":"circle","left":100,"top":100,"width":100,"height":100,"fill":"red","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"radius":50}],"background":"rgba(0, 0, 0, 0)"}');
..en beide objecten verschijnen "magisch" op canvas:
Het laden van canvas vanaf een touwtje is dus vrij eenvoudig. Maar hoe zit het met die vreemd uitziende loadFromDatalessJSON-methode? Hoe verschilt het precies van loadFromJSON dat we zojuist hebben gebruikt? Om te begrijpen waarom we deze methode nodig hebben, moeten we naar het geserialiseerde canvas kijken dat een min of meer complex padobject heeft. Zoals deze:
..en de JSON.stringify(canvas)-uitvoer voor deze vorm is:
{"objects":[{"type":"path","left":184,"top":177,"width":175,"height":151,"fill":"#231F20","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":-19,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"path":[["M",39.502,61.823],["c",-1.235,-0.902,-3.038,-3.605,-3.038,-3.605],["s",0.702,0.4,3.907,1.203],["c",3.205,0.8,7.444,-0.668,10.114,-1.97],["c",2.671,-1.302,7.11,-1.436,9.448,-1.336],["c",2.336,0.101,4.707,0.602,4.373,2.036],["c",-0.334,1.437,-5.742,3.94,-5.742,3.94],["s",0.4,0.334,1.236,0.334],["c",0.833,0,6.075,-1.403,6.542,-4.173],["s",-1.802,-8.377,-3.272,-9.013],["c",-1.468,-0.633,-4.172,0,-4.172,0],["c",4.039,1.438,4.941,6.176,4.941,6.176],["c",-2.604,-1.504,-9.279,-1.234,-12.619,0.501],["c",-3.337,1.736,-8.379,2.67,-10.083,2.503],["c",-1.701,-0.167,-3.571,-1.036,-3.571,-1.036],["c",1.837,0.034,3.239,-2.669,3.239,-2.669],["s",-2.068,2.269,-5.542,0.434],["c",-3.47,-1.837,-1.704,-8.18,-1.704,-8.18],["s",-2.937,5.909,-1,9.816],["C",34.496,60.688,39.502,61.823,39.502,61.823],["z"],["M",77.002,40.772],["c",0,0,-1.78,-5.03,-2.804,-8.546],["l",-1.557,8.411],["l",1.646,1.602],["c",0,0,0,-0.622,-0.668,-1.691],["C",72.952,39.48,76.513,40.371,77.002,40.772],["z"],["M",102.989,86.943],["M",102.396,86.424],["c",0.25,0.22,0.447,0.391,0.594,0.519],["C",102.796,86.774,102.571,86.578,102.396,86.424],["z"],["M",169.407,119.374],["c",-0.09,-5.429,-3.917,-3.914,-3.917,-2.402],["c",0,0,-11.396,1.603,-13.086,-6.677],["c",0,0,3.56,-5.43,1.69,-12.461],["c",-0.575,-2.163,-1.691,-5.337,-3.637,-8.605],["c",11.104,2.121,21.701,-5.08,19.038,-15.519],["c",-3.34,-13.087,-19.63,-9.481,-24.437,-9.349],["c",-4.809,0.135,-13.486,-2.002,-8.011,-11.618],["c",5.473,-9.613,18.024,-5.874,18.024,-5.874],["c",-2.136,0.668,-4.674,4.807,-4.674,4.807],["c",9.748,-6.811,22.301,4.541,22.301,4.541],["c",-3.097,-13.678,-23.153,-14.636,-30.041,-12.635],["c",-4.286,-0.377,-5.241,-3.391,-3.073,-6.637],["c",2.314,-3.473,10.503,-13.976,10.503,-13.976],["s",-2.048,2.046,-6.231,4.005],["c",-4.184,1.96,-6.321,-2.227,-4.362,-6.854],["c",1.96,-4.627,8.191,-16.559,8.191,-16.559],["c",-1.96,3.207,-24.571,31.247,-21.723,26.707],["c",2.85,-4.541,5.253,-11.93,5.253,-11.93],["c",-2.849,6.943,-22.434,25.283,-30.713,34.274],["s",-5.786,19.583,-4.005,21.987],["c",0.43,0.58,0.601,0.972,0.62,1.232],["c",-4.868,-3.052,-3.884,-13.936,-0.264,-19.66],["c",3.829,-6.053,18.427,-20.207,18.427,-20.207],["v",-1.336],["c",0,0,0.444,-1.513,-0.089,-0.444],["c",-0.535,1.068,-3.65,1.245,-3.384,-0.889],["c",0.268,-2.137,-0.356,-8.549,-0.356,-8.549],["s",-1.157,5.789,-2.758,5.61],["c",-1.603,-0.179,-2.493,-2.672,-2.405,-5.432],["c",0.089,-2.758,-1.157,-9.702,-1.157,-9.702],["c",-0.8,11.75,-8.277,8.011,-8.277,3.74],["c",0,-4.274,-4.541,-12.82,-4.541,-12.82],["s",2.403,14.421,-1.336,14.421],["c",-3.737,0,-6.944,-5.074,-9.879,-9.882],["C",78.161,5.874,68.279,0,68.279,0],["c",13.428,16.088,17.656,32.111,18.397,44.512],["c",-1.793,0.422,-2.908,2.224,-2.908,2.224],["c",0.356,-2.847,-0.624,-7.745,-1.245,-9.882],["c",-0.624,-2.137,-1.159,-9.168,-1.159,-9.168],["c",0,2.67,-0.979,5.253,-2.048,9.079],["c",-1.068,3.828,-0.801,6.054,-0.801,6.054],["c",-1.068,-2.227,-4.271,-2.137,-4.271,-2.137],["c",1.336,1.783,0.177,2.493,0.177,2.493],["s",0,0,-1.424,-1.601],["c",-1.424,-1.603,-3.473,-0.981,-3.384,0.265],["c",0.089,1.247,0,1.959,-2.849,1.959],["c",-2.846,0,-5.874,-3.47,-9.078,-3.116],["c",-3.206,0.356,-5.521,2.137,-5.698,6.678],["c",-0.179,4.541,1.869,5.251,1.869,5.251],["c",-0.801,-0.443,-0.891,-1.067,-0.891,-3.473],...
..en dat is slechts het vijfde (!) deel van de totale output!
Wat is hier aan de hand? Welnu, het blijkt dat deze fabric.Path-instantie โ deze vorm โ bestaat uit letterlijk honderden Bezier-lijnen die dicteren hoe het precies moet worden weergegeven. Al deze ["c",0,2.67,-0.979,5.253,-2.048,9.079] chunks in de JSON-weergave komen overeen met elk van dergelijke curven. En als er honderden (of zelfs duizenden) zijn, wordt de canvasweergave behoorlijk enorm.
Wat moeten we doen?
Dit is wanneer fabric.Canvas#toDatalessJSON van pas komt. Laten we het proberen:
canvas.item(0).sourcePath = '/assets/dragon.svg';
Console.log(JSON.stringify(canvas.toDatalessJSON()));
..en de gelogde uitvoer is:
{"objects":[{"type":"path","left":143,"top":143,"width":175,"height":151,"fill":"#231F20","overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"scaleX":1,"scaleY":1,"angle":-19,"flipX":false,"flipY":false,"opacity":1,"selectable":true,"hasControls":true,"hasBorders":true,"hasRotatingPoint":false,"transparentCorners":true,"perPixelTargetFind":false,"path":"/assets/dragon.svg"}],"background":"rgba(0, 0, 0, 0)"}
Nou, dat is zeker kleiner! Dus wat gebeurde er? Merk op dat we, voordat we toDatalessJSON aanroepen, het object pad (drakenvorm) de eigenschap "sourcePath" van "/assets/dragon.svg" hebben gegeven. Toen we vervolgens toDatalessJSON aanriepen, werd de hele gigantische padreeks uit de vorige uitvoer (die honderden padopdrachten) vervangen door een enkele "dragon.svg" -reeks. Je ziet het hierboven gemarkeerd.
Wanneer we met veel complexe vormen werken, stelt toDatalessJSON ons in staat de canvasrepresentatie nog verder te verminderen en de representatie van enorme padgegevens te vervangen door een eenvoudige link naar SVG.
En nu we teruggaan naar de loadFromDatalessJSON-methode... je kunt waarschijnlijk wel raden dat het eenvoudigweg mogelijk is canvas te laden vanuit een gegevensloze versie van canvasrepresentatie. loadFromDatalessJSON weet vrijwel hoe hij die "pad" -reeksen (zoals "/assets/dragon.svg") moet nemen, laden en gebruiken als gegevens voor overeenkomstige padobjecten.
Laten we nu eens kijken naar de methoden voor het laden van SVG. We kunnen een string of URL gebruiken:
fabric.loadSVGFromString('...', function(objects, options) {
var obj = fabric.util.groupSVGElements(objects, options);
canvas.add(obj).renderAll();
});
Het eerste argument is de SVG-reeks, het tweede is de callback-functie. De callback wordt aangeroepen wanneer SVG wordt geparseerd en geladen en twee argumenten ontvangt: objecten en opties. objecten bevat een reeks objecten die zijn ontleed uit SVG: paden, padgroepen (voor complexe objecten), afbeeldingen, tekst, enzovoort. Om al deze objecten in een samenhangende verzameling te groeperen, en om ze er hetzelfde uit te laten zien als in het SVG-document, gebruiken we fabric.util.groupSVGElements en geven zowel objecten als opties door. In ruil daarvoor krijgen we een exemplaar van fabric.Path of fabric.Group, die we vervolgens aan canvas kunnen toevoegen.
Fabric.loadSVGFromURL werkt op dezelfde manier, behalve dat u een tekenreeks met URL doorgeeft in plaats van SVG-inhoud. Houd er rekening mee dat Fabric zal proberen die URL op te halen via XMLHttpRequest, dus de SVG moet voldoen aan de gebruikelijke SOP-regels.