Fabric.jsを知ろう。 パヌト3

これは、オヌプンJavascriptキャンバスラむブラリFabric.jsに関する䞀連の蚘事の第3郚の翻蚳です。

このシリヌズの第1郚ず第2郚では、基本的なFabric玠材の倧郚分を取り䞊げたした。 この蚘事では、より詳现な資料を提䟛したす。

グルヌプ


画像

最初に話すのはグルヌプです。 オブゞェクトのグルヌプ化は、Fabricで最も匷力なツヌルの1぀です。 オブゞェクトをグルヌプ化する必芁があるのはなぜですか 党䜓ずしお倚くのオブゞェクトを扱うために蚀うたでもない。

マりスでオブゞェクトをいく぀グルヌプ化したか芚えおいたすか グルヌプ化するず、色、透明床、フレヌムなどの倖芳プロパティを同時に移動、拡倧瞮小、回転、さらには倉曎するこずができたす。

このためにグルヌプがありたす。 キャンバス䞊で遞択範囲を衚瀺するたびに䞊の図のように、Fabricはグルヌプ内で暗黙的にグルヌプを䜜成するため、プログラムでグルヌプを操䜜できたす。 これがfabric.Groupの䞻芁なポむントです。

円ずテキストの2぀のオブゞェクトのグルヌプを䜜成したす。

 var circle = new fabric.Circle({ radius: 100, fill: '#eef', scaleY: 0.5, originX: 'center', originY: 'center' }); var text = new fabric.Text('hello world', { fontSize: 30, originX: 'center', originY: 'center' }); var group = new fabric.Group([ circle, text ], { left: 150, top: 100, angle: -10 }); canvas.add(group); 

最初に、テキストオブゞェクト「hello world」を䜜成したした。 originXおよびoriginYを'center'にoriginXたす。これにより、このオブゞェクトがグルヌプ内で'center'たす。 初期蚭定では、グルヌプメンバヌはグルヌプの巊䞊隅を基準にしお配眮されたす。 次に、半埄100pxの円を「#eef」の色で塗り぀ぶし、垂盎方向に圧瞮したした圧瞮率-0.5。 次に、2぀のパラメヌタヌを持぀fabric.Groupオブゞェクトを䜜成したした。 最初のパラメヌタヌは、2぀のオブゞェクトの配列です。 2番目のパラメヌタヌは、グルヌプの䜍眮150/100ず角床-10を蚭定したす。 最埌に、他のオブゞェクトず同様に、 canvas.add()メ゜ッドを䜿甚しお远加したした。

そしお出来䞊がり キャンバス䞊に、碑文のある楕円のようなオブゞェクトが衚瀺されたす。 グルヌプのプロパティを倉曎するこずで簡単に倉曎できるこずに泚意しおください。 このオブゞェクト党䜓で䜜業できたす。

画像

キャンバスにグルヌプができたした。 少し倉えたしょう。

 group.item(0).setFill('red'); group.item(1).set({ text: 'trololo', fill: 'white' }); canvas.renderAll(); 

ここで䜕が起こっおいたすか item()メ゜ッドを䜿甚しおグルヌプ内のオブゞェクトにアクセスし、プロパティを倉曎したした。 最初のオブゞェクトは圧瞮された円で、2番目のオブゞェクトはテキストです。 䜕が起こったのか芋おみたしょう

画像

あなたがおそらく気づいた重芁なこずは、グルヌプ内のオブゞェクトがグルヌプの䞭心に揃えられおいるこずです。 テキストオブゞェクトのラベルを倉曎した堎合、幅を倉曎した埌でも䞭倮に配眮されたたたでした。 この動䜜は、オブゞェクトの座暙巊\䞊を蚭定するこずでキャンセルできたす。

3぀の円を䜜成しおグルヌプ化し、次々に氎平に配眮したす。

 var circle1 = new fabric.Circle({ radius: 50, fill: 'red', left: 0 }); var circle2 = new fabric.Circle({ radius: 50, fill: 'green', left: 100 }); var circle3 = new fabric.Circle({ radius: 50, fill: 'blue', left: 200 }); var group = new fabric.Group([ circle1, circle2, circle3 ], { left: 200, top: 100 }); canvas.add(group); 


画像

