fabric.js clipTo image

Clipping function for fabric.Objects (image)

by Arthur Lutkevichus

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.1.0/fabric.min.js"></script>
<canvas id="canvas" width="400" height="400" class="canvas"></canvas>

CSS

.canvas {
  border: 1px solid #C0C0C0;
}

JavaScript

var canvas,
  lastTop,
  lastHeight;

$(function() {
  canvas = window._canvas = new fabric.Canvas('canvas');
  var text = new fabric.Textbox("Some content goes here", {
    opacity: 1,
    hoverCursor: "pointer",
    selectable: true,
    visible: true,
    editable: true,
    lockScalingFlip: true,
    hasRotatingPoint: false,
    borderColor: "#4393fd",
    cornerColor: "#4393fd",
    left: 25,
    top: 25,
    fontSize: 28,
    lineHeight: 1,
    splitByGrapheme: true,
    width: 200,
    fill: "red",
    height: 32,
    clipTo: function(ctx) {
      ctx.rect(-text.width / 2, -text.height / 2, text.width, 32);
    }
  });

  text.set({
    height: 32,
  })

  text.on("scaling", event => {
    let height = event.transform.action === "scaleY" ? event.target.getScaledHeight() : lastHeight || 32;
    let top = event.target.top;

		let delta = Math.max(event.transform.ey - event.target.top, 0);

    if (event.transform.corner === "mt") {
    	if (delta > 0) {
      top -= delta / 2;
      height = event.target.height + (delta / 2);
      }
      else {
      height: lastHeight;
      }
    }
    console.log(delta, event.target.height, event.target.getScaledHeight())

    text.set({
      //top,
      height
    });

    lastHeight = text.height;
    lastTop = text.top;

    text.set({
      clipTo: function(ctx) {
        ctx.rect(-text.width / 2, -text.height / 2, text.width, text.height);
      }
    })

    canvas.renderAll();
  });

  canvas.add(text).setActiveObject(text);

  canvas.renderAll();
});