<section class="ef-sub-navigation">
    <div class="sub-navigation-tiles">
        <div class="sub-navigation-tiles__section">
            <a class="navigation-tile" href="/">
                <div class="navigation-tile__bg-image" style="background-image: url(/assets/example-content/tile-background-text.jpg);"></div>
                <div class="navigation-tile__title">Latest News</div>
            </a>
            <a class="navigation-tile" href="/">
                <div class="navigation-tile__bg-image" style="background-image: url(/assets/example-content/tile-background-text.jpg);"></div>
                <div class="navigation-tile__title">Match Highlights</div>
            </a>
            <a class="navigation-tile" href="/">
                <div class="navigation-tile__bg-image" style="background-image: url(/assets/example-content/tile-background-text.jpg);"></div>
                <div class="navigation-tile__title">Find Football</div>
            </a>
            <a class="navigation-tile" href="/">
                <div class="navigation-tile__bg-image" style="background-image: url(/assets/example-content/tile-background-text.jpg);"></div>
                <div class="navigation-tile__title">Grassroots Football</div>
            </a>
            <a class="navigation-tile" href="/">
                <div class="navigation-tile__bg-image-only" style="background-image: url(/assets/example-content/tile-background.jpg);"></div>
            </a>
        </div>
    </div>
</section>

No notes defined.