グルヌプで䜜業する堎合、オブゞェクトの状態に泚意を払う必芁がありたす 。 たずえば、むメヌゞのグルヌプを圢成する堎合、それらが完党にロヌドされおいるこずを確認する必芁がありたす。 幞いなこずに、Fabricには既補の゜リュヌションがありたす。

 fabric.Image.fromURL('/assets/pug.jpg', function(img) { var img1 = img.scale(0.1).set({ left: 100, top: 100 }); fabric.Image.fromURL('/assets/pug.jpg', function(img) { var img2 = img.scale(0.1).set({ left: 175, top: 175 }); fabric.Image.fromURL('/assets/pug.jpg', function(img) { var img3 = img.scale(0.1).set({ left: 250, top: 250 }); canvas.add(new fabric.Group([ img1, img2, img3], { left: 200, top: 200 })) }); }); }); 

画像

グルヌプにはさらにいく぀かの重芁な方法がありたす。 fabric.Canvas#getObjects()ず同じようにfabric.Canvas#getObjects()し、グルヌプ内のすべおのオブゞェクトの配列を返すgetObjects()メ゜ッド。 グルヌプ内のすべおのオブゞェクトの数を瀺すsize()メ゜ッドがありたす。 グルヌプ内の特定のオブゞェクトの存圚を確認するcontains()メ゜ッドもありcontains() 。 前述のitem()メ゜ッド。グルヌプから特定のオブゞェクトを取埗できたす。 forEachObject()メ゜ッドfabric.Canvas#forEachObjectず同様にfabric.Canvas#forEachObjectし、グルヌプのみで機胜したす。 最埌に、 add()およびremove()メ゜ッドは、それぞれグルヌプにオブゞェクトを远加および削陀したす。

グルヌプにオブゞェクトを远加/削陀するには、2぀の方法がありたす。 グルヌプの䜍眮/サむズの曎新ありずなし。
グルヌプの䞭心に長方圢を远加したす。

 group.add(new fabric.Rect({ ... originX: 'center', originY: 'center' })); 

グルヌプの䞭心から100pxの長方圢を远加したす。

 group.add(new fabric.Rect({ ... left: 100, top: 100, originX: 'center', originY: 'center' })); 

グルヌプの䞭心に長方圢を远加し、グルヌプサむズを曎新したす。

 group.addWithUpdate(new fabric.Rect({ ... left: group.getLeft(), top: group.getTop(), originX: 'center', originY: 'center' })); 

グルヌプの䞭心から100pxの長方圢を远加し、グルヌプのサむズを曎新したす。

 group.addWithUpdate(new fabric.Rect({ ... left: group.getLeft() + 100, top: group.getTop() + 100, originX: 'center', originY: 'center' })); 

既にキャンバス䞊にあるオブゞェクトのグルヌプを䜜成するには、それらを耇補しおからグルヌプ化する必芁がありたす。

 //     2-  . var group = new fabric.Group([ canvas.item(0).clone(), canvas.item(1).clone() ]); //     . canvas.clear().renderAll(); //    canvas. canvas.add(group); 

連茉


たずえば、ナヌザヌがキャンバスのコンテンツを保存できるようにしたり、別のクラむアントにブロヌドキャストしたりする機胜を実装する堎合は、キャンバスをシリアル化する必芁がありたす 。 キャンバスコンテンツを送信するにはどうすればよいですか もちろん、キャンバス党䜓を画像に゚クスポヌトするこずもできたすが、サヌバヌに画像をアップロヌドするのは面倒で䞍䟿です。 Fabricが私たちをずおも幞せにしおくれるよりも、コンテンツをテキストに翻蚳する方がはるかに簡単です。

メ゜ッドtoObject、toJSON


Fabrisでのシリアル化の基瀎は、 fabric.Canvas#toObject()およびfabric.Canvas#toJSON()です。
空のキャンバスをシリアル化する䟋を芋おみたしょう。

 var canvas = new fabric.Canvas('c'); JSON.stringify(canvas); // '{"objects":[],"background":"rgba(0, 0, 0, 0)"}' 

ES5 JSON.stringify()メ゜ッドを䜿甚したす。このメ゜ッドが存圚する堎合、オブゞェクトのtoJSONメ゜ッドを呌び出したす。 Fabricのキャンバスオブゞェクトにはこのメ゜ッドがあり、 JSON.stringify(canvas.toJSON())を呌び出すのず同等です。

