4

我正在尝试保存 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>
4

2 回答 2

0

这可能是有史以来最新的答案,但我想我不妨回答一下,因为这是在 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/ (该特定代码似乎不起作用)

于 2014-05-06T19:22:04.477 回答
0

使用以下代码将图像源转换为 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>

于 2018-07-19T07:16:07.173 回答