FabricJs:从 JSON (patternSourceCanvas) 保存和加载动态模式
FabricJs: Saving and loading dynamic patterns from JSON (patternSourceCanvas)
我在保存和加载应用于对象的 dynamic patterns 时遇到问题。
我在网上搜索过这个问题的解决方案,但无济于事。我明白why it is happening,但不明白如何解决。
这基本上就是我正在做的...
- 正在将动态模式应用于对象。
- 将 canvas 保存到 MongoDB 使用...'JSON.stringify(canvas.toJSON([...]))'
- 正在使用 'loadFromJSON'
加载 canvas
- 获取错误'Uncaught ReferenceError: patternSourceCanvas is not defined'
我在这个问题上发现的一切都可以追溯到至少 2 年前 (some even 2013),没有可靠的代码示例。
更新
这是我用来在路径上应用模式的函数...
function applyPatternOnPath(p, image, width, patternRepeat, patternPadding) {
if (patternRepeat) {
var r = 'repeat'
} else {
var r = 'no-repeat'
}
fabric.Image.fromURL(image, function(img) {
var padding = 0 + patternPadding;
img.scaleToWidth(width);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: function() {
patternSourceCanvas.setDimensions({
width: img.getScaledWidth() + padding,
height: img.getScaledHeight() + padding
});
patternSourceCanvas.renderAll();
return patternSourceCanvas.getElement();
},
repeat: r
});
p.set('fill', pattern);
canvas.renderAll();
}, { crossOrigin: 'Anonymous' });
}
我已经通过一些变通方法解决了我的问题。我不确定这是否是 "correct" 处理使用 JSON 保存的动态模式的方法,但它对我有用。
这是我正在做的...
- 正在将动态图案应用到对象上。
就在将 canvas(JSON 字符串)保存到 MongoDB 之前,我正在做两件事...
a) 在名为 'canvasLayers'.
的 mongoDB 文档的字段之一上保存对象信息(包括模式 src、宽度、填充等)
b) 通过将 'fill' 属性 设置为“”来清除应用了动态模式的路径的所有 'fill' 属性。
所以 JSON 在保存到数据库时不包含任何模式信息。
加载以前保存的 canvas 时,我 re-applying 基于保存在每个对象的 'canvasLayers' 字段中的模式信息的模式。
基本上,我不是用 JSON 字符串保存模式信息,而是将模式数据存储在一个单独的对象(mongodb 字段),然后 re-applying canvas 加载时的模式。
使用以下代码将图像源转换为 base 64 格式并存储并重新打开。
//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)
})
Css
canvas{
border:2px solid #000;
}
Html :
<canvas id="canvas" width="300" height="300"></canvas><br>
<button id="loadjson">loadfromjson </button>
<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>
我在保存和加载应用于对象的 dynamic patterns 时遇到问题。
我在网上搜索过这个问题的解决方案,但无济于事。我明白why it is happening,但不明白如何解决。
这基本上就是我正在做的...
- 正在将动态模式应用于对象。
- 将 canvas 保存到 MongoDB 使用...'JSON.stringify(canvas.toJSON([...]))'
- 正在使用 'loadFromJSON' 加载 canvas
- 获取错误'Uncaught ReferenceError: patternSourceCanvas is not defined'
我在这个问题上发现的一切都可以追溯到至少 2 年前 (some even 2013),没有可靠的代码示例。
更新
这是我用来在路径上应用模式的函数...
function applyPatternOnPath(p, image, width, patternRepeat, patternPadding) {
if (patternRepeat) {
var r = 'repeat'
} else {
var r = 'no-repeat'
}
fabric.Image.fromURL(image, function(img) {
var padding = 0 + patternPadding;
img.scaleToWidth(width);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: function() {
patternSourceCanvas.setDimensions({
width: img.getScaledWidth() + padding,
height: img.getScaledHeight() + padding
});
patternSourceCanvas.renderAll();
return patternSourceCanvas.getElement();
},
repeat: r
});
p.set('fill', pattern);
canvas.renderAll();
}, { crossOrigin: 'Anonymous' });
}
我已经通过一些变通方法解决了我的问题。我不确定这是否是 "correct" 处理使用 JSON 保存的动态模式的方法,但它对我有用。
这是我正在做的...
- 正在将动态图案应用到对象上。
就在将 canvas(JSON 字符串)保存到 MongoDB 之前,我正在做两件事...
a) 在名为 'canvasLayers'.
的 mongoDB 文档的字段之一上保存对象信息(包括模式 src、宽度、填充等)b) 通过将 'fill' 属性 设置为“”来清除应用了动态模式的路径的所有 'fill' 属性。
所以 JSON 在保存到数据库时不包含任何模式信息。
加载以前保存的 canvas 时,我 re-applying 基于保存在每个对象的 'canvasLayers' 字段中的模式信息的模式。
基本上,我不是用 JSON 字符串保存模式信息,而是将模式数据存储在一个单独的对象(mongodb 字段),然后 re-applying canvas 加载时的模式。
使用以下代码将图像源转换为 base 64 格式并存储并重新打开。
//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)
})
Css
canvas{
border:2px solid #000;
}
Html :
<canvas id="canvas" width="300" height="300"></canvas><br>
<button id="loadjson">loadfromjson </button>
<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>