2024-06-02 09:30:07 608 0
本文收集了几种搜索网站的结果,进行了对比,并结合自身项目做了解决方案
如下是百度的回答:
在使用fabric.js进行开发时,如果在执行undo和redo操作时发现自定义属性丢失,很可能是因为你没有正确地序列化和反序列化这些自定义属性。
为了确保自定义属性在undo和redo操作中得以保留,你需要在初始化fabric.js对象时,使用toObject方法手动包含这些自定义属性。同时,在从对象的状态恢复时,使用fromObject方法来设置这些属性。
// 假设有一个自定义属性 customProp
var customProp = { value: 'custom' };
// 创建fabric对象时,包含自定义属性
var obj = new fabric.Circle({
radius: 20,
fill: 'red',
customProp: customProp
});
// 将对象转换为对象状态(对象的JSON表示)
var objState = obj.toObject(['customProp']); // 包含自定义属性在内的序列化
// 之后,当你需要从这个状态恢复对象时
var restoredObj = new fabric.Circle(objState);
// 你可以这样设置自定义属性
restoredObj.set('customProp', customProp);
// 现在,当你执行 undo 和 redo 操作时,customProp 应该会被正确处理。
如下是腾讯爬取s't'a'c'k的回答:
text = new fabric.IText('Tap and Type');
// my new object
var newtext = text.toJSON();
// adding my attribute
newtext.attr1 = "value 1";
// object showing fine as json object
console.log(newtext);
// stringified object showing with my added attributes
console.log(JSON.stringify(newtext));
如下是博客园:
const a = canvas.toJSON(['id1', 'id2']);
const b = canvas.toDatalessJSON(['id1', 'id2']);
const c = canvas.toDatalessObject(['id1', 'id2']);
const d = canvas.toObject(['id1', 'id2']);
如下是github issue:
Undo redo is not something fabricJS ship with.
It has been discussed in various issues how to get there and different way to implement that, please have a search in past issues, closed or open
如下是stack:
fabric.StaticCanvas.prototype.getObjectByName = function(name){
if(!name || typeof name === 'undefined'){
return [];
}
return this._objects.filter(function(o) {
return o.name === name;
});
}
var canvas = new fabric.Canvas('fabriccanvas');
canvas.counter = 0;
var newleft = 0;
canvas.selection = false;
var undoStack = [];
var redoStack = [];
addrect = function addrect(top, left, width, height, fill) {
var rect = new fabric.Rect({
top: document.getElementById("fabriccanvas").height,
name: 'rectangle ' + canvas.counter,
left: 0 + newleft,
width: 100,
height: 100,
fill: '#' + (0x1000000 + (Math.random()) * 0xffffff).toString(16).substr(1, 6),
//fix attributes applied for all rects
opacity: 0.75,
lockRotation: true,
originX: 'left',
originY: 'bottom',
cornerSize: 15,
hasRotatingPoint: false,
perPixelTargetFind: true,
minScaleLimit: 1
})
canvas.add(rect);
undoStack.push({
type:'added',
object : rect
})
canvas.counter++;
newleft += 100;
redoStack=[];
}
var state = [];
var mods = 0;
var props = {};
canvas.on(
'mouse:down', function (e) {
var block = e.target;
if(block){
props.oldStage = {
left:block.left,
top:block.top,
width:block.width,
height:block.height,
scaleX:block.scaleX,
scaleY:block.scaleY,
}
}
}).on(
'mouse:up', function (e) {
var block = e.target;
if(block){
props.newStage = {
left:block.left,
top:block.top,
width:block.width,
height:block.height,
scaleX:block.scaleX,
scaleY:block.scaleY,
}
undoStack.push({
objectName : block.name,
type:'modified',
oldStage:props.oldStage,
newStage:props.newStage
});
props={};
}
});
undo = function undo() {
if(undoStack.length){
var undoData = undoStack.pop();
if(undoData && undoData.type){
switch(undoData.type){
case 'added':
var objectByName = canvas.getObjectByName(undoData.object.name);
if(objectByName.length){
canvas.remove(objectByName[0]);
}
break;
case 'modified':
var objectByName = canvas.getObjectByName(undoData.objectName);
if(objectByName.length){
for(var key in undoData.oldStage){
objectByName[0].set(key, undoData.oldStage[key]);
}
}
break;
}
canvas.renderAll();
}
redoStack.push(undoData);
}
}
redo = function redo() {
if(redoStack.length){
var redoData = redoStack.pop();
if(redoData && redoData.type){
switch(redoData.type){
case 'added':
if(redoData.object){
canvas.add(redoData.object);
}
break;
case 'modified':
var objectByName = canvas.getObjectByName(redoData.objectName);
if(objectByName.length){
for(var key in redoData.newStage){
objectByName[0].set(key, redoData.newStage[key]);
}
}
break;
}
canvas.renderAll();
}
undoStack.push(redoData);
}
}
clearcan = function clearcan() {
canvas.clear().renderAll();
canvas.counter=0;
undoStack=[];
redoStack=[];
newleft = 0;
}
笔者由于只使用在一个项目中,故直接在插件写死交付。
/**
* Initialization of the plugin
*/
fabric.Canvas.prototype._historyInit = function () {
this.historyUndo = [];
this.historyRedo = [];
this.extraProps = ['selectable', 'editable','prodId','spaceProdId','picType','prodPicId','border','borderMsg'
,'afterStatus'];
this.historyNextState = this._historyNext();
this.on(this._historyEvents());
}