/home/bdqbpbxa/demo-subdomains/magnetiq.goodface.com.ua/js/animations.js
// Animations module

// Scroll animations - params

const DEFAULT_SCROLL_ANIMATION_DELAY = 200;

const DEFAULT_SCROLL_ANIMATION_OFFSET = {
  'word': 1,
  'fade': 0.25,
  'scale': 0.25,
  'swim-top': 0.25,
  'swim-left': 0.25,
  'swim-right': 0.25,
  'animate-group': 0.25
};


// Scroll animations - main functionality

function scrollAnimations() {
  const scrollBottom = window.scrollY + window.innerHeight;

  const groupElements = $('[data-animate-group]').not('.-animated');
  const singleElements = $('[data-animate]').not('.-animated, [data-animate-group] [data-animate]');

  singleElements.each(function() {
    const offsetTop = $(this).offset().top;

    if (scrollBottom > offsetTop) {
      if (!$(this).closest('[data-animate-group]').data('on-click')) {
        const startOffset = offsetTop + getScrollAnimationElementOffset(this);

        if (scrollBottom > startOffset) {
          const dataType = $(this).data('animate');

          if (dataType === 'word') scrollAnimateTextPrepare(this);

          $(this).outerWidth(); // Lifehack for text animation
          $(this).addClass('-animated');

          scrollAnimateClearTransition(this);
        }

      }
    }
  });

  groupElements.each(function() {
    let onClickTrigger = $(this).data('on-click');
    if (!onClickTrigger) {
      const offsetTop = $(this).offset().top;

      if (scrollBottom > offsetTop) {
        const startOffset = offsetTop + getScrollAnimationElementOffset(this);

        if (scrollBottom > startOffset) {
          $(this).find('[data-animate="word"]').each(function() {
            scrollAnimateTextPrepare(this);
          });

          $(this).outerWidth(); // Lifehack for text animation

          $(this).addClass('-animated');
          $(this).find('[data-animate]').addClass('-animated');

          scrollAnimateClearTransition(this);
        }
      }
    }
  });
}

// Scroll animations - helpers

function scrollAnimateTextPrepare(el) {
  const nodesArr = getAllTextNodesFromElement(el);
  const delay = $(el).css('transition-delay');
  let elParent = $(el);
  let needRedDot = $(el).is('.--red-dot, .editor h1, .editor h2');

  nodesArr.forEach(node => {
    const textContent = node.textContent.trim();
    const textArr = textContent.split(' ');

    let textNodeNewHtml = '';
    textArr.forEach(el => {
      textNodeNewHtml += `
				<span class="animate-word" style="transition-delay: ${delay}">
					<span class="animate-word__inner" style="transition-delay: ${delay}">${el}</span>
				</span> `;
    });

    const replaceNode = document.createRange().createContextualFragment(textNodeNewHtml);

    node.replaceWith(replaceNode);
    let previousOffset = 0;
    let customDelay = 0;
    $(el).find('.animate-word').each(function() {
      if (Number($(this).css('transition-delay').replace('s', '')) == 0) {
        let thisOffsetTop = $(this).offset().top;

        if (previousOffset != thisOffsetTop) {
          customDelay += 0.08;
        }
        $(this).find('.animate-word__inner').css('transition-delay', `${customDelay}s`);

        previousOffset = thisOffsetTop;
      }

      if ($(this).is(':last-child')) {
        if (needRedDot) {
          let thisText = $(this).find('span').html().trim();
          let last = thisText.slice(-1);
          if (last == '.') {
            let newString = thisText.substring(0, thisText.length - 1) + "<span class='--red-color'>.</span>";
            $(this).find('span').html(newString);
          }
        }
      }
    })

    if ($(el).find('a').length) {
      $(el).find('a').each(function() {
        if ($(this).is(':last-of-type')) {
          let next = $(this).next('.animate-word');
          let text = next.find('.animate-word__inner').text().trim();
          if (text == '.') {
            next.addClass('-absolute-dot');
          }
        }
      })
    }
  });
}

