API Docs for: 3.10.3
Show:

File: matrix/js/Matrix.js

  1. /**
  2. * Matrix is a class that allows for the manipulation of a transform matrix.
  3. * This class is a work in progress.
  4. *
  5. * @class Matrix
  6. * @constructor
  7. * @module matrix
  8. */
  9. var Matrix = function(config) {
  10. this.init(config);
  11. };
  12.  
  13. Matrix.prototype = {
  14. /**
  15. * Used as value for the _rounding method.
  16. *
  17. * @property _rounder
  18. * @private
  19. */
  20. _rounder: 100000,
  21.  
  22. /**
  23. * Updates the matrix.
  24. *
  25. * @method multiple
  26. * @param {Number} a
  27. * @param {Number} b
  28. * @param {Number} c
  29. * @param {Number} d
  30. * @param {Number} dx
  31. * @param {Number} dy
  32. */
  33. multiply: function(a, b, c, d, dx, dy) {
  34. var matrix = this,
  35. matrix_a = matrix.a * a + matrix.c * b,
  36. matrix_b = matrix.b * a + matrix.d * b,
  37. matrix_c = matrix.a * c + matrix.c * d,
  38. matrix_d = matrix.b * c + matrix.d * d,
  39. matrix_dx = matrix.a * dx + matrix.c * dy + matrix.dx,
  40. matrix_dy = matrix.b * dx + matrix.d * dy + matrix.dy;
  41.  
  42. matrix.a = this._round(matrix_a);
  43. matrix.b = this._round(matrix_b);
  44. matrix.c = this._round(matrix_c);
  45. matrix.d = this._round(matrix_d);
  46. matrix.dx = this._round(matrix_dx);
  47. matrix.dy = this._round(matrix_dy);
  48. return this;
  49. },
  50.  
  51. /**
  52. * Parses a string and updates the matrix.
  53. *
  54. * @method applyCSSText
  55. * @param {String} val A css transform string
  56. */
  57. applyCSSText: function(val) {
  58. var re = /\s*([a-z]*)\(([\w,\.,\-,\s]*)\)/gi,
  59. args,
  60. m;
  61.  
  62. val = val.replace(/matrix/g, "multiply");
  63. while ((m = re.exec(val))) {
  64. if (typeof this[m[1]] === 'function') {
  65. args = m[2].split(',');
  66. this[m[1]].apply(this, args);
  67. }
  68. }
  69. },
  70.  
  71. /**
  72. * Parses a string and returns an array of transform arrays.
  73. *
  74. * @method getTransformArray
  75. * @param {String} val A css transform string
  76. * @return Array
  77. */
  78. getTransformArray: function(val) {
  79. var re = /\s*([a-z]*)\(([\w,\.,\-,\s]*)\)/gi,
  80. transforms = [],
  81. args,
  82. m;
  83.  
  84. val = val.replace(/matrix/g, "multiply");
  85. while ((m = re.exec(val))) {
  86. if (typeof this[m[1]] === 'function') {
  87. args = m[2].split(',');
  88. args.unshift(m[1]);
  89. transforms.push(args);
  90. }
  91. }
  92. return transforms;
  93. },
  94.  
  95. /**
  96. * Default values for the matrix
  97. *
  98. * @property _defaults
  99. * @private
  100. */
  101. _defaults: {
  102. a: 1,
  103. b: 0,
  104. c: 0,
  105. d: 1,
  106. dx: 0,
  107. dy: 0
  108. },
  109.  
  110. /**
  111. * Rounds values
  112. *
  113. * @method _round
  114. * @private
  115. */
  116. _round: function(val) {
  117. val = Math.round(val * this._rounder) / this._rounder;
  118. return val;
  119. },
  120.  
  121. /**
  122. * Initializes a matrix.
  123. *
  124. * @method init
  125. * @param {Object} config Specified key value pairs for matrix properties. If a property is not explicitly defined in the config argument,
  126. * the default value will be used.
  127. */
  128. init: function(config) {
  129. var defaults = this._defaults,
  130. prop;
  131.  
  132. config = config || {};
  133.  
  134. for (prop in defaults) {
  135. if(defaults.hasOwnProperty(prop))
  136. {
  137. this[prop] = (prop in config) ? config[prop] : defaults[prop];
  138. }
  139. }
  140.  
  141. this._config = config;
  142. },
  143.  
  144. /**
  145. * Applies a scale transform
  146. *
  147. * @method scale
  148. * @param {Number} val
  149. */
  150. scale: function(x, y) {
  151. this.multiply(x, 0, 0, y, 0, 0);
  152. return this;
  153. },
  154.  
  155. /**
  156. * Applies a skew transformation.
  157. *
  158. * @method skew
  159. * @param {Number} x The value to skew on the x-axis.
  160. * @param {Number} y The value to skew on the y-axis.
  161. */
  162. skew: function(x, y) {
  163. x = x || 0;
  164. y = y || 0;
  165.  
  166. if (x !== undefined) { // null or undef
  167. x = Math.tan(this.angle2rad(x));
  168.  
  169. }
  170.  
  171. if (y !== undefined) { // null or undef
  172. y = Math.tan(this.angle2rad(y));
  173. }
  174.  
  175. this.multiply(1, y, x, 1, 0, 0);
  176. return this;
  177. },
  178.  
  179. /**
  180. * Applies a skew to the x-coordinate
  181. *
  182. * @method skewX
  183. * @param {Number} x x-coordinate
  184. */
  185. skewX: function(x) {
  186. this.skew(x);
  187. return this;
  188. },
  189.  
  190. /**
  191. * Applies a skew to the y-coordinate
  192. *
  193. * @method skewY
  194. * @param {Number} y y-coordinate
  195. */
  196. skewY: function(y) {
  197. this.skew(null, y);
  198. return this;
  199. },
  200.  
  201. /**
  202. * Returns a string of text that can be used to populate a the css transform property of an element.
  203. *
  204. * @method toCSSText
  205. * @return String
  206. */
  207. toCSSText: function() {
  208. var matrix = this,
  209. text = 'matrix(' +
  210. matrix.a + ',' +
  211. matrix.b + ',' +
  212. matrix.c + ',' +
  213. matrix.d + ',' +
  214. matrix.dx + ',' +
  215. matrix.dy + ')';
  216. return text;
  217. },
  218.  
  219. /**
  220. * Returns a string that can be used to populate the css filter property of an element.
  221. *
  222. * @method toFilterText
  223. * @return String
  224. */
  225. toFilterText: function() {
  226. var matrix = this,
  227. text = 'progid:DXImageTransform.Microsoft.Matrix(';
  228. text += 'M11=' + matrix.a + ',' +
  229. 'M21=' + matrix.b + ',' +
  230. 'M12=' + matrix.c + ',' +
  231. 'M22=' + matrix.d + ',' +
  232. 'sizingMethod="auto expand")';
  233.  
  234. text += '';
  235.  
  236. return text;
  237. },
  238.  
  239. /**
  240. * Converts a radian value to a degree.
  241. *
  242. * @method rad2deg
  243. * @param {Number} rad Radian value to be converted.
  244. * @return Number
  245. */
  246. rad2deg: function(rad) {
  247. var deg = rad * (180 / Math.PI);
  248. return deg;
  249. },
  250.  
  251. /**
  252. * Converts a degree value to a radian.
  253. *
  254. * @method deg2rad
  255. * @param {Number} deg Degree value to be converted to radian.
  256. * @return Number
  257. */
  258. deg2rad: function(deg) {
  259. var rad = deg * (Math.PI / 180);
  260. return rad;
  261. },
  262.  
  263. angle2rad: function(val) {
  264. if (typeof val === 'string' && val.indexOf('rad') > -1) {
  265. val = parseFloat(val);
  266. } else { // default to deg
  267. val = this.deg2rad(parseFloat(val));
  268. }
  269.  
  270. return val;
  271. },
  272.  
  273. /**
  274. * Applies a rotate transform.
  275. *
  276. * @method rotate
  277. * @param {Number} deg The degree of the rotation.
  278. */
  279. rotate: function(deg, x, y) {
  280. var rad = this.angle2rad(deg),
  281. sin = Math.sin(rad),
  282. cos = Math.cos(rad);
  283. this.multiply(cos, sin, 0 - sin, cos, 0, 0);
  284. return this;
  285. },
  286.  
  287. /**
  288. * Applies translate transformation.
  289. *
  290. * @method translate
  291. * @param {Number} x The value to transate on the x-axis.
  292. * @param {Number} y The value to translate on the y-axis.
  293. */
  294. translate: function(x, y) {
  295. x = parseFloat(x) || 0;
  296. y = parseFloat(y) || 0;
  297. this.multiply(1, 0, 0, 1, x, y);
  298. return this;
  299. },
  300.  
  301. /**
  302. * Applies a translate to the x-coordinate
  303. *
  304. * @method translateX
  305. * @param {Number} x x-coordinate
  306. */
  307. translateX: function(x) {
  308. this.translate(x);
  309. return this;
  310. },
  311.  
  312. /**
  313. * Applies a translate to the y-coordinate
  314. *
  315. * @method translateY
  316. * @param {Number} y y-coordinate
  317. */
  318. translateY: function(y) {
  319. this.translate(null, y);
  320. return this;
  321. },
  322.  
  323.  
  324. /**
  325. * Returns an identity matrix.
  326. *
  327. * @method identity
  328. * @return Object
  329. */
  330. identity: function() {
  331. var config = this._config,
  332. defaults = this._defaults,
  333. prop;
  334.  
  335. for (prop in config) {
  336. if (prop in defaults) {
  337. this[prop] = defaults[prop];
  338. }
  339. }
  340. return this;
  341. },
  342.  
  343. /**
  344. * Returns a 3x3 Matrix array
  345. *
  346. * / \
  347. * | matrix[0][0] matrix[1][0] matrix[2][0] |
  348. * | matrix[0][1] matrix[1][1] matrix[2][1] |
  349. * | matrix[0][2] matrix[1][2] matrix[2][2] |
  350. * \ /
  351. *
  352. * @method getMatrixArray
  353. * @return Array
  354. */
  355. getMatrixArray: function()
  356. {
  357. var matrix = this,
  358. matrixArray = [
  359. [matrix.a, matrix.c, matrix.dx],
  360. [matrix.b, matrix.d, matrix.dy],
  361. [0, 0, 1]
  362. ];
  363. return matrixArray;
  364. },
  365.  
  366. /**
  367. * Returns the left, top, right and bottom coordinates for a transformed
  368. * item.
  369. *
  370. * @method getContentRect
  371. * @param {Number} width The width of the item.
  372. * @param {Number} height The height of the item.
  373. * @param {Number} x The x-coordinate of the item.
  374. * @param {Number} y The y-coordinate of the item.
  375. * @return Object
  376. */
  377. getContentRect: function(width, height, x, y)
  378. {
  379. var left = !isNaN(x) ? x : 0,
  380. top = !isNaN(y) ? y : 0,
  381. right = left + width,
  382. bottom = top + height,
  383. matrix = this,
  384. a = matrix.a,
  385. b = matrix.b,
  386. c = matrix.c,
  387. d = matrix.d,
  388. dx = matrix.dx,
  389. dy = matrix.dy,
  390. x1 = (a * left + c * top + dx),
  391. y1 = (b * left + d * top + dy),
  392. //[x2, y2]
  393. x2 = (a * right + c * top + dx),
  394. y2 = (b * right + d * top + dy),
  395. //[x3, y3]
  396. x3 = (a * left + c * bottom + dx),
  397. y3 = (b * left + d * bottom + dy),
  398. //[x4, y4]
  399. x4 = (a * right + c * bottom + dx),
  400. y4 = (b * right + d * bottom + dy);
  401. return {
  402. left: Math.min(x3, Math.min(x1, Math.min(x2, x4))),
  403. right: Math.max(x3, Math.max(x1, Math.max(x2, x4))),
  404. top: Math.min(y2, Math.min(y4, Math.min(y3, y1))),
  405. bottom: Math.max(y2, Math.max(y4, Math.max(y3, y1)))
  406. };
  407. },
  408.  
  409. /**
  410. * Returns the determinant of the matrix.
  411. *
  412. * @method getDeterminant
  413. * @return Number
  414. */
  415. getDeterminant: function()
  416. {
  417. return Y.MatrixUtil.getDeterminant(this.getMatrixArray());
  418. },
  419.  
  420. /**
  421. * Returns the inverse (in array form) of the matrix.
  422. *
  423. * @method inverse
  424. * @return Array
  425. */
  426. inverse: function()
  427. {
  428. return Y.MatrixUtil.inverse(this.getMatrixArray());
  429. },
  430.  
  431. /**
  432. * Returns the transpose of the matrix
  433. *
  434. * @method transpose
  435. * @return Array
  436. */
  437. transpose: function()
  438. {
  439. return Y.MatrixUtil.transpose(this.getMatrixArray());
  440. },
  441.  
  442. /**
  443. * Returns an array of transform commands that represent the matrix.
  444. *
  445. * @method decompose
  446. * @return Array
  447. */
  448. decompose: function()
  449. {
  450. return Y.MatrixUtil.decompose(this.getMatrixArray());
  451. }
  452. };
  453.  
  454. Y.Matrix = Matrix;
  455.