FabricJS Puppet Wrap
by codingdude
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.4.0/fabric.min.js"></script>
<canvas width="600" height="400" id="c"></canvas>
<img style="display:none" src="https://upload.wikimedia.org/wikipedia/en/0/05/Flag_of_Brazil.svg" id="my-image" crossorigin="anonymous">
<input id="v" type="range" min="-5" max="5" step="any" value="0">
JavaScript
//https://testdrive-archive.azurewebsites.net/Graphics/Warp/Default.html
function setupFilter(options){
fabric.Image.filters[options.filterName] = fabric.util.createClass(fabric.Image.filters.BaseFilter, Object.assign({
type: options.filterName,
applyTo2d: function(options) {
alert("This filter only works on browsers that support webgl");
},
resolution:100,
getPosition:function(){
var resolution = this.resolution;
var q = 0.001;
var r = (1 - q * 2) / resolution;
var c = new Float32Array(resolution * resolution * 12); //2 numbers per coord; three coords per triangle; 2 triagles per square; resolution * resolution squares
var i = 0;
for (var xs = 0; xs < resolution; xs++) {
for (var ys = 0; ys < resolution; ys++) {
var x = r * xs + q;
var y = r * ys + q;
c[i++] = x;
c[i++] = y;
c[i++] = x + r;
c[i++] = y;
c[i++] = x;
c[i++] = y + r;
c[i++] = x + r;
c[i++] = y;
c[i++] = x;
c[i++] = y + r;
c[i++] = x + r;
c[i++] = y + r;
}
}
return c;
},
renderLines:false,
applyToWebGL: function(options) {
options.aPosition = this.getPosition();
var gl = options.context;
var shader = this.retrieveShader(options);
if (options.pass === 0 && options.originalTexture) {
gl.bindTexture(gl.TEXTURE_2D, options.originalTexture);
}
else {
gl.bindTexture(gl.TEXTURE_2D, options.sourceTexture);
}
gl.useProgram(shader.program);
this.sendAttributeData(gl, shader.attributeLocations, options.aPosition);
gl.uniform1f(shader.uniformLocations.uStepW, 1 / options.sourceWidth);
gl.uniform1f(shader.uniformLocations.uStepH,...