function getScrollAnimationElementOffset(el) {
  let offset = 0;
  let dataOffset = Number($(el).data('offset'));

  if (dataOffset === 0) return 0;

  if (!dataOffset) {
    const isGroup = $(el).is('[data-animate-group]');
    const animationType = $(el).data('animate');
    const type = isGroup ? 'animate-group' : animationType;

    dataOffset = DEFAULT_SCROLL_ANIMATION_OFFSET[type];
  }

  if (dataOffset && dataOffset <= 1) {
    offset = $(el).outerHeight() * dataOffset;
  }

  if (dataOffset && dataOffset > 1) {
    offset = dataOffset;
  }

  return offset;
}

function getAllTextNodesFromElement(el) {
  const nodes = el.childNodes;
  const nodesArr = [];

  nodes.forEach(node => {
    const isTextNode = node.nodeType === 3 && node.textContent.trim().length;

    if (isTextNode) {
      nodesArr.push(node);
    }
  });

  el.querySelectorAll('*').forEach(childEl => {
    const nodes = childEl.childNodes;

    nodes.forEach(node => {
      const isTextNode = node.nodeType === 3 && node.textContent.trim().length;

      if (isTextNode) {
        nodesArr.push(node);
      }
    });
  });

  return nodesArr;
}

function scrollAnimateClearTransition(el) {
  const isGroup = $(el).is('[data-animate-group]');
  const doNotClearAnimations = $(el).is('[data-do-not-clear-animate]');

  if (isGroup) {
    $(el).find('[data-animate]').each(function() {
      const animateEl = this;
      const doNotClearAnimations = $(this).is('[data-do-not-clear-animate]');

      const callbackEl = $(this).is('[data-animate="word"]') ? $(this).find('.animate-word__inner')[0] : this;

      if (!doNotClearAnimations) {
        fullTransitionendCallback(callbackEl, function(e) {
          $(animateEl).off('transitionend');
          $(animateEl).removeAttr('data-animate data-index').css('transition-delay', '');
        });
      }
    });
  } else if (!isGroup && !doNotClearAnimations) {
    fullTransitionendCallback(el, function(e) {
      $(e.target).off('transitionend');
      $(e.target).removeAttr('data-animate data-index').css('transition-delay', '');
    });
  }
}

// Scroll animations - initialization

function scrollAnimationsInit() {
  $('[data-animate-group]').each(function() {
    const groupDataType = $(this).data('animate-group');
    const groupDataDelay = $(this).data('delay');

    const groupType = groupDataType !== 'list' && groupDataType !== 'index-list' ? 'default' : groupDataType;
    const groupDelay = groupDataDelay ? groupDataDelay : DEFAULT_SCROLL_ANIMATION_DELAY;


    $(this).find('[data-animate]').each(function(index) {
      let delay = 0;

      const itemDataIndex = $(this).data('index');
      const itemDataDelay = $(this).data('delay');

      if (groupType === 'default') {
        delay = itemDataDelay ? itemDataDelay : 0;
      }

      if (groupType === 'list') {
        delay = itemDataIndex ? groupDelay * itemDataIndex : groupDelay * index;
      }
      $(this).css('transition-delay', `${delay}ms`);
    });
  });

  scrollAnimations();

  $(window).on("scroll", scrollAnimations);
}

$(window).on("load", scrollAnimationsInit);

// default animations group but On Click

function animateGroupAfterClick(element) {
  let group = element.find('[data-animate-group]').length ? element.find('[data-animate-group]') : element;
  group.each(function() {
    group.find('[data-animate="word"]').each(function() {
      if (!$(this).data('first-iteration')) {
        scrollAnimateTextPrepare(this);
        $(this).data('first-iteration', true);
      }
    });

    group.outerWidth(); // Lifehack for text animation

    group.addClass('-animated');
    group.find('[data-animate]').addClass('-animated');

    scrollAnimateClearTransition(this);
  })
}

// prepare mobile animation

$(window).on('load', function() {
  let elementsForAnimation = $('[data-mobile-animate]');
  if (isPc || !elementsForAnimation.length) return;
  elementsForAnimation.each(function() {
    let animationAttr = $(this).attr('data-mobile-animate');
    $(this).attr('data-animate', animationAttr);
    $(this).removeAttr('data-mobile-animate')
  })
})



// Conveyor line functionality
const conveyor = $(".conveyor-belt__belt");

