FabricJS Filter Pixelate
by codingdude
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
<script id="shader" type="x-shader/x-vertex">
precision highp float;
uniform sampler2D uTexture;
uniform float uStepW,uStepH;
varying vec2 vTexCoord;
uniform float uParam;
void main() {
vec2 p = vTexCoord.st;
float pixelSizeOneW = 1.0 / uStepW;
float pixelSizeOneH = 1.0 / uStepH;
p.x -= mod(p.x, uParam * pixelSizeOneW);
p.y -= mod(p.y, uParam * pixelSizeOneH);
vec3 col = texture2D(uTexture, p).rgb;
gl_FragColor = vec4(col, 1.0);
}
</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/>
Param:
<input type="range" min="0.1" max="100" step="0.01" id="param"/>
JavaScript
//https://github.com/genekogan/Processing-Shader-Examples/blob/master/TextureShaders/data/
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.Pixelate = fabric.util.createClass(fabric.Image.filters.BaseFilter, {
type: 'Pixelate',
param:1,
mainParameter:"param",
/**
* Fragment source for the redify program
*/
fragmentSource: window.document.getElementById("shader").textContent,
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 {
uParam: gl.getUniformLocation(program, 'uParam')
};
},
sendUniformData: function(gl, uniformLocations) {
gl.uniform1f(uniformLocations.uParam, this.param);
gl.uniform1f(uniformLocations.uStepW, canvas.width);
gl.uniform1f(uniformLocations.uStepH, canvas.height);
}
});
fabric.Image.filters.Pixelate.fromObject = fabric.Image.filters.BaseFilter.fromObject;
var filter = new fabric.Image.filters.Pixelate({param:7});
imgInstance.filters.push(filter);
imgInstance.applyFilters();
var slider = window.document.getElementById("param");
slider.oninput = slider.onchange = function(){
filter.param = this.value;
console.log(this.value);
imgInstance.applyFilters();
canvas.requestRenderAll();
}