空のキャンバスを衚す戻り文字列を考えたす。 JSON圢匏であり、プロパティ ''オブゞェクト ''および ''バックグラりンド ''で構成されたす。 キャンバスには䜕もないため、「オブゞェクト」プロパティは珟圚空です。「背景」には初期透明倀がありたす「rgba0、0、0、0」。

キャンバスを別の背景に蚭定し、どのような倉化があるかを確認したす。

 canvas.backgroundColor = 'red'; JSON.stringify(canvas); // '{"objects":[],"background":"red"}' 

予想どおり、キャンバスビュヌには別の背景が含たれるようになりたした。 それでは、いく぀かのオブゞェクトを远加しおみたしょう。

 canvas.add(new fabric.Rect({ left: 50, top: 50, height: 20, width: 20, fill: 'green' })); console.log(JSON.stringify(canvas)); 

...コン゜ヌルに出力されたす
 '{"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}],"background":"rgba(0, 0, 0, 0)"}' 

わあ 䞀芋、倚くのこずが倉曎されおいたすが、詳しく芋おみるず、この新しいオブゞェクトがJSONでシリアル化された「オブゞェクト」配列の䞀郚になっおいるこずがわかりたす。 その説明には、座暙、幅、高さ、塗り぀ぶしなどのすべおの芖芚的なコンポヌネントが含たれおいるこずに泚意しおください。 赀い円などの別のオブゞェクトを远加し、長方圢の埌ろに配眮するず、それに応じお結果が倉わりたす。

 canvas.add(new fabric.Circle({ left: 100, top: 100, radius: 50, fill: 'red' })); console.log(JSON.stringify(canvas)); 

...コン゜ヌルに出力されたす
 '{"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)"}' 

これらのオブゞェクトの開始䜍眮を瀺すために、 "type":"rect"および"type":"circle"を匷調衚瀺したした。 線が長すぎるように芋えるかもしれたせんが、画像をシリアル化するのに比べお、これらはただ花です。 比范のために、 canvas.toDataURL('png')メ゜ッドが返す1/10行を芋おください。

 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAK8CAYAAAAXo9vkAAAgAElEQVR4Xu3dP4xtBbnG4WPAQOQ2YBCLK1qpoQE1/m+NVlCDwUACicRCEuysrOwkwcJgAglEItRQaWz9HxEaolSKtxCJ0FwMRIj32zqFcjm8e868s2fNWo/Jygl+e397rWetk5xf5pyZd13wPwIECBAgQIAAAQIECBxI4F0H++Qb134R/U2fevC8q+5esGWESBAgAABAgQIEFiOwPL/MC5AlvO0OBMCBAgQIECAAAECJxQQICcE9HYCBAgQIECAAAECBPYXECD7W3klAQIECBAgQIAAAQInFBAgJwT0dgIECBAgQIAAAQIE9hcQIPtbeSUBAgQIECBAgAABAicUECAnBPR2AgQIECBAgAABAgT2FxAg+1t5JQECBAgQIECAAAECJxQQICcE9HYCBAgQIECAAAECBPYXECD7W3klAQIECBAgQIAAAQInFBAgJwTc9+3z49yvmNd+dI7PzPHJOW6Y4wNzXD3HlXNc9pZdb85/vzbHK3P8aY7n5vj1HL+Y43dz417f97O9jgABAgQIECBAgMBSBATIKd2JCY5dWNwyx5fn+PwcV5U/6tXZ99M5fjjHk3Mjd6HifwQIECBAgAABAgQWLSBAirdnouP6WXfvHHfOcU1x9T6rXp4XPTLHA3NTX9jnDV5DgAABAgQIECBA4NACAuSE4hMdl8+Kr83xzTmuO+G61ttfnEXfnuN7c4PfaC21hwABAgQIECBAgMBJBQTIJQpOeFw7b71/jtsvccWh3vbYfNB9c6NfOtQH+hwCBAgQIECAAAECFxMQIMd8No7C4+F5283HfOtZv/ypOYG7hMhZ3wafT4AAAQIECBDYtoAA2fP+H/1Vqwd3f4jf8y1Lfdkunu7xV7OWenucFwECBAgQIEBg3QICZI/7O/Fxx7xs9wf3t36r3D3evciX7L7F7+6rIY8u8uycFAECBAgQIE' 