function conveyorReady(conveyor) {
  let thisConveyor = conveyor;
  const part = thisConveyor.find(".conveyor-belt__belt-part");
  if (part.length) {
    const partWidth = part.outerWidth();
    const containerWidth = part.closest('.conveyor-belt__belt').innerWidth();

    let partDublicateCount;
    let partHtml = part[0].outerHTML;
    let appendHtml = "";

    if (partWidth > containerWidth) {
      partDublicateCount = 1;
    } else {
      partDublicateCount = Math.ceil(containerWidth / partWidth);
    }

    for (var i = 0; i < partDublicateCount; i++) {
      appendHtml += partHtml;
    }

    thisConveyor.append(appendHtml);

    if (!thisConveyor.hasClass('-custom-trigger')) {
      startConveyorAnimation(thisConveyor, partWidth);
    }
  }
}

function startConveyorAnimation(conveyor, partWidth) {
  let index = 1.2;
  if (!isPc) {
    index = 1.5;
  }
  const speed = index * (partWidth / 100);

  let animationVal = `conveyor-part ${speed}s linear infinite`;
  if (conveyor.hasClass('-reverse')) {
    animationVal = `conveyor-part-reverse ${speed}s linear infinite`;
  }

  conveyor.find(".conveyor-belt__belt-part").css({
    animation: animationVal,
  });
}

// Conveyor start
$(window).on('load', function() {

  const conveyorObserver = new IntersectionObserver((entries) => {
    entries.forEach(function(item, index) {
      if (item.isIntersecting) {
        let allowToStart = ($(item.target).hasClass('-only-for-mob') && !isPc) || !$(item.target).hasClass('-only-for-mob');
        if (allowToStart) {
          if (!$(item.target).find('.-lazyload:not(.-loaded)').length) {
            const conveyor = $(item.target);
            conveyorReady(conveyor);
            conveyorObserver.unobserve(item.target);
          }
        }
      }
    })
  }, {
    rootMargin: '50px',
    threshold: 0
  });

  conveyor.each(function() {
    conveyorObserver.observe(this);
  });

})


// Auto slider in texts

$(window).on('load', function() {
  let sliders = $('.auto-slider');

  const autoSliderObserver = new IntersectionObserver((entries) => {
    entries.forEach(function(item, index) {
      if (item.isIntersecting) {
        runSliderInTexts($(item.target));
      } else {
        stopSliderInTexts($(item.target));
      }
    })
  }, {
    threshold: 0
  });

  sliders.each(function() {
    autoSliderObserver.observe(this);
  });
})

let sliderInTextsIntervals = [];

function runSliderInTexts(slider) {
  stopSliderInTexts(slider);

  let interval = setInterval(function() {
    let currImg = slider.find('img.-active');
    let nextImg = currImg.next('img').length ? currImg.next('img') : slider.find('img:first-child');

    currImg.removeClass('-active');
    nextImg.addClass('-active');
  }, 1000);
  let object = {
    slider: slider,
    interval: interval,
  }
  sliderInTextsIntervals.push(object);
}

function stopSliderInTexts(slider) {
  let foundObjectIndex = sliderInTextsIntervals.findIndex(function(obj) {
    return obj.slider.is(slider);
  });

  if (sliderInTextsIntervals[foundObjectIndex]) {
    clearInterval(sliderInTextsIntervals[foundObjectIndex].interval);
    sliderInTextsIntervals.splice(foundObjectIndex, 1);
  }
}


// animate steps section

