title: FabricJS - Preserve events on saving / getting canvas from JSON
body: <p>Is there a way to "preserve" events when saving canvas to JSON and then get them bonded back on <strong><em>loadFromJSON</em></strong></p>
  
  <p>In the link below I've created an element <em>redBox</em> and bonded an event "moving" on it. After "restoring" canvas from JSON that event no longer available and it makes sense why... </p>
  
  <p>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.</p>
  
  <p><a href="http://jsfiddle.net/redlive/rwdt6rwj/" rel="nofollow noreferrer">http://jsfiddle.net/redlive/rwdt6rwj/</a></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>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)=&gt;{
            if (obj.type === 'image') {
        obj.ddpLoadImage(obj.imgSrc, obj.sanboxValues);
            }
        });
       canvas.renderAll();
   });
  });
      </code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>#paper {
    border: solid 1px red;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.3/fabric.js"&gt;&lt;/script&gt;
  &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;img id="image" /&gt;
  &lt;canvas id="paper" width="400" height="400" style="border:1px solid #ccc"&gt;&lt;/canvas&gt;
  &lt;button id="save"&gt;Save to JSON&lt;/button&gt;
  &lt;button id="restore"&gt;Restore form JSON&lt;/button&gt;</code></pre>
  </div>
  </div>
  </p>