Skip to content

Commit

Permalink
auto transform pr
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaMan123 committed Jun 12, 2022
1 parent 79d5b07 commit 0b6da98
Show file tree
Hide file tree
Showing 9 changed files with 609 additions and 588 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
(function(global) {
//@ts-nocheck

'use strict';

var fabric = global.fabric,
Expand Down Expand Up @@ -26,42 +27,42 @@
* canvas.renderAll();
*/

filters.BlendImage = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.BlendImage.prototype */ {
type: 'BlendImage',
export class BlendImage extends fabric.Image.filters.BaseFilter {
type = 'BlendImage'

/**
* Color to make the blend operation with. default to a reddish color since black or white
* gives always strong result.
**/
image: null,
image = null

/**
* Blend mode for the filter (one of "multiply", "mask")
* @type String
* @default
**/
mode: 'multiply',
mode = 'multiply'

/**
* alpha value. represent the strength of the blend image operation.
* not implemented.
**/
alpha: 1,
alpha = 1

vertexSource: 'attribute vec2 aPosition;\n' +
vertexSource = 'attribute vec2 aPosition;\n' +
'varying vec2 vTexCoord;\n' +
'varying vec2 vTexCoord2;\n' +
'uniform mat3 uTransformMatrix;\n' +
'void main() {\n' +
'vTexCoord = aPosition;\n' +
'vTexCoord2 = (uTransformMatrix * vec3(aPosition, 1.0)).xy;\n' +
'gl_Position = vec4(aPosition * 2.0 - 1.0, 0.0, 1.0);\n' +
'}',
'}'

/**
* Fragment source for the Multiply program
*/
fragmentSource: {
fragmentSource = {
multiply: 'precision highp float;\n' +
'uniform sampler2D uTexture;\n' +
'uniform sampler2D uImage;\n' +
Expand All @@ -86,43 +87,43 @@
'color.a = color2.a;\n' +
'gl_FragColor = color;\n' +
'}',
},
}

/**
* Retrieves the cached shader.
* @param {Object} options
* @param {WebGLRenderingContext} options.context The GL context used for rendering.
* @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
*/
retrieveShader: function(options) {
retrieveShader(options) {
var cacheKey = this.type + '_' + this.mode;
var shaderSource = this.fragmentSource[this.mode];
if (!options.programCache.hasOwnProperty(cacheKey)) {
options.programCache[cacheKey] = this.createProgram(options.context, shaderSource);
}
return options.programCache[cacheKey];
},
}

applyToWebGL: function(options) {
applyToWebGL(options) {
// load texture to blend.
var gl = options.context,
texture = this.createTexture(options.filterBackend, this.image);
this.bindAdditionalTexture(gl, texture, gl.TEXTURE1);
this.callSuper('applyToWebGL', options);
super.applyToWebGL(options);
this.unbindAdditionalTexture(gl, gl.TEXTURE1);
},
}

createTexture: function(backend, image) {
createTexture(backend, image) {
return backend.getCachedTexture(image.cacheKey, image._element);
},
}

/**
* Calculate a transformMatrix to adapt the image to blend over
* @param {Object} options
* @param {WebGLRenderingContext} options.context The GL context used for rendering.
* @param {Object} options.programCache A map of compiled shader programs, keyed by filter type.
*/
calculateMatrix: function() {
calculateMatrix() {
var image = this.image,
width = image._element.width,
height = image._element.height;
Expand All @@ -131,15 +132,15 @@
0, 1 / image.scaleY, 0,
-image.left / width, -image.top / height, 1
];
},
}

/**
* Apply the Blend operation to a Uint8ClampedArray representing the pixels of an image.
*
* @param {Object} options
* @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
*/
applyTo2d: function(options) {
applyTo2d(options) {
var imageData = options.imageData,
resources = options.filterBackend.resources,
data = imageData.data, iLen = data.length,
Expand Down Expand Up @@ -188,46 +189,46 @@
break;
}
}
},
}

/**
* Return WebGL uniform locations for this filter's shader.
*
* @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
* @param {WebGLShaderProgram} program This filter's compiled shader program.
*/
getUniformLocations: function(gl, program) {
getUniformLocations(gl, program) {
return {
uTransformMatrix: gl.getUniformLocation(program, 'uTransformMatrix'),
uImage: gl.getUniformLocation(program, 'uImage'),
};
},
}

/**
* Send data from this filter to its shader program's uniforms.
*
* @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
* @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
*/
sendUniformData: function(gl, uniformLocations) {
sendUniformData(gl, uniformLocations) {
var matrix = this.calculateMatrix();
gl.uniform1i(uniformLocations.uImage, 1); // texture unit 1.
gl.uniformMatrix3fv(uniformLocations.uTransformMatrix, false, matrix);
},
}

/**
* Returns object representation of an instance
* @return {Object} Object representation of an instance
*/
toObject: function() {
toObject() {
return {
type: this.type,
image: this.image && this.image.toObject(),
mode: this.mode,
alpha: this.alpha
};
}
});
}

