FabricJS Filter Vignette

by codingdude

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
<canvas width="600" height="400" id="c"></canvas>
<img style="display:none" src="https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg" id="my-image" crossorigin="anonymous">
<br/>
Radius:
<input type="range" min="0" max="1" step="0.01" id="vignetteRadius"/>
<br/>
Smoothness:
<input type="range" min="0" max="1" step="0.01" id="vignetteSmoothness"/>

JavaScript

fabric.textureSize = 4096;//for filters on large images
var canvas = new fabric.Canvas('c');
var imgElement = document.getElementById('my-image');
var imgInstance = new fabric.Image(imgElement, {
  left: 100,
  top: 50,
  angle: 0,
  opacity: 1,
  scaleX:0.1,
  scaleY:0.1
});
canvas.add(imgInstance);



fabric.Image.filters.Vignette = fabric.util.createClass(fabric.Image.filters.BaseFilter, {

  type: 'Vignette',
	radius:0.1,
  smoothness:0.5,
  mainParameter:"radius",
  /**
   * Fragment source for the redify program
   */
  fragmentSource: 
    'precision highp float;\n' +
    'uniform sampler2D uTexture;\n' +
    'uniform float uRadius;'+
    'uniform float uSmoothness;'+
    'varying vec2 vTexCoord;\n' +
    'float vignette(vec2 uv, float radius, float smoothness) {'+
		'float diff = radius - distance(uv, vec2(0.5, 0.5));'+
		'return smoothstep(-smoothness, smoothness, diff);'+
		'}'+
    'void main() {\n' +
    	'vec2 p = -1.0 + 2.0 * vTexCoord;'+
      'float r = 1.0 - uRadius;'+
      'float vignetteValue = vignette(vTexCoord, r, uSmoothness);'+
      'vec4 color = vec4(texture2D(uTexture, vTexCoord).rgb * vignetteValue,1.0);'+
      //'vec4 color = vec4(texture2D(uTexture,vTexCoord).rgb*r,1.0);\n' +
      
      //'color.g = 1.0;\n' +
      //'color.b = 0.0;\n' +
      'gl_FragColor = color;\n' +
    '}',

  applyTo2d: function(options) {
    var imageData = options.imageData,
        data = imageData.data, i, len = data.length;

    for (i = 0; i < len; i += 4) {
      data[i + 1] = 0;
      data[i + 2] = 0;
    }

  },
  getUniformLocations: function(gl, program) {
      return {
        uRadius: gl.getUniformLocation(program, 'uRadius'),
        uSmoothness: gl.getUniformLocation(program, 'uSmoothness')
      };
    },
  sendUniformData: function(gl, uniformLocations) {
      gl.uniform1f(uniformLocations.uRadius, this.radius);
      gl.uniform1f(uniformLocations.uSmoothness, this.smoothness);
    }
});

fabric.Image.filters.Vignette.fromObject =...