lundi 5 mars 2018

Trying to create a tile/masonry based landing page

I am trying to create a 100% width by 100% height website landing page that has a bunch of tiles of different sizes all stacked together to fill up the entire available viewport. Like puzzle pieces put together.

I achieved this by using packery.js by metafizzy. Example below:

Using Packery.js on Chrome: https://imgur.com/a/wvVxr

Above is the design I want. The problem is that this displays perfectly on chrome but not on other browsers due to pixel rounding.

packery.js Safari: https://imgur.com/a/QJFO4

As you can see on safari the boxes get re-aligned due to pixel rounding and they no longer fit as desired.

Things I have tried: I have tried to use vh for height and % for width that adds up to 100% of the available viewport dimension, chrome behaves as desired in most viewport sizes but not all and safari just doesn't work at all as you can see in the attached image.

The issue happens due to height attribute as resizing just the width the responsiveness of packery works perfectly. But when I try to resize the height of the browser window, the grid-items get dislocated and unaligned. I tried to use verge to calculate the total viewport height available and then destroy and re-initialize packery with fixed pixels after the resize event to resolve the issue, but it didn't work as intended.

Summary of things I have tried: - Use vh for grid-item height - Calculate total pixels in viewport height and then dynamically assign fixed pixels to each grid-item based on their size and re-init packery.

Below is the code with the utilization of verge, dynamically assigning grid-item height and packery destroy and re-init upon resize.

    <script>
  var packeryOptions = {
    itemSelector: '.grid-item',
    percentPosition: true

  };

  getVergeHeight();

  var $grid = $('.grid').packery( packeryOptions );   // initialize Packery


  function getVergeHeight() {
   viewportHeight = verge.viewportH() // Get the viewport height in pixels.

    var height1 = (10 / 100) * viewportHeight;
    var height2 = (20 / 100) * viewportHeight;
    var height3 = (30 / 100) * viewportHeight;
    var height4 = (40 / 100) * viewportHeight;
    var height5 = (50 / 100) * viewportHeight;
    var height6 = (60 / 100) * viewportHeight;
    var height7 = (70 / 100) * viewportHeight;
    setGridItemHeight();

    function setGridItemHeight() {
      $('.grid-item').height(height1);
      $('.grid-item--height2').height(height2);
      $('.grid-item--height3').height(height3);
      $('.grid-item--height4').height(height4);
      $('.grid-item--height5').height(height5);
      $('.grid-item--height6').height(height6);
      $('.grid-item--height7').height(height7);
      console.log('Grid-items height has been set')
    }
  }


  function destroyInitPackery() {
      $grid.packery('destroy'); // destroy Packery
      $grid.packery( packeryOptions ); // re-initialize Packery

  }

  var resizeId;
  $(window).resize(function() {
      clearTimeout(resizeId);
      resizeId = setTimeout(doneResizing, 200);
  });

  function doneResizing(){
    getVergeHeight();
    destroyInitPackery();
  }

I got in touch with packery creator to get some help and he proposed that packery might not be the solution for my use-case due to pixel rounding and different grid-item alignment on different browsers.

I need help with either using a different method to achieve masonry style tiles or use some other creative way to get around the pixel rounding issue to have a similar experience across different browsers.




Aucun commentaire:

Enregistrer un commentaire