さらに〜17,000文字 。

䞀芋、 fabric.Canvas#toObjectメ゜ッドがもう1぀fabric.Canvas#toObject理由は明らかではありたせん。 簡単ですtoObjectは、オブゞェクトずしおのみtoJSONず同じ衚珟を返したす。 たずえば、コンテンツが緑色の長方圢のキャンバスを䜿甚したす。 canvas.toObject()はコン゜ヌルに出力したす

 { "background" : "rgba(0, 0, 0, 0)", "objects" : [ { "angle" : 0, "fill" : "green", "flipX" : false, "flipY" : false, "hasBorders" : true, "hasControls" : true, "hasRotatingPoint" : false, "height" : 20, "left" : 50, "opacity" : 1, "overlayFill" : null, "perPixelTargetFind" : false, "scaleX" : 1, "scaleY" : 1, "selectable" : true, "stroke" : null, "strokeDashArray" : null, "strokeWidth" : 1, "top" : 50, "transparentCorners" : true, "type" : "rect", "width" : 20 } ] } 

ご芧のずおり、 toJSONの出力は、 toObject文字列の翻蚳にすぎたせん。 toObjectメ゜ッドtoObject 、スマヌトで怠toObjectずいう点toObject興味深く、䟿利です。 配列に衚瀺されるのは、すべおのキャンバスオブゞェクトを反埩凊理し、 toObjectメ゜ッドをtoObject委任したtoObjectです。 fabric.Pathクラスfabric.Pathは独自のtoObject 、これは ''ポむント ''の配列を返したす。 たた、 fabric.Imageもこのメ゜ッドがあり、画像の `` src ''プロパティを返したす。 OOPのパタヌンに埓っお、各オブゞェクトは自身をシリアル化する方法を知っおいたす。

぀たり、独自の「クラス」を䜜成する堎合、たたはオブゞェクトのシリアル化された衚珟を倉曎する堎合は、その機胜で䞊曞きたたは拡匵できるtoObjectメ゜ッドが必芁です。
䟋を芋おみたしょう

 var rect = new fabric.Rect(); rect.toObject = function() { return { name: 'trololo' }; }; canvas.add(rect); console.log(JSON.stringify(canvas)); 

...コン゜ヌルに出力されたす

 '{"objects":[{"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}' 

ご芧のずおり、「オブゞェクト」配列には、四角圢の衚珟が倉曎されおいたす。 ただし、この方法で曞き換えるこずはtoObject远加のプロパティでtoObject の機胜を拡匵するのずは異なり、あたり有甚ではないこずがよくありたす。

 var rect = new fabric.Rect(); rect.toObject = (function(toObject) { return function() { return fabric.util.object.extend(toObject.call(this), { name: this.name }); }; })(rect.toObject); canvas.add(rect); rect.name = 'trololo'; console.log(JSON.stringify(canvas)); 

...コン゜ヌルに出力されたす

 '{"objects":[{"type":"rect","left":0,"top":0,"width":0,"height":0,"fill":"rgb(0,0,0)","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,"name":"trololo"}],"background":"rgba(0, 0, 0, 0)"}' 

远加のプロパティ '' name ''を䜿甚しお、オブゞェクトの既存のtoObjectメ゜ッドを拡匵したした。 珟圚、メ゜ッド呌び出しの結果ずしお存圚しおいたす。 このように機胜を拡匵する堎合、オブゞェクトこの堎合はfabric.Rect の「クラス」には、配列 '' stateProperties ''に新しく远加されたプロパティが含たれおいる必芁があるこずに泚意しおください。 この堎合のみ、すべおが正しく機胜したす。

ToSVGメ゜ッド


キャンバスのもう1぀のテキスト衚珟は、SVG圢匏です。 FabricはSVGの解析ずキャンバス䞊の衚瀺を専門ずしおいたす。 これにより、キャンバスからSVGに、たたはその逆に倉換する機胜が提䟛されたす。 同じ長方圢をキャンバスに远加し、 toSVGメ゜ッドの動䜜を確認したす。

 canvas.add(new fabric.Rect({ left: 50, top: 50, height: 20, width: 20, fill: 'green' })); console.log(canvas.toSVG()); 

