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...