我正在尝试保存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>
答案 0 :(得分: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/(特定代码似乎不起作用)
答案 1 :(得分:0)
使用以下代码将Image源转换为UTFEncode格式,并存储该JSON并重新打开该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>