...コン゜ヌルに出力されたす

 '<?xml version="1.0" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve"><desc>Created with Fabric.js 0.9.21</desc><rect x="-10" y="-10" rx="0" ry="0" width="20" height="20" style="stroke: none; stroke-width: 1; stroke-dasharray: ; fill: green; opacity: 1;" transform="translate(50 50)" /></svg>' 

toJSONやtoObjectず同様に、 toSVGはキャンバスで呌び出されるず、そのロゞックを各オブゞェクトに委任し、各オブゞェクトは各タむプのオブゞェクトに固有の独自のtoSVGメ゜ッドを持ちたす。 toSVGメ゜ッドを倉曎たたは拡匵する必芁がある堎合は、 toSVGメ゜ッドず同じ方法で倉曎できたす。

toObject/toJSONず比范したSVGプレれンテヌションの利点は、SVGレンダリングが可胜な任意のデバむスブラりザヌ、アプリケヌション、プリンタヌ、カメラなどず連携できるこずです。 toObject / toJSONメ゜ッドでは、最初にビュヌをキャンバスにロヌドする必芁がありたす。 キャンバスぞの読み蟌みずいえば。 canvasのコンテンツをテキストにシリアル化できたすが、どのようにロヌドし盎すこずができたすか

逆シリアル化、SVGパヌサヌ


シリアル化の堎合ず同様に、文字列からキャンバスをロヌドするには、JSONビュヌずSVGビュヌからの2぀の方法がありたす。 JSONにはfabric.Canvas#loadFromJSONおよびfabric.Canvas#loadFromDatalessJSONメ゜ッドがありたす。 SVGの堎合-メ゜ッドfabric.loadSVGFromURLおよびfabric.loadSVGFromString 。
最初の2぀のメ゜ッドはキャンバスで呌び出され、他の2぀のメ゜ッドはファブリックで盎接呌び出されるこずに泚意しおください。

これらの方法に぀いお特別なこずはありたせん。 それらは期埅どおりに機胜したす。 たずえば、前のJSON出力を空のキャンバスに配眮したす。

 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)"}'); 

...䞡方のオブゞェクトがキャンバスに衚瀺されたす。

画像

さお、文字列からキャンバスをロヌドするこずは非垞に簡単ですが、䞀芋理解できないloadFromDatalessJSONメ゜ッドはどうでしょうか 先ほど䜿甚したloadFromJSONずの基本的な違いは䜕ですか このメ゜ッドの目的を理解するには、次のような、倚少耇雑なパスオブゞェクトを調べる必芁がありたす。

画像

...そしおJSON.stringify(canvas)は以䞋を出力したす

 '{"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]'... 

...そしお、これはテキスト党䜓の5番目の郚分です。

ここで䜕が起こっおいたすか Pathオブゞェクトは、このオブゞェクトの衚瀺方法を瀺す数癟のベゞェ曲線シンボルで構成されおいたす。 JSON圢匏のこれらすべおのパヌツ["c",0,2.67,-0.979,5.253,-2.048,9.079]は、いずれかの曲線の座暙です。 そしお、これらの曲線が数癟たたは数千ある堎合、匊の倧きさを掚枬するこずは難しくありたせん。

どうする

fabric.Canvas#toDatalessJSONメ゜ッドがfabric.Canvas#toDatalessJSON助けになりfabric.Canvas#toDatalessJSON 。 詊しおみたしょう

 canvas.item(0).sourcePath = '/assets/dragon.svg'; console.log(JSON.stringify(canvas.toDatalessJSON())); 

...コン゜ヌルに出力されたす

 {"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)"} 

たあ、はるかに少ない 私たちは䜕をしたしたか toDatalessJSONメ゜ッドを呌び出す前に、パスドラゎンシェむプの「sourcePath」プロパティを「/assets/dragon.svg」に蚭定するこずに泚意しおください。 次にtoDatalessJSONメ゜ッドを呌び出し、この巚倧なパス文字列党䜓が単玔な文字列「/assets/dragon.svg」に倉わりたした。

倚数の耇雑なフォヌムを䜿甚するtoDatalessJSONメ゜ッドを䜿甚するず、canvasのテキスト衚珟を倧幅に削枛し、倧きなパスデヌタを単玔なSVGリンクに眮き換えるこずができたす。

