Fractal Starter
Project version : 0.1.2

Block Product Image

<aside class="block-product-image js-productGallery">
    <div class="block-product-image__thumbnail js-mainPicture">
        <a href="https://source.unsplash.com/67TZmPNs9yM" class="inner-box" data-target-id="1">
         <img src="https://source.unsplash.com/67TZmPNs9yM" alt="" />
      </a>
    </div>

    <div class="block-product-image__navigation js-productGalleryLists">
        <button class="scrollLeft"></button>
        <button class="scrollTop"></button>

        <ul class="block-product-image__pictures lst__unstyled">
            <li>
                <a href="https://source.unsplash.com/67TZmPNs9yM" data-pics-id="1" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/67TZmPNs9yM" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/QfAX7_xjxm4" data-pics-id="2" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/QfAX7_xjxm4" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="3" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="4" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="5" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="6" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="7" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="8" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="9" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
            <li>
                <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="10" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
            </li>
        </ul>

        <button class="scrollRight"></button>
        <button class="scrollBottom"></button>
    </div>

</aside>
<aside class="block-product-image js-productGallery">
   <div class="block-product-image__thumbnail js-mainPicture">
      <a href="https://source.unsplash.com/67TZmPNs9yM" class="inner-box" data-target-id="1">
         <img src="https://source.unsplash.com/67TZmPNs9yM" alt="" />
      </a>
   </div>

   <div class="block-product-image__navigation js-productGalleryLists">
      <button class="scrollLeft"></button>
      <button class="scrollTop"></button>

      <ul class="block-product-image__pictures lst__unstyled">
         <li>
            <a href="https://source.unsplash.com/67TZmPNs9yM" data-pics-id="1" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/67TZmPNs9yM" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/QfAX7_xjxm4" data-pics-id="2" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/QfAX7_xjxm4" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="3" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="4" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="5" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="6" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="7" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="8" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="9" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
         <li>
            <a href="https://source.unsplash.com/UgNjyPkphtU" data-pics-id="10" data-fslightbox="blockProductImage">
               <img src="https://source.unsplash.com/UgNjyPkphtU" alt="" />
            </a>
         </li>
      </ul>

      <button class="scrollRight"></button>
      <button class="scrollBottom"></button>
   </div>
   
