Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

removing the need for the Sylvester with some simple matrix calculati…

…ons inspired by mjs. Some tests indicated that the multiplication of matrices may be increased by 5x. http://blog.vlad1.com/2010/02/05/mjs-simple-vector-and-matrix-math-for-js/
  • Loading branch information...
commit 2c817183156a6c480e277da71097830a30549e85 1 parent 9423dda
@heygrady authored
Showing with 170 additions and 80 deletions.
  1. +170 −80 lib/jquery.transform.js
View
250 lib/jquery.transform.js
@@ -242,7 +242,7 @@
// handle origin separately
if (func == 'origin') {
this[func].apply(this, $.isArray(funcs[func]) ? funcs[func] : [funcs[func]]);
- } else if ($.inArray($.transform.funcs, func)) {
+ } else if ($.inArray(func, $.transform.funcs) > 0) {
values.push(this.createTransformFunc(func, funcs[func]));
}
}
@@ -664,6 +664,25 @@
///////////////////////////////////////////////////////
(function($, window, document, undefined) {
/**
+ * Convenience function, matches Sylvester creator
+ * @param Array elements
+ */
+ function $M2x2(elements) {
+ return new $.matrix.M2x2(
+ elements[0][0], elements[0][1],
+ elements[1][0], elements[1][1]
+ );
+ }
+
+ /**
+ * Convenience function, matches Sylvester
+ * @param Array elements
+ */
+ function $V2(elements) {
+ return new $.matrix.V2(elements[0], elements[1]);
+ }
+
+ /**
* Matrix object for creating matrices relevant for 2d Transformations
* @var Object
*/
@@ -697,14 +716,32 @@
},
/**
+ * A 2-value vector
+ * @param Number x
+ * @param Number y
+ * @constructor
+ */
+ V2: function(x, y){
+ this.elements = [x, y];
+ },
+
+ /**
+ * A 2x2 Matrix, useful for 2D-transformations without translations
+ * @param Number mn
+ * @constructor
+ */
+ M2x2: function(m11, m12, m21, m22) {
+ this.elements = [m11, m12, m21, m22];
+ },
+
+ /**
* Reflect (same as rotate(180))
* @returm Matrix
*/
reflect: function() {
- return $M([
- [-1, 0, 0],
- [ 0, -1, 0],
- [ 0, 0, 1]
+ return $M2x2([
+ [-1, 0],
+ [ 0, -1]
]);
},
@@ -713,10 +750,9 @@
* @returm Matrix
*/
reflectX: function() {
- return $M([
- [1, 0, 0],
- [0, -1, 0],
- [0, 0, 1]
+ return $M2x2([
+ [1, 0],
+ [0, -1]
]);
},
@@ -725,10 +761,9 @@
* @returm Matrix
*/
reflectXY: function() {
- return $M([
- [0, 1, 0],
- [1, 0, 0],
- [0, 0, 1]
+ return $M2x2([
+ [0, 1],
+ [1, 0]
]);
},
@@ -737,10 +772,9 @@
* @returm Matrix
*/
reflectY: function() {
- return $M([
- [-1, 0, 0],
- [ 0, 1, 0],
- [ 0, 0, 1]
+ return $M2x2([
+ [-1, 0],
+ [ 0, 1]
]);
},
@@ -760,10 +794,9 @@
c = -sintheta,
d = costheta;
- return $M([
- [a, c, 0],
- [b, d, 0],
- [0, 0, 1]
+ return $M2x2([
+ [a, c],
+ [b, d]
]);
},
@@ -777,10 +810,9 @@
scale: function (sx, sy) {
sx = sx || sx === 0 ? sx : 1;
sy = sy || sy === 0 ? sy : 1;
- return $M([
- [sx, 0, 0],
- [0, sy, 0],
- [0, 0, 1]
+ return $M2x2([
+ [sx, 0],
+ [0, sy]
]);
},
@@ -815,10 +847,9 @@
x = Math.tan(radX),
y = Math.tan(radY);
- return $M([
- [1, x, 0],
- [y, 1, 0],
- [0, 0, 1]
+ return $M2x2([
+ [1, x],
+ [y, 1]
]);
},
@@ -832,10 +863,9 @@
var rad = $.angle.degreeToRadian(deg),
x = Math.tan(rad);
- return $M([
- [1, x, 0],
- [0, 1, 0],
- [0, 0, 1]
+ return $M2x2([
+ [1, x],
+ [0, 1]
]);
},
@@ -850,10 +880,9 @@
var rad = $.angle.degreeToRadian(deg),
y = Math.tan(rad);
- return $M([
- [1, 0, 0],
- [y, 1, 0],
- [0, 0, 1]
+ return $M2x2([
+ [1, 0],
+ [y, 1]
]);
},
@@ -868,7 +897,8 @@
tx = tx ? tx : 0;
ty = ty ? ty : 0;
- return $M([
+ // TODO: this is no longer supported as a matrix
+ return $M2x2([
[1, 0, tx],
[0, 1, ty],
[0, 0, 1]
@@ -881,6 +911,7 @@
* @returm Matrix
*/
translateX: function (tx) {
+ // TODO: this is no longer supported as a matrix
return $.matrix.translate(tx);
},
@@ -890,6 +921,7 @@
* @returm Matrix
*/
translateY: function (ty) {
+ // TODO: this is no longer supported as a matrix
return $.matrix.translate(0, ty);
}
});
@@ -901,11 +933,11 @@
*/
coord: function(x, y) {
var matrix = this.matrix,
- coord = matrix.x($M([[x], [y], [1]]));
+ vector = matrix.x($V2([x, y]));
return {
- x: parseFloat(parseFloat(coord.e(1, 1)).toFixed(8)),
- y: parseFloat(parseFloat(coord.e(2, 1)).toFixed(8))
+ x: parseFloat(parseFloat(vector.e(1)).toFixed(8)),
+ y: parseFloat(parseFloat(vector.e(2)).toFixed(8))
};
},
@@ -1009,6 +1041,68 @@
};
}
};
+
+ $.matrix.M2x2.prototype = {
+ /**
+ * Multiply a 2x2 matrix by a similar matrix or a vector
+ * @param M2x2 | V2 matrix
+ * @return M2x2 | V2
+ */
+ x: function(matrix) {
+ var a = this.elements,
+ b = matrix.elements;
+
+ // b is actually a vector
+ if (b.length == 2) {
+ return new $.matrix.V2(
+ a[0] * b[0] + a[1] * b[1],
+ a[2] * b[0] + a[3] * b[1]
+ );
+ }
+
+ // b is a 2x2 matrix
+ else if (b.length == 4) {
+ return new $.matrix.M2x2(
+ a[0] * b[0] + a[1] * b[2],
+ a[0] * b[1] + a[1] * b[3],
+
+ a[2] * b[0] + a[3] * b[2],
+ a[2] * b[1] + a[3] * b[3]
+ );
+ }
+ return false; //We don't know how to handle any other types of operations
+ },
+
+ /**
+ * Return a specific element from the matrix
+ * @param Number row where 1 is the 0th row
+ * @param Number col where 1 is the 0th column
+ * @return Number
+ */
+ e: function(row, col) {
+ var i = 0;
+ if (row == 0 && col == 1) {
+ i = 1;
+ } else if (row == 1 && col == 0) {
+ i = 2;
+ } else if (row == 1 && col == 1) {
+ i = 3;
+ }
+
+ return this.elements[i];
+ }
+ };
+
+ $.matrix.V2.prototype = {
+ /**
+ * Return a specific element from the vector
+ * @param Number i where 1 is the 0th value
+ * @return Number
+ */
+ e: function(i) {
+ return this.elements[i - 1];
+ }
+ };
})(jQuery, this, this.document);
///////////////////////////////////////////////////////
@@ -1045,39 +1139,37 @@
var $elem = this;
jQuery.each( prop, function( name, val ) {
// Clean up the numbers for space-sperated prop values
- for (var i = 0, len = $.transform.funcs.length; i < len; i++) {
- if (name == $.transform.funcs[i]) {
- var parts = rfxnum.exec(val);
- if (parts) {
- var end = parseFloat( parts[2] ),
- unit = parts[3] || "px",
- values = [];
-
- // Remember the first value
- values.push({
- end: (parts[1] ? parts[1] : '') + end,
- unit: unit
- });
+ if ($.inArray(name, $.transform.funcs) > 0) {
+ var parts = rfxnum.exec(val);
+ if (parts) {
+ var end = parseFloat( parts[2] ),
+ unit = parts[3] || "px",
+ values = [];
- // Detect additional values hidden in the unit
- var j = 0;
- while (parts = rfxmultinum.exec(unit)) {
- // Fix the previous unit
- values[j].unit = parts[1];
-
- // Remember this value
- values.push({
- end: (parts[2] ? parts[2] : '') + parseFloat(parts[3]),
- unit: parts[4]
- });
- unit = parts[4];
- j++;
- }
+ // Remember the first value
+ values.push({
+ end: (parts[1] ? parts[1] : '') + end,
+ unit: unit
+ });
+
+ // Detect additional values hidden in the unit
+ var i = 0;
+ while (parts = rfxmultinum.exec(unit)) {
+ // Fix the previous unit
+ values[i].unit = parts[1];
- // Save the values and truncate the value to make it safe to animate
- $elem.each(function(){this['data-animate-' + name] = values;});
- prop[name] = values[0].end;
+ // Remember this value
+ values.push({
+ end: (parts[2] ? parts[2] : '') + parseFloat(parts[3]),
+ unit: parts[4]
+ });
+ unit = parts[4];
+ i++;
}
+
+ // Save the values and truncate the value to make it safe to animate
+ $elem.each(function(){this['data-animate-' + name] = values;});
+ prop[name] = values[0].end;
}
}
});
@@ -1098,16 +1190,14 @@
// and it's extremely easy to poison the element.style
// with a random property and ruin all of the fun. So, it's
// easier to just look it up ourselves.
- for (var i = 0, len = $.transform.funcs.length; i < len; i++) {
- if (this.prop == $.transform.funcs[i]) {
- this.transform = this.transform || new $.transform(this.elem);
-
- // return a single unitless number and animation will play nice
- var parts = rfxnum.exec(this.transform.getAttr(this.prop));
- return parseFloat(parts[2]) || 0;
- }
+ if ($.inArray(this.prop, $.transform.funcs) > 0) {
+ this.transform = this.transform || new $.transform(this.elem);
+
+ // return a single unitless number and animation will play nice
+ var parts = rfxnum.exec(this.transform.getAttr(this.prop));
+ return parseFloat(parts[2]) || 0;
}
- return _cur.apply(this, arguments);
+ return _cur.apply(this, arguments);
};
/**
Please sign in to comment.
Something went wrong with that request. Please try again.