【问题标题】:Load from JSON with dynamic patterns使用动态模式从 JSON 加载
【发布时间】:2013-08-24 15:54:04
【问题描述】:

我正在尝试保存 Fabric.js 画布并使用 loadFromJson 重新加载它。 但我收到错误 patternSourceCanvas 未定义。 我想我应该让它成为全局的,所以我删除了 var. 但是当我用新图案填充其他一些新形状时,这个新图案将应用于所有先前绘制的在画布上具有旧图案的形状。 请帮助我处理动态模式。

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <title>Dynamic patterns | Fabric.js Demos</title>




    <!--[if lt IE 9]>
      <script src="../lib/excanvas.js"></script>
    <![endif]-->

    <!-- <script src="base/prism.js"></script> -->
    <script src="http://fabricjs.com/lib/fabric.js"></script>
  </head>
  <body>





    <div id="bd-wrapper">
      <h2><span>Fabric.js demos</span>Dynamic patterns</h2>



<div>
  <p>
    <label>Repeat pattern?</label>
    <input type="checkbox" id="img-repeat" checked>
  </p>
  <p>
    <label>Pattern image width</label>
    <input type="range" min="50" max="1000" value="100" id="img-width">
  </p>
  <p>
    <label>Pattern left offset</label>
    <input type="range" min="0" max="500" value="0" id="img-offset-x">
  </p>
  <p>
    <label>Pattern top offset</label>
    <input type="range" min="0" max="500" value="0" id="img-offset-y">
  </p>
  <br>
  <p>
    <label>Pattern image angle</label>
    <input type="range" min="-90" max="90" value="0" id="img-angle">
  </p>
  <p>
    <label>Pattern image padding</label>
    <input type="range" min="-50" max="50" value="0" id="img-padding">
  </p>

</div>
<div><button id="toJson">TOJSON</button></div>
<div><button id="fromJson">LoadFromJSON</button></div>
<canvas id="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
<script>






var canvas = new fabric.Canvas('c');
var padding = 0;

fabric.Image.fromURL('http://fabricjs.com/assets/pug.jpg', function(img) {

  img.scaleToWidth(100).set({
    originX: 'left',
    originY: 'top'
  });

  var patternSourceCanvas = new fabric.StaticCanvas();
  patternSourceCanvas.add(img);

  var pattern = new fabric.Pattern({
    source: function() {
      patternSourceCanvas.setDimensions({
        width: img.getWidth() + padding,
        height: img.getHeight() + padding
      });
      return patternSourceCanvas.getElement();
    },
    repeat: 'repeat'
  });

  canvas.add(new fabric.Polygon([
    {x: 185, y: 0},
    {x: 250, y: 100},
    {x: 385, y: 170},
    {x: 0, y: 245} ], {
      left: 220,
      top: 200,
      angle: -30,
      fill: pattern
    }));




  document.getElementById('img-width').onchange = function() {
    img.scaleToWidth(parseInt(this.value, 10));
    canvas.renderAll();
  };
  document.getElementById('img-angle').onchange = function() {
    img.setAngle(this.value);
    canvas.renderAll();
  };
  document.getElementById('img-padding').onchange = function() {
    padding = parseInt(this.value, 10);
    canvas.renderAll();
  };
  document.getElementById('img-offset-x').onchange = function() {
    pattern.offsetX = parseInt(this.value, 10);
    canvas.renderAll();
  };
  document.getElementById('img-offset-y').onchange = function() {
    pattern.offsetY = parseInt(this.value, 10);
    canvas.renderAll();
  };
  document.getElementById('img-repeat').onclick = function() {
    pattern.repeat = this.checked ? 'repeat' : 'no-repeat';
    canvas.renderAll();
  };
});
document.getElementById('toJson').onclick = function () {
    jsonData = JSON.stringify(canvas);
}
document.getElementById('fromJson').onclick = function () {
    canvas.clear();
    canvas.loadFromJSON(jsonData);
    canvas.renderAll();

}

</script>


</body>
</html>

