JSFiddle - React, Tailwind, and code Playground

by codingdude

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<div>
    <img style="display: none" src="https://i.ibb.co/FhgZgzN/cat.png" id="img" crossorigin="anonymous">
    <img style="display: none" src="https://i.ibb.co/MBr3bzx/b17caaa9-69bd-44ea-a391-70a9e37963c8.png" id="mask" crossorigin="anonymous">
    <canvas id="canvas" width="500" height="500"></canvas>
</div>

JavaScript

window.onload = function () {
(function(){
    fabric.Image.filters.BlendImage.prototype.mode = "mask";
    fabric.Image.fromURL("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQYV2NgYGD4DwABBAEAcCBlCwAAAABJRU5ErkJggg==",function(img){
        fabric.Image.filters.BlendImage.prototype.image = img;
    })

    fabric.Image.filters.BlendImage.prototype.fragmentSource["mask"] = `
        precision highp float;
		uniform sampler2D uTexture;
		uniform sampler2D uImage;
		uniform vec4 uColor;
		varying vec2 vTexCoord;
		varying vec2 vTexCoord2;

		void main() {
			vec4 color = texture2D(uTexture, vTexCoord);
			vec4 color2 = texture2D(uImage, vTexCoord2);
			color.a *= color2.a;
			gl_FragColor = color;
		}`;


		fabric.MaskBrush = fabric.util.createClass(fabric.PencilBrush,{
		    initialize: function(options) {
		      this.canvas = options.canvas;
		      this.width = options.width;
		      this.target = options.target;
		      this.shadow = options.shadow;
		      this.blur = options.blur;
		      this.color = options.color;
		      this.targetMaskFilter = options.targetMaskFilter;
		      //"destination-over" ADD
		      //"source-out" REMOVE
		      this.mode = options.mode?options.mode:"source-out";
		      this._points = [];
		      
		    },
			_saveAndTransform: function(ctx) {
				var self = this;
				var v = this.canvas.viewportTransform;
				ctx.save();
				ctx.transform(v[0], v[1], v[2], v[3], v[4], v[5]);
				ctx.filter = self.blur?"blur("+self.blur+"px)":"none";
			},
		    _finalizeAndAddPath: function() {
		      var self = this;
		      var ctx = this.canvas.contextTop;
		      

		      ctx.closePath();
		      if (this.decimate) {
		        this._points = this.decimatePoints(this._points, this.decimate);
		      }
		      var pathData = this.convertPointsToSVGPath(this._points).join('');
		      if (pathData === 'M 0 0 Q 0 0 0 0 L 0 0') {
		        // do not create 0 width/height paths, as they are
		        // rendered...