loadFromDatalessJSONメ゜ッドに戻るず、おそらくデヌタのないデヌタレスのビュヌからcanvasをロヌドできるず掚枬したでしょう。 loadFromDatalessJSONは、「パス」文字列「/assets/dragon.svg」などをロヌドし、それらをパスオブゞェクトのデヌタずしお䜿甚できたす。

SVGをロヌドする方法を芋おみたしょう。 文字列たたはURLを䜿甚できたす。

 fabric.loadSVGFromString('...', function(objects, options) { var obj = fabric.util.groupSVGElements(objects, options); canvas.add(obj).renderAll(); }); 

最初の匕数はSVG文字列で、2番目はコヌルバック関数です。 この関数は、SVGが読み蟌たれたずきに呌び出されたす。 objectsずoptions 2぀の匕数を取りoptions 。 objects -SVGから取埗したオブゞェクトの配列-パス、パスオブゞェクトのグルヌプ耇雑なオブゞェクト甚、画像、テキストなど これらすべおのオブゞェクトを1぀のコレクションにグルヌプ化し、SVGドキュメントにあるようにfabric.util.groupSVGElementsために、 objectsずoptions䞡方にfabric.util.groupSVGElementsを䜿甚しoptions 。 キャンバスに远加できるfabric.Pathたたはfabric.PathGroupオブゞェクトが䜜成されたす。

fabric.loadSVGFromURLも同様に機胜したすが、SVGのコンテンツではなく、URLを含む文字列を䜿甚したす。 FabricはXMLHttpRequestを介しおこのURLを取埗しようずするため、SVGぞのリンクはSOPルヌルに準拠する必芁があるこずに泚意しおください。

サブクラス化


FabricはOOPの原則に基づいお構築されおいるため、サブクラスを簡単に䜜成および䜜成し、オブゞェクトの機胜を拡匵できたす。 シリヌズの最初の郚分からわかるように、Fabricにはオブゞェクトの厳密な階局がありたす。 すべおの2Dオブゞェクトパス、画像、テキストなどはfabric.Objectから継承し、 fabric.Objectなどの䞀郚の「クラス」は3レベルの継承さえ持っおいたす。

Fabricの既存の「クラス」をサブクラス化するのはどうですか たたは、新しい「クラス」を䜜成したすか

これを行うには、javascriptの通垞のプロトタむプ継承を単玔に抜象化したfabric.util.createClassメ゜ッドが必芁です。 最初に、単玔な「クラス」ポむントを䜜成したす。

 var Point = fabric.util.createClass({ initialize: function(x, y) { this.x = x || 0; this.y = y || 0; }, toString: function() { return this.x + '/' + this.y; } }); 

createClassはオブゞェクトを受け取り、そのプロパティを新しい「クラス」のオブゞェクトのプロパティずしお䜿甚したす。 '' initialize ''はコンストラクタヌずしお䜿甚されたす。 したがっお、Pointを初期化するずきに、プロパティ '' x ''、 '' y ''、およびメ゜ッド '' toString ''を持぀新しいオブゞェクトを䜜成したす。

 var point = new Point(10, 20); point.x; // 10 point.y; // 20 point.toString(); // "10/20" 

「クラス」ポむントの子孫、たずえば色付きのポむントを䜜成する堎合、 createClassを䜿甚したす。

 var ColoredPoint = fabric.util.createClass(Point, { initialize: function(x, y, color) { this.callSuper('initialize', x, y); this.color = color || '#000'; }, toString: function() { return this.callSuper('toString') + ' (color: ' + this.color + ')'; } }); 

継承甚のオブゞェクトが2番目の匕数ずしお䜿甚されるようになりたした。最初の匕数は、このオブゞェクトの芪になる「クラス」ポむントです。 重耇を避けるために、芪の「クラス」でメ゜ッドを呌び出すcallSuperメ゜ッドを䜿甚したす。 これは、Pointを倉曎するず、倉曎がColoredPointも圱響するこずを意味したす。 䟋を芋おみたしょう

 var redPoint = new ColoredPoint(15, 33, '#f55'); redPoint.x; // 15 redPoint.y; // 33 redPoint.color; // "#f55" redPoint.toString(); "15/35 (color: #f55)" 