</aside>
/* No context defined for this component. */
  • Content:
    .block-product-image {
       @supports (display: grid) {
          display: flex;
          flex-direction: column;
    
          @include mediaWQuery($media-query-s) {
             flex-direction: row;
          }
       }
    
       &__thumbnail {
          flex: 1;
          
          .inner-box {
             display: block;
             position: relative;
             width: 100%;
             height: 0;
             padding-top: 100%;
    
             &::after, &::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                opacity: 0;
                transition: .3s;
             }
       
             &::before {
                z-index: 10;
                background: rgba(37,35,34,0.8);
             }
       
             &::after {
                background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg aria-hidden='true' data-prefix='far' data-icon='search' class='svg-inline--fa fa-search fa-w-16' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23fff' d='M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z'/%3E%3C/svg%3E");
                background-size: 18px 18px;
                background-position: center;
                background-repeat: no-repeat;
                transform: scale(0);
                z-index: 11;
             }
    
             &:hover, &:focus {
                &::after, &::before {
                   opacity: 1;
                }
       
                &::after {
                   transform: scale(1)
                }
             }
          }
    
          img {
             position: absolute;
             top: 0;
             left: 0;
             object-fit: contain;
             width: 100%;
             height: 100%;
          }
       }
    
       &__navigation {
          width: auto;
          position: relative;
          margin-top: 1rem;
    
          @include mediaWQuery($media-query-s) {
             width: 90px;
             height: auto;
             margin-left: 1rem;
             margin-top: 0;
          }
    
          > button {
             position: absolute;
             width: 30px;
             height: 100%;
             top: 0;
             border: 0;
             margin: 0;
             opacity: .7;
             background-color: $c-gold-medium;
             background-repeat: no-repeat;
             background-size: auto 20px;
             background-position: center;
             -webkit-appearance: none;
             transition: .3s ease;
             cursor: not-allowed;
    
             &.display-it {
                opacity: 1;
                cursor: pointer;
             }
    
             &.display-it:hover, &.display-it:focus {
                background-color: darken($c-gold-medium, 10%);
             }
    
             &.scrollTop, &.scrollBottom { display: none }
    
             &.scrollLeft {
                left: 0;
                background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg aria-hidden='true' data-prefix='far' data-icon='chevron-left' class='svg-inline--fa fa-chevron-left fa-w-8' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 512'%3E%3Cpath fill='%23fff' d='M231.3 473.9l19.8-19.8a12 12 0 000-17L70.4 256 251 74.9a12 12 0 000-17l-19.8-19.8a12 12 0 00-17 0L5 247.5a12 12 0 000 17l209.4 209.4a12 12 0 0017 0z'/%3E%3C/svg%3E");
             }
    
             &.scrollRight {
                right: 0;
                background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg aria-hidden='true' data-prefix='far' data-icon='chevron-right' class='svg-inline--fa fa-chevron-right fa-w-8' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 512'%3E%3Cpath fill='%23fff' d='M24.7 38.1L5 57.9a12 12 0 000 17L185.6 256 5 437.1a12 12 0 000 17l19.8 19.8a12 12 0 0017 0L251 264.5a12 12 0 000-17L41.7 38.1a12 12 0 00-17 0z'/%3E%3C/svg%3E");
             }
    
             @include mediaWQuery($media-query-s) {
                height: 40px;
                width: 100%;
                background-size: 15px auto;
    
                &.scrollLeft, &.scrollRight { display: none }
    
                &.scrollTop {
                   display: block;
                   top: 0;
                   background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg aria-hidden='true' data-prefix='far' data-icon='chevron-up' class='svg-inline--fa fa-chevron-up fa-w-14' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23FFF' d='M6.1 359.3L25.9 379a12 12 0 0017 0L224 198.4 405.1 379a12 12 0 0017 0l19.8-19.8a12 12 0 000-17L232.5 133a12 12 0 00-17 0L6.1 342.3a12 12 0 000 17z'/%3E%3C/svg%3E");
                }
       
                &.scrollBottom {
                   display: block;
                   top: initial;
                   bottom: 0;
                   background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg aria-hidden='true' data-prefix='far' data-icon='chevron-down' class='svg-inline--fa fa-chevron-down fa-w-14' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'%3E%3Cpath fill='%23FFF' d='M441.9 167.3l-19.8-19.8a12 12 0 00-17 0L224 328.2 42.9 147.5a12 12 0 00-17 0L6.1 167.3a12 12 0 000 17l209.4 209.4a12 12 0 0017 0l209.4-209.4a12 12 0 000-17z'/%3E%3C/svg%3E");
                }
             }
          }
    
          > ul {
             height: auto;
             display: flex;
             margin: 0 30px;
             overflow-x: auto;
       
             @include mediaWQuery($media-query-s) {
                position: absolute;
                display: block;
                margin: 0;
                top: 50px;
                bottom: 40px;
                left: 0;
                width: 100%;
                height: auto;
                margin: 0;
                overflow-x: hidden;
                overflow-y: auto;
             }
          }
          
          > ul > li {
             display: inline-block;
             flex-basis: 33%;
             width: 100%;
             margin: 0 .25rem;
             flex-shrink: 0;
       
             @include mediaWQuery($media-query-s) {
                display: block;
                max-width: 100%;
                margin: 0;
    
                &:last-child a { margin-bottom: 0!important }
             }
          }
       
          > ul > li > a {
             position: relative;
             display: block;
             height: 0;
             padding-top: 100%;
             overflow: hidden;
       
             @include mediaWQuery($media-query-s) {
                width: 90px;
                height: 90px;
                padding-top: 0;
                margin: 0;
                margin-bottom: 1rem;
             }
       
             &::after, &::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                opacity: 0;
                transition: .3s;
             }
       
             &::before {
                z-index: 10;
                background: rgba(37,35,34,0.8);
             }
       
             &::after {
                background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg aria-hidden='true' data-prefix='far' data-icon='search' class='svg-inline--fa fa-search fa-w-16' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23fff' d='M508.5 468.9L387.1 347.5c-2.3-2.3-5.3-3.5-8.5-3.5h-13.2c31.5-36.5 50.6-84 50.6-136C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c52 0 99.5-19.1 136-50.6v13.2c0 3.2 1.3 6.2 3.5 8.5l121.4 121.4c4.7 4.7 12.3 4.7 17 0l22.6-22.6c4.7-4.7 4.7-12.3 0-17zM208 368c-88.4 0-160-71.6-160-160S119.6 48 208 48s160 71.6 160 160-71.6 160-160 160z'/%3E%3C/svg%3E");
                background-size: 18px 18px;
                background-position: center;
                background-repeat: no-repeat;
                transform: scale(0);
                z-index: 11;
             }
       
             &:hover, &:focus {
                &::after, &::before {
                   opacity: 1;
                }
       
                &::after {
                   transform: scale(1)
                }
             }
          }
       
          > ul > li > a > img {
             position: absolute;
             width: 100%;
             height: 100%;
             object-fit: cover;
             top: 0;
          }
       }
    }
  • URL: /components/raw/block-product-image/block-product-image.scss
  • Filesystem Path: components/06-components/02-blocks/07-block-product-image/block-product-image.scss
  • Size: 7.9 KB
  • Content:
    const getWidthElement = element => {
       let style = element.currentStyle || window.getComputedStyle(element),
                   width = element.offsetWidth, // or use style.width
                   margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight),
                   padding = parseFloat(style.paddingLeft) + parseFloat(style.paddingRight),
                   border = parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);
    
       return (width + margin + padding + border)
    }
    
    const getHeightElement = element => {
       let style = element.currentStyle || window.getComputedStyle(element),
                   height = element.offsetHeight, // or use style.width
                   margin = parseFloat(style.marginTop) + parseFloat(style.marginBottom),
                   padding = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom),
                   border = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);
    
       return (height + margin + padding + border)
    }
    
    
    
    /********
    GALLERY
    *********/
    class oProductGallery {
       constructor(parent) {
          this.parent = parent || false;
          this.mainPicture = parent ? parent.querySelector('.js-mainPicture > a') : false;
          this.picturesSlider = parent ? parent.querySelector('.js-productGalleryLists > ul') : false;
          this.allPictures = parent ? parent.querySelectorAll('.js-productGalleryLists > ul > li > a') : false;
          this.sliderLeft = parent ? parent.querySelector('.js-productGalleryLists > .scrollRight') : false;
          this.sliderRight = parent ? parent.querySelector('.js-productGalleryLists > .scrollLeft') : false;
          this.sliderTop = parent ? parent.querySelector('.js-productGalleryLists > .scrollTop') : false;
          this.sliderBottom = parent ? parent.querySelector('.js-productGalleryLists > .scrollBottom') : false;
    
          this.initSlider();
       }
    
       watchClickEvent() {
          [].slice.call(this.allPictures).forEach(picture => {
             picture.addEventListener('mouseover', event => {
                event.preventDefault();
    
                this.mainPicture.setAttribute('data-target-id', picture.getAttribute('data-pics-id'))
    
                let childImg = this.mainPicture.querySelector('img');
                childImg.src = picture.href;
                childImg.setAttribute('srcset', picture.getAttribute('srcset') || picture.href);
                childImg.setAttribute('src', picture.href);
             })
          })
       }
    
       checkScrollHPosition() {
          let maxScrollLeft = this.picturesSlider.scrollWidth - this.picturesSlider.clientWidth;
          let scrollLeft = this.picturesSlider.scrollLeft;
    
          return (maxScrollLeft == 0)
             ? 'noScroll'
             : (scrollLeft == maxScrollLeft)
                ? 'onRight'
                : (scrollLeft == 0)
                   ? 'onLeft'
                   : 'onMiddle'
       }
    
       updateScrollHNav(position = this.checkScrollHPosition()) {
          this.sliderLeft.classList.remove('display-it');
          this.sliderRight.classList.remove('display-it');
    
          if(position == 'onLeft') {
             this.sliderLeft.classList.add('display-it');
          } else if(position == 'onRight') {
             this.sliderRight.classList.add('display-it');
          } else if(position == 'onMiddle') {
             this.sliderLeft.classList.add('display-it');
             this.sliderRight.classList.add('display-it');
          }
       }
    
       checkScrollVPosition() {
          let maxScrollTop = this.picturesSlider.scrollHeight - this.picturesSlider.clientHeight;
          let scrollTop = this.picturesSlider.scrollTop;
    
          return (maxScrollTop == 0)
             ? 'noScroll'
             : (scrollTop == maxScrollTop)
                ? 'onBottom'
                : (scrollTop == 0)
                   ? 'onTop'
                   : 'onMiddle'
       }
    
       updateScrollVNav(position = this.checkScrollVPosition()) {
          this.sliderTop.classList.remove('display-it');
          this.sliderBottom.classList.remove('display-it');
    
          if(position == 'onTop') {
             this.sliderBottom.classList.add('display-it');
          } else if(position == 'onBottom') {
             this.sliderTop.classList.add('display-it');
          } else if(position == 'onMiddle') {
             this.sliderTop.classList.add('display-it');
             this.sliderBottom.classList.add('display-it');
          }
       }
    
       initSlider() {
          this.updateScrollHNav();
          this.updateScrollVNav();
          this.picturesSlider.addEventListener('scroll', () => {
             this.updateScrollHNav();
             this.updateScrollVNav();
          })
    
          // Check main picture click
          this.mainPicture.onclick = event => {
             event.preventDefault();
             document.querySelector(`[data-pics-id="${this.mainPicture.getAttribute('data-target-id')}"]`).click();
          }
    
          this.sliderLeft.onclick = () => {
             
             let maxScrollLeft = this.picturesSlider.scrollWidth - this.picturesSlider.clientWidth;
             let scrollLeft = this.picturesSlider.scrollLeft;
    
             let scrollTransition = scrollLeft + getWidthElement(this.allPictures[0].parentNode);
             
             this.picturesSlider.scrollLeft = (scrollTransition > maxScrollLeft) ? maxScrollLeft : scrollTransition;
    
             this.updateScrollHNav();
          }
    
          this.sliderRight.onclick = () => {
             let scrollLeft = this.picturesSlider.scrollLeft;
    
             let scrollTransition = scrollLeft - getWidthElement(this.allPictures[0].parentNode);
             
             this.picturesSlider.scrollLeft = (scrollTransition < 0) ? 0 : scrollTransition;
    
             this.updateScrollHNav();
          }
    
          this.sliderBottom.onclick = () => {
             let maxScrollTop = this.picturesSlider.scrollTop + this.picturesSlider.clientHeight;
             let scrollTop = this.picturesSlider.scrollTop;
    
             let scrollTransition = scrollTop + getHeightElement(this.allPictures[0].parentNode);
             
             this.picturesSlider.scrollTop = (scrollTransition > maxScrollTop) ? maxScrollTop : scrollTransition;
    
             this.updateScrollVNav();
          }
    
          this.sliderTop.onclick = () => {
             let scrollTop = this.picturesSlider.scrollTop;
    
             let scrollTransition = scrollTop - getHeightElement(this.allPictures[0].parentNode);
             
             this.picturesSlider.scrollTop = (scrollTransition < 0) ? 0 : scrollTransition;
    
             this.updateScrollVNav();
          }
       }
    }
    
    document.addEventListener('DOMContentLoaded', () => {
       [].slice.call(document.querySelectorAll('.js-productGallery')).forEach(productGallery => {
          if(productGallery.querySelector('.js-productGalleryLists')) {
             let gallery = new oProductGallery(productGallery);
             gallery.initSlider();
             gallery.watchClickEvent();
          }
       })
    })
    
  • URL: /components/raw/block-product-image/block-product-image.js
  • Filesystem Path: components/06-components/02-blocks/07-block-product-image/block-product-image.js
  • Size: 6.6 KB

There are no notes for this item.