/scripts/wookmark/js/jquery.wookmark.js

https://gitlab.com/ytaras/Modus · JavaScript · 177 lines · 113 code · 23 blank · 41 comment · 22 complexity · 45d927625e301fdb85a78d2a48f6f08a MD5 · raw file

  1. /*!
  2. jQuery Wookmark plugin 0.5
  3. @name jquery.wookmark.js
  4. @author Christoph Ono (chri@sto.ph or @gbks)
  5. @version 0.5
  6. @date 3/19/2012
  7. @category jQuery plugin
  8. @copyright (c) 2009-2012 Christoph Ono (www.wookmark.com)
  9. @license Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
  10. */
  11. $.fn.wookmark = function(options) {
  12. if(!this.wookmarkOptions) {
  13. this.wookmarkOptions = $.extend( {
  14. container: $('body'),
  15. offset: 2,
  16. autoResize: false,
  17. itemWidth: $(this[0]).outerWidth(),
  18. resizeDelay: 50
  19. }, options);
  20. } else if(options) {
  21. this.wookmarkOptions = $.extend(this.wookmarkOptions, options);
  22. }
  23. // Layout variables.
  24. if(!this.wookmarkColumns) {
  25. this.wookmarkColumns = null;
  26. this.wookmarkContainerWidth = null;
  27. }
  28. // Main layout function.
  29. this.wookmarkLayout = function() {
  30. // Calculate basic layout parameters.
  31. var columnWidth = this.wookmarkOptions.itemWidth + this.wookmarkOptions.offset;
  32. var containerWidth = this.wookmarkOptions.container.width();
  33. var columns = Math.floor((containerWidth+this.wookmarkOptions.offset)/columnWidth);
  34. var offset = 0//YSW Math.round((containerWidth - (columns*columnWidth-this.wookmarkOptions.offset))/2);
  35. // If container and column count hasn't changed, we can only update the columns.
  36. var bottom = 0;
  37. if(this.wookmarkColumns != null && this.wookmarkColumns.length == columns) {
  38. bottom = this.wookmarkLayoutColumns(columnWidth, offset);
  39. } else {
  40. bottom = this.wookmarkLayoutFull(columnWidth, columns, offset);
  41. }
  42. // Set container height to height of the grid.
  43. this.wookmarkOptions.container.css('height', bottom+'px');
  44. };
  45. /**
  46. * Perform a full layout update.
  47. */
  48. this.wookmarkLayoutFull = function(columnWidth, columns, offset) {
  49. // Prepare Array to store height of columns.
  50. var heights = [];
  51. while(heights.length < columns) {
  52. heights.push(0);
  53. }
  54. // Store column data.
  55. this.wookmarkColumns = [];
  56. while(this.wookmarkColumns.length < columns) {
  57. this.wookmarkColumns.push([]);
  58. }
  59. // Loop over items.
  60. var item, top, left, i=0, k=0, length=this.length, shortest=null, shortestIndex=null, bottom = 0;
  61. for(; i<length; i++ ) {
  62. item = $(this[i]);
  63. // Find the shortest column.
  64. shortest = null;
  65. shortestIndex = 0;
  66. for(k=0; k<columns; k++) {
  67. if(shortest == null || heights[k] < shortest) {
  68. shortest = heights[k];
  69. shortestIndex = k;
  70. }
  71. }
  72. // Postion the item.
  73. /*item.css({
  74. position: 'absolute',
  75. top: shortest + 'px',
  76. left: (shortestIndex * columnWidth + offset) + 'px'
  77. }); YSW*/
  78. item.css({
  79. position: 'absolute', top: shortest + 'px',
  80. left: (shortestIndex * columnWidth + offset) + 'px',
  81. opacity: 0
  82. });
  83. item.animate({ opacity: 1
  84. }, 500);
  85. // Update column height.
  86. heights[shortestIndex] = shortest + item.outerHeight() + this.wookmarkOptions.offset;
  87. bottom = Math.max(bottom, heights[shortestIndex]);
  88. this.wookmarkColumns[shortestIndex].push(item);
  89. }
  90. return bottom;
  91. };
  92. /**
  93. * This layout function only updates the vertical position of the
  94. * existing column assignments.
  95. */
  96. this.wookmarkLayoutColumns = function(columnWidth, offset) {
  97. var heights = [];
  98. while(heights.length < this.wookmarkColumns.length) {
  99. heights.push(0);
  100. }
  101. var i=0, length = this.wookmarkColumns.length, column;
  102. var k=0, kLength, item;
  103. var bottom = 0;
  104. for(; i<length; i++) {
  105. column = this.wookmarkColumns[i];
  106. kLength = column.length;
  107. for(k=0; k<kLength; k++) {
  108. item = column[k];
  109. item.css({
  110. left: (i*columnWidth + offset)+'px',
  111. top: heights[i]+'px'
  112. });
  113. heights[i] += item.outerHeight() + this.wookmarkOptions.offset;
  114. bottom = Math.max(bottom, heights[i]);
  115. }
  116. }
  117. return bottom;
  118. };
  119. // Listen to resize event if requested.
  120. this.wookmarkResizeTimer = null;
  121. if(!this.wookmarkResizeMethod) {
  122. this.wookmarkResizeMethod = null;
  123. }
  124. if(this.wookmarkOptions.autoResize) {
  125. // This timer ensures that layout is not continuously called as window is being dragged.
  126. this.wookmarkOnResize = function(event) {
  127. if(this.wookmarkResizeTimer) {
  128. clearTimeout(this.wookmarkResizeTimer);
  129. }
  130. this.wookmarkResizeTimer = setTimeout($.proxy(this.wookmarkLayout, this), this.wookmarkOptions.resizeDelay)
  131. };
  132. // Bind event listener.
  133. if(!this.wookmarkResizeMethod) {
  134. this.wookmarkResizeMethod = $.proxy(this.wookmarkOnResize, this);
  135. }
  136. $(window).resize(this.wookmarkResizeMethod);
  137. };
  138. /**
  139. * Clear event listeners and time outs.
  140. */
  141. this.wookmarkClear = function() {
  142. if(this.wookmarkResizeTimer) {
  143. clearTimeout(this.wookmarkResizeTimer);
  144. this.wookmarkResizeTimer = null;
  145. }
  146. if(this.wookmarkResizeMethod) {
  147. $(window).unbind('resize', this.wookmarkResizeMethod);
  148. }
  149. };
  150. // Apply layout
  151. this.wookmarkLayout();
  152. // Display items (if hidden).
  153. this.show();
  154. };