これで、独自の「クラス」ず「サブクラス」を䜜成する方法がわかりたしたが、Fabricで既存のものを䜿甚するこずもできたす。 たずえば、「クラス」 LabeledRect䜜成したす。これは、碑文のある長方圢になりたす。 「クラス」のむンスタンスがキャンバスに衚瀺されるず、ラベルは長方圢の内偎に衚瀺されたす。 「グルヌプ」の章ですでに怜蚎した類䌌の内容円ずテキスト。 ずころで、Fabricで䜜業しおいるずきに、グルヌプず「クラス」の䞡方を䜿甚しお抜象化をここで䜜成できるこずに気付くこずができたす。

 var LabeledRect = fabric.util.createClass(fabric.Rect, { type: 'labeledRect', initialize: function(options) { options || (options = { }); this.callSuper('initialize', options); this.set('label', options.label || ''); }, toObject: function() { return fabric.util.object.extend(this.callSuper('toObject'), { label: this.get('label') }); }, _render: function(ctx) { this.callSuper('_render', ctx); ctx.font = '20px Helvetica'; ctx.fillStyle = '#333'; ctx.fillText(this.label, -this.width/2, -this.height/2 + 20); } }); 

コヌドは耇雑に芋えるかもしれたせんが、非垞に単玔です。

最初に、衚瀺機胜を远加するために、芪の「クラス」をfabric.Rectずしおfabric.Rectしたす。 次に、プロパティ '' type ''を定矩し、倀 '' labeledRect ''に蚭定したす。 これは、Fabricアヌキテクチャに合わせるために行われたす。そこにあるすべおのオブゞェクトには、「type」長方圢、円、パス、テキストなどのプロパティがあるためです。

コンストラクタヌ initialize は既におなじみで、 callSuperを呌び出し、 callSuperでinitializeを呌び出しinitialize 。 さらに、 optionsから倀を取埗しお、オブゞェクトに碑文ラベルを付けoptions 。

その結果、2぀のメ゜ッドleft- toObjectず_renderたす。 toObject 、シリアル化の章から思い出すように、オブゞェクトを衚す責任がありたす。

LabeledRectは通垞のrectず同じプロパティがあるため、単玔にラベルを远加するこずで芪toObjectメ゜ッドを拡匵したした。

_renderメ゜ッドに関しおは、オブゞェクトを盎接レンダリングする責任がありたす。 これは、長方圢ディスプレむ callSuper ず远加のテキスト衚瀺ロゞックで構成されおいたす。

さお、そのようなオブゞェクトを衚瀺したい堎合

 var labeledRect = new LabeledRect({ width: 100, height: 50, left: 100, top: 100, label: 'test', fill: '#faa' }); canvas.add(labeledRect); 

...次のようになりたす

画像

プロパティラベルなどを倉曎するず、期埅される結果が生成されたす。

 labeledRect.set({ label: 'trololo', fill: '#aaf', rx: 10, ry: 10 }); 


画像

必芁に応じお、「クラス」の動䜜を倉曎できたす。 たずえば、コンストラクタでもう䞀床蚭定しないようにデフォルト倀を远加したす。 たたは、オブゞェクトでカスタムプロパティを䜿甚可胜にしたす。 远加のプロパティをカスタムにした堎合、それらをtoObjectに入れおinitialize 

 ... initialize: function(options) { options || (options = { }); this.callSuper('initialize', options); //       /   100/50 this.set({ width: 100, height: 50 }); this.set('label', options.label || ''); } ... _render: function(ctx) { //        ctx.font = this.labelFont; ctx.fillStyle = this.labelFill; ctx.fillText(this.label, -this.width/2, -this.height/2 + 20); } ... 

これで、シリヌズの第3郚は終わりです。 これで、グルヌプ、「クラス」、「サブクラス」、およびデシリアル化のアむデアが埗られたした。 この蚘事で玹介した資料が、Fabricのより耇雑な問題の解決に圹立぀こずを願っおいたす。 シリヌズの第4郚では、さらに倚くの情報が提瀺されたす。

成功ず開発の成功

翻蚳は、著者の同意ず盎接の参加で行われたした。 ゜ヌスぞのリンク 。

Source: https://habr.com/ru/post/J254763/


All Articles