2017-09-18 13 views
0

Fabric.jsでカスタムクラスを作成しようとしていて、保存して読み込むことができます。 LineクラスとCircleクラスを拡張してカスタム属性を追加しようとしています...しかし、データをロードしようとすると問題が発生しています。それはokを保存し、私の単純な 'name'属性はそこにありますが、ロードしようとすると、klassがfabric.util.getKlass関数からそのオブジェクト型を取得する場所である "enlivenObjects"関数にぶつかります。私は私のオブジェクトのために何も戻って来ない( "未定義")。 添付の例では、「SAVE」をクリックすると、キャンバスのデータがDIVに入れられます。キャンバスを「クリア」し、データを「ロード」しようとします。ロードしようとするとエラーが発生します。 JS Consoleのウィンドウでは、 "fabric.util.getKlass( 'Line')"を実行することができます。それはオブジェクトを取得しますが、私の 'namedCircle'または 'namedLine'定義されていない... どのような考えですか?このアプローチは私にとってはうまくいかないでしょうか?Fabric.js既存のシェイプからの新しいクラスfromObjectエラー

var canvas; 
 
      
 
    window.onload = function() { 
 
     canvas = new fabric.Canvas('c'); 
 

 
     /** 
 
     * Attempt to make a custom Line, inherited from the fabric.Line 
 
     * currently has a custom attribute of 'name' 
 
     * 
 
     */ 
 
     fabric.namedLine = fabric.util.createClass(fabric.Line, { 
 
      type: 'namedLine', 
 
      initialize: function(points, options) { 
 
       options || (options = { }); 
 
       this.callSuper('initialize', points, options); 
 
       this.set('name', options.name || ''); 
 
      }, 
 
      toObject: function() { 
 
       return fabric.util.object.extend(this.callSuper('toObject'), { 
 
       name: this.get('name') 
 
       }); 
 
      }, 
 
      fromObject: function(object, callback) { 
 
       return fabric.Object._fromObject('namedLine', options, callback); 
 
      }, 
 
      _render: function(ctx) { 
 
       this.callSuper('_render', ctx); 
 
      } 
 
     }); 
 

 
     /** 
 
     * Attempt at custom Circle, inherited from fabric.Circle with 
 
     * a 'name' attribute. 
 
     * 
 
     */ 
 
     fabric.namedCircle = fabric.util.createClass(fabric.Circle, { 
 
      type: 'namedCircle', 
 
      initialize: function(options) { 
 
       options || (options = { }); 
 
       this.callSuper('initialize', options); 
 
       this.set('name', options.name || ''); 
 
      }, 
 
      toObject: function() { 
 
       return fabric.util.object.extend(this.callSuper('toObject'), { 
 
       name: this.get('name') 
 
       }); 
 
      }, 
 
      fromObject: function(object, callback) { 
 
       return fabric.Object._fromObject('namedCircle', object, callback); 
 
      }, 
 
      _render: function(ctx) { 
 
       this.callSuper('_render', ctx); 
 
      } 
 
     }); 
 
     
 
     fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center'; 
 

 
     // First Create our line. 
 
     var line = makeLine([ 250, 125, 250, 175 ], "myLine"); 
 
     canvas.add(line); 
 
     
 
     // Now we create our circles, linking to our line. 
 
     canvas.add(
 
      // first circle is at top of line, line1 is null, line2 is the line. 
 
      makeCircle(line.get('x1'), line.get('y1'), "head", null, line), 
 

 
      // second circle is at the bottom, line 1 is the line, nothing for line 2. 
 
      makeCircle(line.get('x2'), line.get('y2'), "tail", line), 
 
     ); 
 

 
     canvas.on('object:moving', function(e) { 
 
      var p = e.target; 
 
      // set bottom of the line to the shapes left and top position. 
 
      p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top }); 
 
      // set the top to the line to the circle position. 
 
      p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top }); 
 
      canvas.renderAll(); 
 
     }); 
 

 
     // Add our button events. 
 
     document.getElementById("btnSave").addEventListener("click", saveData); 
 
     document.getElementById("btnLoad").addEventListener("click", loadData); 
 
     document.getElementById("btnClear").addEventListener("click", clearData); 
 

 
    }; 
 

 
    // our circle has up to 2 links. 
 
    function makeCircle(left, top, name, line1, line2) { 
 
     var c = new fabric.namedCircle({ 
 
      left: left, 
 
      top: top, 
 
      strokeWidth: 5, 
 
      radius: 12, 
 
      fill: '#fff', 
 
      stroke: '#666', 
 
      name: name 
 
     }); 
 
     c.hasControls = c.hasBorders = false; 
 

 
     c.line1 = line1; 
 
     c.line2 = line2; 
 

 
     return c; 
 
    } 
 

 
    function makeLine(coords, name) { 
 
     return new fabric.namedLine(coords, { 
 
      fill: 'red', 
 
      stroke: 'red', 
 
      strokeWidth: 5, 
 
      selectable: false, 
 
      name: name 
 
     }); 
 
    } 
 

 
    function saveData() { 
 
     document.getElementById("out").innerHTML = ""; 
 
     document.getElementById("out").innerHTML = JSON.stringify(canvas.toDatalessJSON()); 
 
    }; 
 

 
    function loadData() { 
 
     var data = document.getElementById("out").innerHTML; 
 
     console.log(data); 
 
     canvas.loadFromDatalessJSON(data); 
 
     canvas.renderAll(); 
 
    }; 
 

 
    function clearData() { 
 
     canvas.clear(); 
 
    }
#out { 
 
    width:500px; 
 
    height:300px; 
 
    border:1px solid red; 
 
    overflow:scroll; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"></script> 
 
