FabricJS - Preserve events on saving / getting canvas from JSON

孤街浪徒 提交于 2021-02-19 06:27:04

问题


Is there a way to "preserve" events when saving canvas to JSON and then get them bonded back on loadFromJSON

In the link below I've created an element redBox and bonded an event "moving" on it. After "restoring" canvas from JSON that event no longer available and it makes sense why...

The problem is, based on requirements, I have no idea what element could be in the JSON and what event was previously applied to it. Basically, I need dynamically apply all possible events on that particular element.

http://jsfiddle.net/redlive/rwdt6rwj/

fabric.util.object.extend(fabric.Image.prototype, {
		toObject: function() {
        return fabric.util.object.extend(this.callSuper('toObject'), {
            	sanboxValues: this.get('sanboxValues'),
          		imgSrc: this.get('imgSrc')
            }
            // name: this.get('name'),
        );
    },
    ddpLoadImage: function(imgSrc, sanboxValues){
    	this.setSrc(imgSrc, function(img){
        const {scaleFactor} = sanboxValues;
        img.scale( 1 / scaleFactor ).setCoords();
        img.set({
          clipTo:	function(ctx){
            const {x, y, width, height, scaleFactor} = this.sanboxValues;
            ctx.rect(
                x * scaleFactor - width / 2, 
                y * scaleFactor - height / 2, 
                width * scaleFactor, 
                height * scaleFactor
            );
          }
        });
        image.canvas.renderAll()
	  	}, {
		    sanboxValues,
    		imgSrc
			});
		}
});


let store;
const canvas = new fabric.Canvas('paper');
const canvasOriginalSize = {
	width: 600,
  height: 600
};

const image = new fabric.Image('', {
    left: 50,
    top: 50,
});

const redBox = new fabric.Rect({
    left: 0,
    top: 0,
    width: 50,
    height: 50,
    fill: 'red'
});


const page = new fabric.Rect({
    left: 50,
    top: 50,
    width: 300,
    height: 300
});

canvas.add(page);
canvas.add(image);
canvas.add(redBox);
canvas.renderAll();



canvas.on("object:modified", function(obj){
	console.log(obj.target);
});

redBox.on("moving", function(obj){
	console.log('Moving redBox');
});




const scaleFactor = 1;
const imgSrc = ['https://picsum.photos/', page.width * scaleFactor,'/',  page.height * scaleFactor].join('');
const x = 10, y = 7, width = page.width, height = page.height; 

image.ddpLoadImage(imgSrc, {x, y, width, height, scaleFactor});

  
  
  
  
  
$("#save").on('click', function(){
	store = canvas.toJSON();
  console.log(store);
});
    
$("#restore").on('click', function(){
	canvas.loadFromJSON(store, function(){
      canvas.getObjects().forEach((obj)=>{
          if (obj.type === 'image') {
						obj.ddpLoadImage(obj.imgSrc, obj.sanboxValues);
          }
      });
    	canvas.renderAll();
	});
});
    
#paper {
  border: solid 1px red;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.3/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="image" />
<canvas id="paper" width="400" height="400" style="border:1px solid #ccc"></canvas>
<button id="save">Save to JSON</button>
<button id="restore">Restore form JSON</button>

回答1:


You have to again attach events to objects. In loadFromJSON 3rd arguments which is reviver having object from json and fabric object. Add event to fabric objects.

DEMO

fabric.util.object.extend(fabric.Image.prototype, {
  toObject: function() {
    return fabric.util.object.extend(this.callSuper('toObject'), {
        sanboxValues: this.get('sanboxValues'),
        imgSrc: this.get('imgSrc')
      }
      // name: this.get('name'),
    );
  },
  ddpLoadImage: function(imgSrc, sanboxValues) {
    this.setSrc(imgSrc, function(img) {
      const {
        scaleFactor
      } = sanboxValues;
      img.scale(1 / scaleFactor).setCoords();
      img.set({
        clipTo: function(ctx) {
          const {
            x,
            y,
            width,
            height,
            scaleFactor
          } = this.sanboxValues;
          ctx.rect(
            x * scaleFactor - width / 2,
            y * scaleFactor - height / 2,
            width * scaleFactor,
            height * scaleFactor
          );
        }
      });
      image.canvas.renderAll()
    }, {
      sanboxValues,
      imgSrc
    });
  }
});


let store;
const canvas = new fabric.Canvas('paper');
const canvasOriginalSize = {
  width: 600,
  height: 600
};

const image = new fabric.Image('', {
  left: 50,
  top: 50,
});

const redBox = new fabric.Rect({
  left: 0,
  top: 0,
  width: 50,
  height: 50,
  fill: 'red',
  rectType: 'eventedRect'
});


const page = new fabric.Rect({
  left: 50,
  top: 50,
  width: 300,
  height: 300
});

canvas.add(page,image,redBox);

canvas.on("object:modified", function(obj) {
  console.log(obj.target);
});

redBox.on("moving", rectMoving);

function rectMoving(obj) {
  console.log('Moving redBox');
};

const scaleFactor = 1;
const imgSrc = ['https://picsum.photos/', page.width * scaleFactor, '/', page.height * scaleFactor].join('');
const x = 10,
  y = 7,
  width = page.width,
  height = page.height;

image.ddpLoadImage(imgSrc, {
  x,
  y,
  width,
  height,
  scaleFactor
});


$("#save").on('click', function() {
  store = canvas.toJSON(['rectType']);
  console.log(store);
});

$("#restore").on('click', function() {
  canvas.loadFromJSON(store, function() {
    canvas.renderAll();
  },function(o,object){
    if (object.rectType == 'eventedRect') {
      object.on("moving", rectMoving);
    }
    if (object.type === 'image') {
      object.ddpLoadImage(object.imgSrc, object.sanboxValues);
    }
  });
});
#paper {
  border: solid 1px red;
}
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.3/fabric.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="image" />
<canvas id="paper" width="400" height="400" style="border:1px solid #ccc"></canvas>
<button id="save">Save to JSON</button>
<button id="restore">Restore form JSON</button>


来源:https://stackoverflow.com/questions/49697408/fabricjs-preserve-events-on-saving-getting-canvas-from-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!