You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

162 lines
3.8 KiB

  1. import $ from 'jquery';
  2. class Masonry {
  3. constructor(row, buttonText, sizes, buttonColor = 'primary') {
  4. this.section = row.addClass('initiated');
  5. this.sizes = sizes;
  6. this.items = [];
  7. this.visibleItems = [];
  8. this.batchSize = 0;
  9. this.btn = $('<button class="btn btn-regular icon-right icon-laden ' + buttonColor + '" />').text(buttonText);
  10. row.children().each((i, element) => {
  11. this.items.push($(element).remove());
  12. })
  13. row.after($('<div class="button-wrapper" />').append(this.btn));
  14. this.btn.on('click', (e) => {
  15. e.preventDefault();
  16. this.addBatch();
  17. })
  18. this.buildCols();
  19. this.addBatch();
  20. this.handleResize();
  21. }
  22. addBatch() {
  23. const newItems = [];
  24. for (let i = 0; i < this.batchSize; i++) {
  25. if (this.items.length > 0) {
  26. if (this.items[0].attr('data-thumb')) {
  27. this.loadImage(this.items[0]);
  28. }
  29. this.items[0].find('img[data-src]').each((i, el) => {
  30. $(el).one('load', (e) => {
  31. $(e.currentTarget).addClass('loaded');
  32. }).attr('src', $(el).attr('data-src'))
  33. })
  34. this.visibleItems.push(this.items[0]);
  35. newItems.push(this.items[0].css({'opacity': 0, 'transform': 'scale(0.8)', 'transition': '0.4s ease ' + (0.07 * i) + 's'}));
  36. this.items.splice(0,1);
  37. }
  38. }
  39. if (this.items.length === 0) {
  40. this.btn.parent().hide();
  41. }
  42. this.addToCols(newItems);
  43. }
  44. loadImage(item) {
  45. const img = $('<img src="' + this.items[0].attr('data-thumb') + '" alt="" />').one('load', () => {
  46. setTimeout(() => {
  47. item.addClass('loaded');
  48. },200)
  49. })
  50. item.find('a').append(img);
  51. }
  52. handleResize() {
  53. this.width = this.section.outerWidth();
  54. this.timer = null;
  55. $(window).on('resize', () => {
  56. if (this.timer) {
  57. clearTimeout(this.timer);
  58. }
  59. setTimeout(() => {
  60. this.buildCols();
  61. },200);
  62. })
  63. }
  64. buildCols() {
  65. const w = this.section.width();
  66. let cols = 1;
  67. $.each(this.sizes, (i, size) => {
  68. if (w > size.minWidth) {
  69. cols = i + 1;
  70. this.batchSize = size.batchSize;
  71. }
  72. else {
  73. return false;
  74. }
  75. })
  76. if (this.cols && cols === this.cols.length) {
  77. return;
  78. }
  79. $.each(this.cols, (i, item) => {
  80. item.col.remove();
  81. })
  82. this.cols = [];
  83. this.section.attr('data-cols', cols);
  84. for (let i = 0; i < cols; i++) {
  85. const col = $('<div class="column" />').appendTo(this.section);
  86. this.cols.push({
  87. col: col,
  88. index: i,
  89. height: 0
  90. })
  91. }
  92. this.addToCols(this.visibleItems);
  93. }
  94. addToCols(items) {
  95. $.each(items, (i, element) => {
  96. const item = $(element);
  97. this.cols[0].col.append(item);
  98. this.cols[0].height = Math.round(item.position().top + item.outerHeight());
  99. this.cols.sort( this.compareCols );
  100. window.requestAnimationFrame(() => {
  101. item.css({'opacity': '1', 'transform': 'scale(1)'});
  102. })
  103. })
  104. }
  105. compareCols(a, b) {
  106. if (a.height < b.height) {
  107. return -1;
  108. }
  109. else if (a.height > b.height) {
  110. return 1;
  111. }
  112. else {
  113. if (a.index < b.index) {
  114. return -1;
  115. }
  116. if (a.index > b.index) {
  117. return 1;
  118. }
  119. }
  120. return 0;
  121. }
  122. }
  123. export default Masonry;
  124. $('body').on('ihk-init dynamic-component-loaded gfi-dynamic-init', function () {
  125. $('.teasers[data-type="masonry"] .row:not(.initiated)').each((i, el) => {
  126. const btnText = window.ihk.translations.loadMoreArticles;
  127. const selector = $(el);
  128. if (!selector.find('dynamic-content').length) {
  129. new Masonry(selector, btnText,[
  130. { minWidth: 0, batchSize: 2 },
  131. { minWidth: 567, batchSize: 3 },
  132. { minWidth: 1000, batchSize: 6 }
  133. ]);
  134. }
  135. });
  136. });