/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);
})
});