JAVASCRIPT   81

Waterfall.js

Guest on 24th August 2021 01:33:12 PM

  1. /*!
  2.    --------------------------------
  3.    Waterfall.js
  4.    --------------------------------
  5.    + https://github.com/raphamorim/waterfall
  6.    + version 1.0.0
  7.    + Copyright  Raphael Amorim
  8.    + Licensed under the MIT license
  9.    + Documentation: https://github.com/raphamorim/waterfall
  10. */
  11.  
  12. function waterfall(container){
  13.     if(typeof(container) === 'string')
  14.         container = document.querySelector(container);
  15.  
  16.     // Freeze the list of nodes
  17.     var els = [].map.call(container.children, function(el){
  18.         el.style.position = 'absolute';
  19.         return el;
  20.     });
  21.     container.style.position = 'relative';
  22.  
  23.     function margin(name, el){
  24.         var style = window.getComputedStyle(el);
  25.         return parseFloat(style['margin' + name]) || 0;
  26.     }
  27.     function px(n){ return n + 'px'; }
  28.     function y(el){ return parseFloat(el.style.top) ; }
  29.     function x(el){ return parseFloat(el.style.left); }
  30.     function width(el){ return el.clientWidth; }
  31.     function height(el){ return el.clientHeight; }
  32.     function bottom(el){ return y(el) + height(el) + margin('Bottom', el); }
  33.     function right(el){ return x(el) + width(el) + margin('Right', el); }
  34.  
  35.     function sort(l){
  36.         l = l.sort(function(a, b){
  37.             if(bottom(a) === bottom(b)){
  38.                 return x(b) - x(a);
  39.             }else{
  40.                 return bottom(b) - bottom(a);
  41.             }
  42.         });
  43.     }
  44.  
  45.     var boundary = [];
  46.  
  47.     // Deal with the first element.
  48.     if(els.length){
  49.         els[0].style.top = '0px';
  50.         els[0].style.left = px(margin('Left', els[0]));
  51.         boundary.push(els[0]);
  52.     }
  53.  
  54.     // Deal with the first line.
  55.     for(var i = 1; i < els.length; i++){
  56.         var prev = els[i - 1],
  57.         el = els[i],
  58.         thereIsSpace = right(prev) + width(el) <= width(container);
  59.         if(!thereIsSpace) break;
  60.             el.style.top = prev.style.top;
  61.         el.style.left = px(right(prev) + margin('Left', el));
  62.         boundary.push(el);
  63.     }
  64.  
  65.     // Place following elements at the bottom of the smallest column.
  66.     for(; i < els.length; i++){
  67.         sort(boundary);
  68.         var el = els[i],
  69.             minEl = boundary.pop();
  70.         el.style.top = px(bottom(minEl) + margin('Top', el));
  71.         el.style.left = px(x(minEl));
  72.         boundary.push(el);
  73.     }
  74.  
  75.     sort(boundary);
  76.     var maxEl = boundary[0];
  77.     container.style.height = px(bottom(maxEl) + margin('Bottom', maxEl));
  78.  
  79.     // Responds to window resize
  80.     var containerWidth = width(container);
  81.     function resize(e) {
  82.         if(width(container) != containerWidth){
  83.             e.target.removeEventListener(e.type, arguments.callee);
  84.             waterfall(container);
  85.         }
  86.     }
  87.  
  88.     if (window.addEventListener) {
  89.         window.addEventListener('resize', resize);
  90.     } else {
  91.         document.body.onresize = resize;
  92.     }
  93. }

Raw Paste


Login or Register to edit or fork this paste. It's free.