function animatePinnedCardsSection() {
  const pinnedSliderContainer = $('.pinned-slider');
  const textCards = gsap.utils.toArray('.pinned-slider__card-wrapper');
  const cardsWrappers = gsap.utils.toArray('.pinned-slider__card');

  let pinnedSlider, blockHeight, startPos, cardHeight, parentOffsetTop, cardOffsetTop, parentHeight;

  if (!pinnedSliderContainer.length || !textCards.length || !isPc) return;

  cardHeight = $(textCards[0]).innerHeight();
  blockHeight = (textCards.length * cardHeight) - cardHeight;
  parentOffsetTop = pinnedSliderContainer.offset().top;

  let offsetPerSlide = Math.min(32, (window.innerWidth / 100) * ((32 / 800) * 100));
  let paddingBottom = cardsWrappers.length > 3 ? offsetPerSlide * (cardsWrappers.length - 2) : offsetPerSlide * (cardsWrappers.length - 1);
  let sliderContainer = pinnedSliderContainer.closest(".pinned-slider__wrapper");
  let currentPadding = parseFloat(sliderContainer.css('padding'));
  let paddingCalculation = paddingBottom + currentPadding;
  sliderContainer.css('padding-bottom', paddingCalculation);
  sliderContainer.css('padding-top', paddingCalculation);

  pinnedSlider = gsap.to(pinnedSliderContainer[0], {
    ease: "none",
    scrollTrigger: {
      invalidateOnRefresh: true,
      trigger: pinnedSliderContainer[0],
      start: () => {
        let calculatedStart = pinnedSliderContainer.innerHeight() / 2;
        return `${calculatedStart} center`;
      },
      end: `+=${blockHeight}px`,
      pin: true,
      scrub: 0.5,
      // markers: true,
    }
  });


  textCards.forEach((card, index) => {


    const tl = gsap.timeline({
        scrollTrigger: {
          // markers: true,
          trigger: cardsWrappers[index],
          start: () => {
            cardOffsetTop = $(cardsWrappers[index]).offset().top;

            startPos = parentOffsetTop - cardOffsetTop + (cardHeight / 2) + (cardHeight * index) - cardHeight;
            return `${startPos} center`;
          },
          end: () => {
            if (index == 0) {
              return `+=${cardHeight / 2}`;
            } else {
              return `+=${cardHeight}`;
            }
          },
          scrub: 0.5,
          onUpdate: (progress) => {
            $(cardsWrappers[index]).attr('data-progress', progress.progress);
          }
        }
      })
      .to(
        card, {
          y: 0,
        },
        '<'
      )


    for (let i = 0; i < index; i++) {
      let scaling = 1 - ((index - i) * 0.1);
      let opacityValue = Math.abs(((index - i) * 0.35));
      let yValue = (index - i) * (offsetPerSlide * -1);

      tl.to(
        cardsWrappers[i], {
          y: yValue,
          scale: scaling,
          // opacity: opacityValue,
          onUpdate: () => {
            let progress = $(cardsWrappers[index]).attr('data-progress');
            if (progress < 0.1) {
              $(cardsWrappers[index - 1]).find('.overlay').css('opacity', 0);
            } else {
              $(cardsWrappers[i]).find('.overlay').css('opacity', opacityValue);
            }
          }
        },
        '<'
      );
    }

  });

  setTimeout(() => {
    ScrollTrigger.refresh(true);
  }, 100)
}

$(window).on('load', function() {
  if (!$('.pinned-slider').length) return;
  animatePinnedCardsSection();
  // const stepsSectionObserver = new IntersectionObserver((entries) => {
  //   if (entries[0].isIntersecting) {
  //     animatePinnedCardsSection();
  //     stepsSectionObserver.unobserve(entries[0].target);
  //   }
  // }, {
  //   rootMargin: "100px",
  //   threshold: 0,
  // });


  // $('.pinned-slider').each(function() {
  //   stepsSectionObserver.observe(this);
  // })

});



// animate statistics cards
gsap.registerPlugin(ScrollTrigger);

function animateStatisticCards(cardsCol) {

  if (!$(cardsCol).length) return;


  $(cardsCol).find('.statistic-card').each(function() {
    let realIndex = $(this).index();
    if (realIndex == 0) return;
    let offset = isPc ? 22 : 31;
    $(this).css('margin-top', `-${offset}%`);
  });

  const tl = gsap.timeline({
    ease: "none",
    scrollTrigger: {
      invalidateOnRefresh: true,
      trigger: cardsCol,
      start: "top center",
      // markers: true,
      onUpdate: () => {
        $(cardsCol).addClass('-animated');
      }
    },

  });



}