【问题讨论】:

    标签: javascript canvas fabricjs


    【解决方案1】:

    这可能是最新的答案,但我想我还是回答吧,因为这是在 Google 上搜索此问题时最先遇到的问题之一,而且我也遇到了这个问题。

    问题是源函数被序列化为代码,例如:

    "fill":{
                "source":"function () {\r\n\t                    patternSourceCanvas.setDimensions({\r\n\t                        width: img.getWidth(),\r\n\t                        height: img.getHeight(),\r\n\t                    });\r\n\t                    return patternSourceCanvas.getElement();\r\n\t                }",
                "repeat":"repeat",
                "offsetX":0,
                "offsetY":0
             },
    

    到目前为止,最好的解决方法是创建自己的对象来扩展所需的形状,并覆盖 toObject() 和初始化函数。这将允许您保存和加载所需的自定义数据。

    大概是这样的:http://jsfiddle.net/Ly9YY/(该特定代码似乎不起作用)

    【讨论】:

    • 我在 4 年后遇到了这个问题,这似乎仍然是在 Google 中搜索此问题时最先遇到的问题之一。不幸的是,我并没有真正理解你的答案。 4年后有这方面的更多信息吗?如何保存和加载应用于对象的动态模式?
    【解决方案2】:

    使用以下代码将图像源转换为 UTFEncode 格式并存储该 JSON 并重新打开它。 查看演示链接:

    //override toObject of fabric.Pattern
    var toFixed = fabric.util.toFixed;
    fabric.Pattern.prototype.toObject = function(propertiesToInclude) {
      var NUM_FRACTION_DIGITS = fabric.Object.NUM_FRACTION_DIGITS,
        source, object;
      if (typeof this.source === "function") {
        source = String(this.source);
      } else if (typeof this.source.src === "string") {
        source = this.source.src;
      } else if (typeof this.source === "object" && this.source.toDataURL) {
        source = this.source.toDataURL();
      }
      object = {
        type: "pattern",
        source: source,
        repeat: this.repeat,
        crossOrigin: this.crossOrigin,
        offsetX: toFixed(this.offsetX, NUM_FRACTION_DIGITS),
        offsetY: toFixed(this.offsetY, NUM_FRACTION_DIGITS),
        patternTransform: this.patternTransform ? this.patternTransform.concat() : null
      };
      fabric.util.populateWithProperties(this, object, propertiesToInclude);
      return object;
    };
    
    
    
    var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/22/Wikimapia_logotype.svg';
    var canvas = new fabric.Canvas('canvas');
    var rect = new fabric.Rect({
      width: 200,
      height: 200,
      strokeWidth: 2,
      stroke: '#000'
    })
    canvas.add(rect);
    
    fabric.Image.fromURL(imageUrl, function(img) {
      //alert('t' + img);
      console.log('img', img);
      img.scaleToHeight(200);
      var patternSourceCanvas = new fabric.StaticCanvas();
      patternSourceCanvas.add(img);
      patternSourceCanvas.setDimensions({
        width: img.getWidth(),
        height: img.getHeight()
      });
      patternSourceCanvas.renderAll();
      var pattern = new fabric.Pattern({
        source: patternSourceCanvas.getElement()
      });
      rect.fill = pattern;
      canvas.renderAll();
    }, {
      crossOrigin: 'annonymous'
    });
    
    $('#loadjson').on('click', function() {
      var json = canvas.toJSON();
      console.log('json', json['objects']);
      canvas.clear();
      setTimeout(function() {
        canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
      }, 3000)
    })
    canvas{
      border:2px solid #000;
    }
    <canvas id="canvas" width="300" height="300"></canvas><br>
    <button  id="loadjson">loadfromjson </button>
    <!-- <script src='https://rawgit.com/kangax/fabric.js/master/dist/fabric.js'></script> -->
    
    <script src='https://www.multicastr.com/imageeditor/assets/js/fabric.unmin.js'></script>
    
    <script src="https://www.multicastr.com/user/js/jquery.min.js"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-14
      • 1970-01-01
      • 2012-12-10
      • 1970-01-01
      • 2019-04-04
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      相关资源
      最近更新 更多