JSFiddle - React, Tailwind, and code Playground

by Eugene Vilder

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.0/fabric.min.js"></script>
<canvas id="paper" width="800" height="800" style="border:1px solid #ccc"></canvas>

JavaScript

fabric.Container = fabric.util.createClass(fabric.Rect, {
  type: 'container',
  initialize: function(options) {
    options || (options = { });
    this.set('objectCaching', false);
    this.callSuper('initialize', options);
  },
  _render: function(ctx) {
    const container = this;
    const content = this.get('content');

    fabric.Image.fromURL(this.get('src'), function(img) {            
      let patternSourceCanvas = new fabric.StaticCanvas();
              
      patternSourceCanvas.setBackgroundColor('red', patternSourceCanvas.renderAll.bind(patternSourceCanvas));
      patternSourceCanvas.setBackgroundImage(img, patternSourceCanvas.renderAll.bind(patternSourceCanvas), {
        top: content.top,
        left: content.left,
        originX: 'left',
        originY: 'top'
      });
      patternSourceCanvas.renderAll();

      let pattern = function(t){
        return new fabric.Pattern({
          source: function() {
            patternSourceCanvas.setDimensions({
              width: img.getWidth() + ( (t.width || container.width) - img.getWidth() ),
              height: img.getHeight() + ( (t.height || container.height) - img.getHeight() ),
            });
            patternSourceCanvas.renderAll();
            return patternSourceCanvas.getElement();
          },
          repeat: 'no-repeat',
          offsetX: 0
        });
      }

      container.set('fill', pattern(container));

      container.on('scaling', function(){
        const scaleX = container.get('scaleX');
        const scaleY = container.get('scaleY');
        const width = container.get('width');
        const height = container.get('height');
        container.set({
          scaleX: 1,
          scaleY: 1,
          width: width * scaleX,
          height: height * scaleY,
          fill: pattern(container)
        })
      });

      container.on('object:dblclick', function (options) {
      });
      
      ////////////////////////////////////////////////
      //...