image-distort-filter-for-fabric

by Steve Eberhardt

HTML

<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/fabric.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/js/verb.min.js"></script>


<canvas id="canvas"></canvas>

Babel + JSX

fabric.textureSize = 4096;
// Set default filter backend
fabric.filterBackend = new fabric.WebglFilterBackend();
fabric.isWebglSupported(fabric.textureSize);

fabric.Image.filters.Perspective = class extends fabric.Image.filters.BaseFilter {
    /**
     * Constructor
     * @param {Object} [options] Options object
     */
    constructor(options) {
        super();

        if (options) this.setOptions(options);

        this.applyPixelRatio();
    }

    type = 'Perspective';
    pixelRatio = fabric.devicePixelRatio;
    bounds = {width: 0, height: 0, minX: 0, maxX: 0, minY: 0, maxY: 0};
    hasRelativeCoordinates = true;

    /**
     * Array of attributes to send with buffers. do not modify
     * @private
     *//** @ts-ignore */
    vertexSource = `
        precision mediump float;

        attribute vec2 aPosition;
        attribute vec2 aUvs;

        uniform float uStepW;
        uniform float uStepH;

        varying vec2 vUvs;

        vec2 uResolution;

        void main() {
            vUvs = aUvs;
            uResolution = vec2(uStepW, uStepH);

            gl_Position = vec4(uResolution * aPosition * 2.0 - 1.0, 0.0, 1.0);
        }
    `;

    fragmentSource = `
        precision mediump float;
        varying vec2 vUvs;
        uniform sampler2D uSampler;

        void main() {
            gl_FragColor = texture2D(uSampler, vUvs);
        }
    `;

    /**
     * Return a map of attribute names to WebGLAttributeLocation objects.
     *
     * @param {WebGLRenderingContext} gl The canvas context used to compile the shader program.
     * @param {WebGLShaderProgram} program The shader program from which to take attribute locations.
     * @returns {Object} A map of attribute names to attribute locations.
     */
    getAttributeLocations(gl, program) {
        return {
            aPosition: gl.getAttribLocation(program, 'aPosition'),
            aUvs: gl.getAttribLocation(program, 'aUvs'),
        };
    }

    /**
     * Send attribute data from...