$(window).on('load', function() {
  if (!$('.statistic-list .col').length) return;
  const stepsSectionObserver = new IntersectionObserver((entries) => {
    entries.forEach(function(item) {
      if (item.isIntersecting) {
        animateStatisticCards(item.target);
        stepsSectionObserver.unobserve(item.target);
      }
    })
  }, {
    rootMargin: "100px",
    threshold: 0,
  });


  $('.statistic-list .col').each(function() {
    stepsSectionObserver.observe(this);
  })

});

$(window).on('load', function() {
  observeTeamVideo();
})


// animate team block

function observeTeamVideo() {

  const videoContainer = $('.team-grid');
  /* TODO: remove condition if get better quality video */
  if (isPc) {
    const teamVimeo = new Vimeo.Player('team-video', {
      id: 927773903,
      controls: false,
      muted: true,
      title: false,
      height: '100%',
      autoplay: false,
      responsive: true,
    });

    const observer = new IntersectionObserver(function(entries) {
      if (entries[0].isIntersecting) {
        observer.unobserve(entries[0].target);

        teamVimeo.play();

        teamVimeo.on('play', function() {
          $('.-before-start-video').removeClass('-before-start-video');
        })

        teamVimeo.on('timeupdate', function(params) {
          let videoOffset = isPc ? 0.4 : 0.1;
          if (params.percent >= videoOffset) {
            animateGroupAfterClick(videoContainer);
          }

          if (params.percent >= 0.95) {
            teamVimeo.pause();
            // videoContainer.closest('.team-grid').addClass('-static');
          }
        })
      }
    }, {
      threshold: isPc ? 0.5 : 0.2,
    });

    observer.observe(videoContainer[0]);
  } else {
    const observer = new IntersectionObserver(function(entries) {
      if (entries[0].isIntersecting) {
        observer.unobserve(entries[0].target);
        animateGroupAfterClick(videoContainer);
      }
    }, {
      threshold: 0.2,
    });

    observer.observe(videoContainer[0]);
  }


}

// animate pinned video 

function animatePinnedVideoSection() {
  const pinnedVideoContainer = $('.pinned-video');
  const pinnedVideo = pinnedVideoContainer.find('.pinned-video__inner');
  if (!pinnedVideoContainer.length) return;
  if (isPc) {

    const tl = gsap.to(pinnedVideoContainer[0], {
      ease: "none",
      // width: '100%',
      scrollTrigger: {
        invalidateOnRefresh: true,
        trigger: pinnedVideoContainer[0],
        start: () => {
          let calculatedStart = window.innerHeight / 2;
          return `${calculatedStart} center`;

        },
        end: `+=${300}px`,
        pin: true,
        scrub: 0.5,
      }
    });

    const innerAnimation = gsap.to(pinnedVideo[0], {
      ease: "none",
      scale: 1,
      scrollTrigger: {
        invalidateOnRefresh: true,
        trigger: pinnedVideo[0],
        start: () => {
          let calculatedStart = window.innerHeight / 2 - $('.header').innerHeight() - $('.rebrand-banner').innerHeight() - 450;
          return `${calculatedStart} center`;

        },
        onUpdate: (progress) => {
          if (progress.progress >= 1 && !$(progress.trigger).hasClass('-show-toolbar')) {
            $(progress.trigger).addClass('-show-button');
          } else {
            // totalResetVideo($(progress.trigger).find('video'));
          }
        },
        end: `+=${600}px`,
        scrub: 0.5,
        // markers: true,
      }
    });
  } else {
    pinnedVideo.addClass('-show-button');
  }

}

$(window).on('load', function() {
  if (!$('.background-video-wrapper').length) return;
  const bgVideoObserver = new IntersectionObserver((entries) => {

    entries.forEach(function(entry) {
      if (entry.isIntersecting) {
        let video = $(entry.target).find('video');
        // video[0].play();
        video[0].onplaying = function() {
          $(entry.target).removeClass('-static');
        };
        video[0].onpause = function() {
          $(entry.target).addClass('-static');
        };
        video[0].onended = function() {
          $(entry.target).addClass('-static');
        };
        video[0].onloadedmetadata = function() {
          $(entry.target).addClass('-static');
        };
        bgVideoObserver.observe(entry.target);
      }
    })
  }, {
    threshold: 0,
  });


  $('.background-video-wrapper').each(function() {
    bgVideoObserver.observe(this);
  })

});