layout-mode.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * Isotope LayoutMode
  3. */
  4. ( function( window, factory ) {
  5. // universal module definition
  6. /* jshint strict: false */ /*globals define, module, require */
  7. if ( typeof define == 'function' && define.amd ) {
  8. // AMD
  9. define( [
  10. 'get-size/get-size',
  11. 'outlayer/outlayer'
  12. ],
  13. factory );
  14. } else if ( typeof module == 'object' && module.exports ) {
  15. // CommonJS
  16. module.exports = factory(
  17. require('get-size'),
  18. require('outlayer')
  19. );
  20. } else {
  21. // browser global
  22. window.Isotope = window.Isotope || {};
  23. window.Isotope.LayoutMode = factory(
  24. window.getSize,
  25. window.Outlayer
  26. );
  27. }
  28. }( window, function factory( getSize, Outlayer ) {
  29. 'use strict';
  30. // layout mode class
  31. function LayoutMode( isotope ) {
  32. this.isotope = isotope;
  33. // link properties
  34. if ( isotope ) {
  35. this.options = isotope.options[ this.namespace ];
  36. this.element = isotope.element;
  37. this.items = isotope.filteredItems;
  38. this.size = isotope.size;
  39. }
  40. }
  41. var proto = LayoutMode.prototype;
  42. /**
  43. * some methods should just defer to default Outlayer method
  44. * and reference the Isotope instance as `this`
  45. **/
  46. var facadeMethods = [
  47. '_resetLayout',
  48. '_getItemLayoutPosition',
  49. '_manageStamp',
  50. '_getContainerSize',
  51. '_getElementOffset',
  52. 'needsResizeLayout',
  53. '_getOption'
  54. ];
  55. facadeMethods.forEach( function( methodName ) {
  56. proto[ methodName ] = function() {
  57. return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
  58. };
  59. });
  60. // ----- ----- //
  61. // for horizontal layout modes, check vertical size
  62. proto.needsVerticalResizeLayout = function() {
  63. // don't trigger if size did not change
  64. var size = getSize( this.isotope.element );
  65. // check that this.size and size are there
  66. // IE8 triggers resize on body size change, so they might not be
  67. var hasSizes = this.isotope.size && size;
  68. return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
  69. };
  70. // ----- measurements ----- //
  71. proto._getMeasurement = function() {
  72. this.isotope._getMeasurement.apply( this, arguments );
  73. };
  74. proto.getColumnWidth = function() {
  75. this.getSegmentSize( 'column', 'Width' );
  76. };
  77. proto.getRowHeight = function() {
  78. this.getSegmentSize( 'row', 'Height' );
  79. };
  80. /**
  81. * get columnWidth or rowHeight
  82. * segment: 'column' or 'row'
  83. * size 'Width' or 'Height'
  84. **/
  85. proto.getSegmentSize = function( segment, size ) {
  86. var segmentName = segment + size;
  87. var outerSize = 'outer' + size;
  88. // columnWidth / outerWidth // rowHeight / outerHeight
  89. this._getMeasurement( segmentName, outerSize );
  90. // got rowHeight or columnWidth, we can chill
  91. if ( this[ segmentName ] ) {
  92. return;
  93. }
  94. // fall back to item of first element
  95. var firstItemSize = this.getFirstItemSize();
  96. this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
  97. // or size of container
  98. this.isotope.size[ 'inner' + size ];
  99. };
  100. proto.getFirstItemSize = function() {
  101. var firstItem = this.isotope.filteredItems[0];
  102. return firstItem && firstItem.element && getSize( firstItem.element );
  103. };
  104. // ----- methods that should reference isotope ----- //
  105. proto.layout = function() {
  106. this.isotope.layout.apply( this.isotope, arguments );
  107. };
  108. proto.getSize = function() {
  109. this.isotope.getSize();
  110. this.size = this.isotope.size;
  111. };
  112. // -------------------------- create -------------------------- //
  113. LayoutMode.modes = {};
  114. LayoutMode.create = function( namespace, options ) {
  115. function Mode() {
  116. LayoutMode.apply( this, arguments );
  117. }
  118. Mode.prototype = Object.create( proto );
  119. Mode.prototype.constructor = Mode;
  120. // default options
  121. if ( options ) {
  122. Mode.options = options;
  123. }
  124. Mode.prototype.namespace = namespace;
  125. // register in Isotope
  126. LayoutMode.modes[ namespace ] = Mode;
  127. return Mode;
  128. };
  129. return LayoutMode;
  130. }));