0

fabric.Object.prototype.objectCaching = false;
var canvasBackground = new fabric.Canvas('backgroundcanvas');
var canvas = new fabric.Canvas('paintcanvas');
var canvas_2 = new fabric.Canvas('paintcanvas_2');
var canvas_3 = new fabric.Canvas('paintcanvas_3');
var canvas_4 = new fabric.Canvas('paintcanvas_4');


fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_01.png', function(myImg) {
 var img1 = myImg.set({ 
    top: 0,
    left: 0,
    scaleX: canvas.width/myImg.width,
    scaleY: canvas.height/myImg.height,
  selectable : false,
    evented: false
 });
 canvas.add(img1); 
});

fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
 var img1 = myImg.set({ 
    top: 20,
    left: 20,
    width: 300,
    height: 300,
  globalCompositeOperation: 'source-atop'
 });
 canvas.add(img1);
});


fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_02.png', function(myImg) {
 var img1 = myImg.set({ 
    top: 0,
    left: 0,
    scaleX: canvas.width/myImg.width,
    scaleY: canvas.height/myImg.height,
  selectable : false,
    evented: false
 });
 canvas_2.add(img1); 
});

fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
 var img1 = myImg.set({ 
    top: 20,
    left: 420,
    width: 300,
    height: 300,
  globalCompositeOperation: 'source-atop'
 });
 canvas_2.add(img1);
});


fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_03.png', function(myImg) {
 var img1 = myImg.set({ 
    top: 0,
    left: 0,
    scaleX: canvas.width/myImg.width,
    scaleY: canvas.height/myImg.height,
  selectable : false,
    evented: false
 });
 canvas_3.add(img1); 
});

fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
 var img1 = myImg.set({ 
    top: 220,
    left: 220,
    width: 300,
    height: 300,
  globalCompositeOperation: 'source-atop'
 });
 canvas_3.add(img1);
});


fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_04.png', function(myImg) {
 var img1 = myImg.set({ 
    top: 0,
    left: 0,
    scaleX: canvas.width/myImg.width,
    scaleY: canvas.height/myImg.height,
  selectable : false,
    evented: false
 });
 canvas_4.add(img1); 
});

fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
 var img1 = myImg.set({ 
    top: 420,
    left: 420,
    width: 300,
    height: 300,
  globalCompositeOperation: 'source-atop'
 });
 canvas_4.add(img1);
});


fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy.png', function(myImg) {
 var img1 = myImg.set({ 
   globalCompositeOperation: 'destination-over',
    top: 0,
    left: 0,
    scaleX: canvasBackground.width/myImg.width,
    scaleY: canvasBackground.height/myImg.height,    
  selectable : false,
    evented: false
 });
 canvasBackground.add(img1); 
});


var $con_1 = $('.paintcanvas');
var $con_2 = $('.paintcanvas_2');
var $con_3 = $('.paintcanvas_3');
var $con_4 = $('.paintcanvas_4');

canvas.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_2.css('pointer-events',/*!*/'none');
      } else {
        $con_2.css('pointer-events',/*!*/'all');
      }
    },
});

canvas_2.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_2.css('pointer-events',/*!*/'all');
      } else {
        $con_2.css('pointer-events',/*!*/'none');
      }
    }
});

canvas_3.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_4.css('pointer-events',/*!*/'none');
      } else {
        $con_4.css('pointer-events',/*!*/'all');
      }
    }
});

canvas_4.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_4.css('pointer-events',/*!*/'all');
      } else {
        $con_4.css('pointer-events',/*!*/'none');
      }
    }
});
.parent {
  position: relative;
  background: black;
}


.backgroundcanvas {
  position: absolute;
  left: 0;
  top: 0;
}

.paintcanvas, .paintcanvas_2, .paintcanvas_3, .paintcanvas_4 {
  position: absolute;
  left: 0px;
  top: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<div class="parent">
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>
  <div class="backgroundcanvas">
    <canvas id="backgroundcanvas"  width="800" height="800"></canvas>  
  </div>
  <div class="paintcanvas">
    <canvas id="paintcanvas" width="800" height="800" ></canvas>  
  </div>
  <div class="paintcanvas_2">
    <canvas id="paintcanvas_2" width="800" height="800" ></canvas>  
  </div>
  <div class="paintcanvas_3">
    <canvas id="paintcanvas_3" width="800" height="800" ></canvas>  
  </div>
  <div class="paintcanvas_4">
    <canvas id="paintcanvas_4" width="800" height="800" ></canvas>  
  </div>
</div>

I managed to create several masked canvas elements in a stacked quilt of canvasses. These are each deposited with a globalCompositeOperation processed mask into which a user should be able to upload a photo.

Now every uploaded image element should be move-/scaleable in every canvas. I try to accomplish this with a bubbling of the pointer events.

I've done this because you can not mask multiple overlapping elements in one canvas independently (masking affects all pixels) and svg's are not possible due to the underlying design and performance. Because 'destination-over' is not working in this combination, the background was excluded in a static canvas.

With two layers / canvasses this can be solved like this:

var $con_1 = $('.paintcanvas');
var $con_2 = $('.paintcanvas_2');

canvas_1.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_1.css('pointer-events',/*!*/'all');
      } else {
        $con_1.css('pointer-events',/*!*/'none');
      }
    }
});

canvas_2.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_2.css('pointer-events',/*!*/'none');
      } else {
        $con_2.css('pointer-events',/*!*/'all');
      }
    }
});

However, I need four layers and do not understand how to bubble down the events.

I've created a fiddle for this here (With canvas content 3+4 editable): https://jsfiddle.net/Metamagikum/2Lpwchzd/199/

metamagikum
  • 1,307
  • 15
  • 19
  • Please trim your code down to a [mcve], then use [Stack Snippets](https://meta.stackoverflow.com/q/358992/215552) to provide the code here on Stack Overflow. – Heretic Monkey May 03 '19 at 19:37

1 Answers1

0

I solved it like this. It's working, but still searching for a better solution.

var $con_1 = $('.paintcanvas');
var $con_2 = $('.paintcanvas_2');
var $con_3 = $('.paintcanvas_3');
var $con_4 = $('.paintcanvas_4');

canvas.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_1.css('pointer-events',/*!*/'all');
      } else {
        $con_2.css('pointer-events',/*!*/'all');
        $con_3.css('pointer-events',/*!*/'all');
        $con_4.css('pointer-events',/*!*/'all');
      }
    },
});

canvas_2.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_2.css('pointer-events',/*!*/'all');
      } else {
        $con_2.css('pointer-events',/*!*/'none');
      }
    }
});

canvas_3.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_3.css('pointer-events',/*!*/'all');
      } else {
        $con_3.css('pointer-events',/*!*/'none');
      }
    }
});

canvas_4.on({
    'mouse:move': function(e) {
      if (e.target) {
        $con_4.css('pointer-events',/*!*/'all');
      } else {
        $con_4.css('pointer-events',/*!*/'none');
      }
    }
});
metamagikum
  • 1,307
  • 15
  • 19