/**
* Create filter instance from an object representation
Expand All @@ -241,4 +242,3 @@
});
};

})(typeof exports !== 'undefined' ? exports : this);
39 changes: 26 additions & 13 deletions src/mixins/animation.mixin.js → src/mixins/animation.mixin.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
//@ts-nocheck

export function StaticCanvasAnimationMixinGenerator(Klass) {
return class StaticCanvasAnimationMixin extends Klass {

/**
* Animation duration (in ms) for fx* methods
* @type Number
* @default
*/
FX_DURATION: 500,
FX_DURATION = 500

/**
* Centers object horizontally with animation.
Expand All @@ -15,7 +18,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @param {Function} [callbacks.onChange] Invoked on every step of animation
* @return {fabric.AnimationContext} context
*/
fxCenterObjectH: function (object, callbacks) {
fxCenterObjectH(object, callbacks) {
callbacks = callbacks || { };

var empty = function() { },
Expand All @@ -38,7 +41,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
onComplete();
}
});
},
}

/**
* Centers object vertically with animation.
Expand All @@ -48,7 +51,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @param {Function} [callbacks.onChange] Invoked on every step of animation
* @return {fabric.AnimationContext} context
*/
fxCenterObjectV: function (object, callbacks) {
fxCenterObjectV(object, callbacks) {
callbacks = callbacks || { };

var empty = function() { },
Expand All @@ -71,7 +74,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
onComplete();
}
});
},
}

/**
* Same as `fabric.Canvas#remove` but animated
Expand All @@ -81,7 +84,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @param {Function} [callbacks.onChange] Invoked on every step of animation
* @return {fabric.AnimationContext} context
*/
fxRemove: function (object, callbacks) {
fxRemove(object, callbacks) {
callbacks = callbacks || { };

var empty = function() { },
Expand All @@ -105,9 +108,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
}
});
}
});
}
}

fabric.StaticCanvas = StaticCanvasAnimationMixinGenerator(fabric.StaticCanvas);


fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prototype */ {

export function ObjectAnimationMixinGenerator(Klass) {
return class ObjectAnimationMixin extends Klass {
/**
* Animates object's properties
* @param {String|Object} property Property to animate (if string) or properties to animate (if object)
Expand All @@ -127,7 +136,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* object.animate('left', { duration: ... });
*
*/
animate: function () {
animate() {
if (arguments[0] && typeof arguments[0] === 'object') {
var propsToAnimate = [], prop, skipCallbacks, out = [];
for (prop in arguments[0]) {
Expand All @@ -143,7 +152,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
else {
return this._animate.apply(this, arguments);
}
},
}

/**
* @private
Expand All @@ -152,7 +161,7 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @param {Object} [options] Options object
* @param {Boolean} [skipCallbacks] When true, callbacks like onchange and oncomplete are not invoked
*/
_animate: function(property, to, options, skipCallbacks) {
_animate(property, to, options, skipCallbacks) {
var _this = this, propPair;

to = to.toString();
Expand Down Expand Up @@ -223,4 +232,8 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
return fabric.util.animate(_options);
}
}
});
}
}

fabric.Object = ObjectAnimationMixinGenerator(fabric.Object);

Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.StaticCanvas.prototype */ {
//@ts-nocheck

export function StaticCanvasSerializationMixinGenerator(Klass) {
return class StaticCanvasSerializationMixin extends Klass {
/**
* Populates canvas with data from the specified JSON.
* JSON format must conform to the one of {@link fabric.Canvas#toJSON}
Expand All @@ -19,7 +22,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* ... canvas is restored, add your code.
* });
*/
loadFromJSON: function (json, reviver) {
loadFromJSON(json, reviver) {
if (!json) {
return;
}
Expand Down Expand Up @@ -50,15 +53,15 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
return _this;
});
});
},
}

/**
* @private
* @param {Object} serialized Object with background and overlay information
* @param {Array} enlivenedObjects canvas objects
* @param {boolean} renderOnAddRemove renderOnAddRemove setting for the canvas
*/
__setupCanvas: function(serialized, enlivenedObjects, renderOnAddRemove) {
__setupCanvas(serialized, enlivenedObjects, renderOnAddRemove) {
var _this = this;
enlivenedObjects.forEach(function(obj, index) {
// we splice the array just in case some custom classes restored from JSON
Expand All @@ -77,27 +80,27 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
// create the Object instance. Here the Canvas is
// already an instance and we are just loading things over it
this._setOptions(serialized);
},
}

/**
* Clones canvas instance
* @param {Array} [properties] Array of properties to include in the cloned canvas and children
* @returns {Promise<fabric.Canvas>}
*/
clone: function (properties) {
clone(properties) {
var data = JSON.stringify(this.toJSON(properties));
return this.cloneWithoutData().then(function(clone) {
return clone.loadFromJSON(data);
});
},
}

/**
* Clones canvas instance without cloning existing data.
* This essentially copies canvas dimensions, clipping properties, etc.
* but leaves data empty (so that you can populate it with your own)
* @returns {Promise<fabric.Canvas>}
*/
cloneWithoutData: function() {
cloneWithoutData() {
var el = fabric.util.createCanvasElement();

el.width = this.width;
Expand All @@ -113,4 +116,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
}
return clone.loadFromJSON(data);
}
});
}
}

fabric.StaticCanvas = StaticCanvasSerializationMixinGenerator(fabric.StaticCanvas);

Loading

0 comments on commit 0b6da98

Please sign in to comment.