{
  "sub-navigation-title": false,
  "tiles": [
    {
      "title": "Latest News",
      "link": "/",
      "alttext": "Latest News"
    },
    {
      "title": "Match Highlights",
      "link": "/",
      "alttext": "Match Highlights"
    },
    {
      "title": "Find Football",
      "link": "/",
      "alttext": "Find Football"
    },
    {
      "title": "Grassroots Football",
      "link": "/",
      "alttext": "Grassroots Football"
    },
    {
      "without-text": "true",
      "link": "/",
      "alttext": "Football Image"
    }
  ]
}
  • Content:
    /** SCROLLING PARALLAX FUNCTIONALITY
     * Creates a horizontal parallax effect on image child elements
     * Takes the following options:
     * scrollContainer: the parent element that scrolls
     * items: the items that should should have a parallaxed image
     * minXPosition / maxX position: The distance which the image should be able to travel
     *
     * * */
    
    export default class HorizontalScrollParallax {
      constructor({
        scrollContainer,
        itemElements,
        maxXPosition = 20,
        minXPosition = -20,
      }) {
        this.maxXPosition = maxXPosition;
        this.minXPosition = minXPosition;
    
        this.scrollContainer = scrollContainer;
    
        this.items = Array.from(itemElements).map(item => {
          const img = item.querySelector('img');
    
          // Adding a hack to stop jumpiness from debouncing the animation
          // TODO: This could be replaced with something like VirtualScroll
          // https://github.com/ayamflow/virtual-scroll
          // TODO: This check for `img` is a stopgap to allow the JS to continue running if
          // an image is missing. But, this may require more thought about what to do with the
          // parallax when there are images missing.
          if (img) {
            img.style.transition = `transformx 0.1s`;
          }
    
          const { clientWidth, offsetLeft } = item;
          const bounds = item.getBoundingClientRect();
    
          // The positions at which the item should stop animating
          // We are going to calculate an x position based on how far it is between these walls
          const leftWall = bounds.left - window.innerWidth;
          const rightWall = bounds.right;
    
          return { bounds, clientWidth, offsetLeft, img, leftWall, rightWall };
        });
    
        this.parallaxRunning = false;
      }
    
      parallax() {
        const lastScrollPosition = this.scrollContainer.scrollLeft;
    
        window.requestAnimationFrame(() => {
          const itemsInView = this.items.filter(
            item =>
              lastScrollPosition + window.innerWidth >= item.bounds.left &&
              lastScrollPosition < item.bounds.right
          );
    
          itemsInView.forEach(({ leftWall, rightWall, img }) => {
            // Calculate how far the item is along the screen
            const percentage =
              ((lastScrollPosition - leftWall) * 100) / (rightWall - leftWall);
    
            // The distance which the image should be able to travel
    
            const x =
              (percentage / 100) * (this.minXPosition - this.maxXPosition) +
              this.maxXPosition;
    
            if (img) {
              // eslint-disable-next-line no-param-reassign
              img.style.transform = `translateX(${x}px) `;
            }
          });
        });
      }
    
      initParallax() {
        if (this.parallaxRunning) {
          return;
        }
    
        this.parallaxRunning = true;
        this.parallax();
    
        this.scrollContainer.addEventListener('scroll', () => this.parallax());
      }
    
      destroyParallaxScrolling() {
        if (!this.parallaxRunning) {
          return;
        }
    
        this.parallaxRunning = false;
        this.scrollContainer.removeEventListener('scroll', () => this.parallax());
    
        Array.from(this.items).forEach(item => {
          // eslint-disable-next-line no-param-reassign
          item.img.style.transform = `translateX(0)`;
        });
      }
    }
    
  • URL: /components/raw/sub-navigation-tiles/scrolling-parallax.js
  • Filesystem Path: src/library/modules/sub-navigation-tiles/scrolling-parallax.js
  • Size: 3.2 KB
  • Content:
    import debounce from 'lodash.debounce';
    
    import HorizontalScrollParallax from './scrolling-parallax';
    
    export default ({ parentElement, maxScreenWidth = 820 }) => {
      const tiles = parentElement.querySelectorAll('.navigation-tile');
    
      // Set up the parallex
      const tilesList = new HorizontalScrollParallax({
        scrollContainer: parentElement,
        itemElements: tiles,
      });
    
      if (parentElement.clientWidth < maxScreenWidth) {
        tilesList.initParallax();
      }
    
      // Create the parallax when smaller than the max screensize
      // Destroy any running parallax when the screen is bigger
      window.addEventListener(
        'resize',
        debounce(() => {
          if (parentElement.clientWidth >= maxScreenWidth) {
            tilesList.destroyParallaxScrolling();
            return;
          }
    
          tilesList.initParallax();
        }, 250)
      );
    };
    
  • URL: /components/raw/sub-navigation-tiles/sub-navigation-tiles.js
  • Filesystem Path: src/library/modules/sub-navigation-tiles/sub-navigation-tiles.js
  • Size: 829 Bytes
  • Content:
    .sub-navigation-tiles {
      overflow-x: auto;
      max-width: 100vw;
    
      &__section {
        column-gap: 2rem;
        display: flex;
        overflow-x: scroll;
        padding: 0 1.5rem 0.5rem 1.5rem;
    
        .navigation-tile {
          flex-shrink: 0;
        }
      }
    
      @media screen and (min-width: $mq-medium) {
        overflow-x: unset;
    
        &__section {
          display: flex;
          column-gap: 3.6rem;
          justify-content: center;
          overflow-x: unset;
          padding: 0;
    
          .navigation-tile {
            flex-shrink: initial;
          }
        }
      }
    }
    
    @media screen and (max-width: $mq-medium) {
      .ef-sub-navigation {
        display: inherit;
      }
    }
    
    .common-template__row-container,
    .common-template__news-container {
      @media screen and (max-width: $mq-medium) {
        .sub-navigation-tiles__section {
          padding: 0 0 0.5rem 0;
        }
      }
    }
    
  • URL: /components/raw/sub-navigation-tiles/sub-navigation-tiles.scss
  • Filesystem Path: src/library/modules/sub-navigation-tiles/sub-navigation-tiles.scss
  • Size: 858 Bytes
<section class="ef-sub-navigation">
  <div class="sub-navigation-tiles">
    {{#if sub-navigation-title}}
    {{render '@optional-title'}}
    {{/if}}
    <div class="sub-navigation-tiles__section">
      {{#each tiles}}
      {{render '@navigation-tiles' this merge="true"}}
      {{/each}}
    </div>
  </div>
</section>