FabricJS Filter Gradient Map
by codingdude
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.6/fabric.min.js"></script>
<script src="https://artf.github.io/grapick/dist/grapick.min.js"></script>
<script id="shader" type="x-shader/x-vertex">
precision highp float;
uniform sampler2D uTexture;
uniform float uPixelsPerRow;
uniform float uStepW,uStepH;
uniform vec3 uColors[10];
uniform float uColorPositions[10];
varying vec2 vTexCoord;
uniform float uParam;
void main() {
vec4 origColor = texture2D(uTexture, vTexCoord);
float grayscaleValue = dot(origColor.rgb, vec3(0.499, 0.087, 0.614));
gl_FragColor = mix(vec4(uColors[0], 1.0), vec4(0.0, 1.0, 0.0, 1.0), grayscaleValue/2.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/>
<div id="gp"></div>
CSS
.grp-wrapper{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==")}.grp-preview{position:absolute;top:0;left:0;width:100%;height:100%;cursor:crosshair}.grp-handler{width:4px;margin-left:-2px;user-select:none;-webkit-user-select:none;-moz-user-select:none;height:100%}.grp-handler-close{color:rgba(0,0,0,0.4);border-radius:100%;box-shadow:0 2px 10px rgba(0,0,0,0.25);background-color:#fff;text-align:center;width:15px;height:15px;margin-left:-5px;line-height:10px;font-size:21px;cursor:pointer}.grp-handler-close-c{position:absolute;top:-17px}.grp-handler-drag{background-color:rgba(0,0,0,0.5);cursor:col-resize;width:100%;height:100%}.grp-handler-selected .grp-handler-drag{background-color:rgba(255,255,255,0.5)}.grp-handler-cp-c{display:none}.grp-handler-selected .grp-handler-cp-c{display:block}.grp-handler-cp-wrap{width:15px;height:15px;margin-left:-8px;border:3px solid #fff;box-shadow:0 2px 10px rgba(0,0,0,0.25);overflow:hidden;border-radius:100%;cursor:pointer}.grp-handler-cp-wrap input[type=color]{opacity:0;cursor:pointer}
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.CustomFilter = fabric.util.createClass(fabric.Image.filters.BaseFilter, {
type: 'CustomFilter',
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);
}
});
fabric.Image.filters.CustomFilter.fromObject = fabric.Image.filters.BaseFilter.fromObject;
var filter = new fabric.Image.filters.CustomFilter({param:0});
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();
} */
//window.onload = function(){
var gp = new Grapick({
el: '#gp',
direction: 'to right',
min: 1,
max: 99,
});
gp.addHandler(1, '#085078', 0);
gp.addHandler(99, '#85D8CE', 0);
gp.on('change', function(complete) {
console.log(gp.getHandlers());
//document.body.style.backgroundImage = gp.getSafeValue();
})
...