<canvas style="border: 2px solid; " height="500" width="600" id="c"></canvas> 
 
<p> 
 
    <button id="btnSave">Save</button> 
 
    <button id="btnClear">Clear</button> 
 
    <button id="btnLoad">Load</button> 
 
</p> 
 
<div id="out"></div>

答えて

0

まあ、時にはあなただけ離れて物事からステップ、それについて考える必要があります。 getKlass関数を詳しく見てみましょう。クラス名の最初の文字を大文字にします... "namedLine"と "namedCircle"から "NamedLine"と "NamedCircle"にクラスを変更することです。 私がしなければならなかったもう一つのことは、クラスの外に戻り関数を移動することでした。

var canvas; 
 
      
 
    /** 
 
    * Attempt to make a custom Line, inherited from the fabric.Line 
 
    * currently has a custom attribute of 'name' 
 
    * 
 
    */ 
 
     fabric.NamedLine = fabric.util.createClass(fabric.Line, { 
 
     type: 'NamedLine', 
 
     initialize: function(points, options) { 
 
      options || (options = { }); 
 
      this.callSuper('initialize', points, options); 
 
      this.set('name', options.name || ''); 
 
     }, 
 
     toObject: function() { 
 
      return fabric.util.object.extend(this.callSuper('toObject'), { 
 
      name: this.get('name') 
 
      }); 
 
     }, 
 
     _render: function(ctx) { 
 
      this.callSuper('_render', ctx); 
 
     } 
 
    }); 
 
    fabric.NamedLine.fromObject = function(object, callback) { 
 
     callback && callback(new fabric.NamedLine([object.x1, object.y1, object.x2, object.y2], object)); 
 
    }; 
 

 

 
    /** 
 
    * Attempt at custom Circle, inherited from fabric.Circle with 
 
    * a 'name' attribute. 
 
    * 
 
    */ 
 
    fabric.NamedCircle = fabric.util.createClass(fabric.Circle, { 
 
     type: 'NamedCircle', 
 
     initialize: function(options) { 
 
      options || (options = { }); 
 
      this.callSuper('initialize', options); 
 
      this.set('name', options.name || ''); 
 
     }, 
 
     toObject: function() { 
 
      return fabric.util.object.extend(this.callSuper('toObject'), { 
 
      name: this.get('name') 
 
      }); 
 
     }, 
 
     _render: function(ctx) { 
 
      this.callSuper('_render', ctx); 
 
     } 
 
    }); 
 

 
    fabric.NamedCircle.fromObject = function(object, callback) { 
 
     return fabric.Object._fromObject('NamedCircle', object, callback); 
 
    }; 
 

 
    fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center'; 
 

 

 

 

 
    window.onload = function() { 
 
     canvas = new fabric.Canvas('c'); 
 

 
     
 
     // First Create our line. 
 
     var line = makeLine([ 250, 125, 250, 175 ], "myLine"); 
 
     canvas.add(line); 
 
     
 
     // Now we create our circles, linking to our line. 
 
     canvas.add(
 
      // first circle is at top of line, line1 is null, line2 is the line. 
 
      makeCircle(line.get('x1'), line.get('y1'), "head", null, line), 
 

 
      // second circle is at the bottom, line 1 is the line, nothing for line 2. 
 
      makeCircle(line.get('x2'), line.get('y2'), "tail", line), 
 
     ); 
 

 
     canvas.on('object:moving', function(e) { 
 
      var p = e.target; 
 
      // set bottom of the line to the shapes left and top position. 
 
      p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top }); 
 
      // set the top to the line to the circle position. 
 
      p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top }); 
 
      canvas.renderAll(); 
 
     }); 
 

 
     // Add our button events. 
 
     document.getElementById("btnSave").addEventListener("click", saveData); 
 
     document.getElementById("btnLoad").addEventListener("click", loadData); 
 
     document.getElementById("btnClear").addEventListener("click", clearData); 
 

 
    }; 
 

 
    // our circle has up to 2 links. 
 
    function makeCircle(left, top, name, line1, line2) { 
 
     var c = new fabric.NamedCircle({ 
 
      left: left, 
 
      top: top, 
 
      strokeWidth: 5, 
 
      radius: 12, 
 
      fill: '#fff', 
 
      stroke: '#666', 
 
      name: name 
 
     }); 
 
     c.hasControls = c.hasBorders = false; 
 

 
     c.line1 = line1; 
 
     c.line2 = line2; 
 

 
     return c; 
 
    } 
 

 
    function makeLine(coords, name) { 
 
     return new fabric.NamedLine(coords, { 
 
      fill: 'red', 
 
      stroke: 'red', 
 
      strokeWidth: 5, 
 
      selectable: false, 
 
      name: name 
 
     }); 
 
    } 
 

 
    function saveData() { 
 
     document.getElementById("out").innerHTML = ""; 
 
     document.getElementById("out").innerHTML = JSON.stringify(canvas.toDatalessJSON()); 
 
    }; 
 

 
    function loadData() { 
 
     var data = document.getElementById("out").innerHTML; 
 
     console.log(data); 
 
     canvas.loadFromDatalessJSON(data); 
 
     canvas.renderAll(); 
 
    }; 
 

 
    function clearData() { 
 
     canvas.clear(); 
 
    }
#out { 
 
    width:500px; 
 
    height:300px; 
 
    border:1px solid red; 
 
    overflow:scroll; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.19/fabric.min.js"></script> 
 
<canvas style="border: 2px solid; " height="500" width="600" id="c"></canvas> 
 
<p> 
 
    <button id="btnSave">Save</button> 
 
    <button id="btnClear">Clear</button> 
 
    <button id="btnLoad">Load</button> 
 
</p> 
 
<div id="out"></div>

関連する問題