/home/bdqbpbxa/demo-subdomains/sendon.goodface.com.ua/layout/js/animations.js
// Button swipe animation
function animateButton(el, direction) {
let button = el;
let icon = button.find('.icon');
let text = button.find('.text');
let buttonPosition = parseInt(button.offset().left);
let iconPosition = parseInt(icon.offset().left);
let textPosition = parseInt(text.offset().left);
let buttonWidth = parseInt(button.innerWidth());
let iconWidth = parseInt(icon.innerWidth());
let textWidth = parseInt(text.innerWidth());
let iconOffset = parseInt(icon.css('left'));
let textOffset = parseInt(button.css('padding-right'));
let iconEndPosition, textEndPosition;
if (direction == 'toFinish') {
iconEndPosition = (buttonPosition + buttonWidth - iconOffset) - iconPosition - iconWidth;
textEndPosition = textPosition - (buttonPosition + textOffset);
icon.css('transform', `translateX(${iconEndPosition}px)`);
// text.css('transform', `translateX(-${textEndPosition}px)`);
} else {
icon.css('transform', `translateX(0)`);
// text.css('transform', `translateX(0)`);
}
}
// $(document).on('mouseenter', '.default-button.-hover-swipe', function () {
// animateButton($(this), 'toFinish')
// })
// $(document).on('mouseleave', '.default-button.-hover-swipe', function () {
// animateButton($(this), 'toStart')
// })
// Conveyor line functionality
const conveyor = $(".conveyor-belt");
function conveyorReady(conveyor) {
let thisConveyor = conveyor;
const part = thisConveyor.find(".conveyor-belt-part");
const partWidth = part.outerWidth();
const windowWidth = window.screen.width;
let partDublicateCount;
let partHtml = part[0].outerHTML;
let appendHtml = "";
if (partWidth >= windowWidth) {
partDublicateCount = 1;
} else {
partDublicateCount = Math.ceil(windowWidth / partWidth) - 1;
}
for (var i = 0; i < partDublicateCount; i++) {
appendHtml += partHtml;
}
thisConveyor.append(appendHtml);
startConveyorAnimation(thisConveyor, partWidth);
}
function startConveyorAnimation(conveyor, partWidth) {
let index = 0.2;
let speed = index * (partWidth / 10);
// const speed = 18;
let animationVal = `conveyor-part ${speed}s linear infinite`;
if (conveyor.hasClass('-reverse')) {
animationVal = `conveyor-part-reverse ${speed}s linear infinite`;
}
conveyor.find(".conveyor-belt-part").css({
animation: animationVal,
});
}
// Conveyor start
$(window).on('load', initConveyer);
function initConveyer() {
conveyor.each(function () {
let line = $(this);
if (line.hasClass('-for-pc')) {
if (isPc) {
enableConveyer()
}
} else {
enableConveyer();
}
function enableConveyer() {
conveyorReady(line);
}
});
}
// Why choose us animation cards
$(window).on('load resize', function () {
const boxes = gsap.utils.toArray('.why-choose-us .why-choose-us-card');
if ($('.why-choose-us').length && isPc) {
let container = $('.why-choose-us-cards');
boxes.forEach(box => {
let elObj = $(box);
let xFinal = elObj.attr('data-x-final');
let yFinal = elObj.attr('data-y-final');
let rotationFinal = elObj.attr('data-rotation-final');
gsap.to(box, {
x: xFinal,
y: yFinal,
rotation: rotationFinal,
duration: 3,
scrollTrigger: {
start: 'top center',
end: '50% center',
trigger: container,
scrub: 1.5,
// once: true,
ignoreMobileResize: true
}
});
});
} else {
boxes.forEach(box => {
$(box).css('transform', 'none');
});
}
})
// our-offer slider
$(window).on('load', function () {
if (isPc) {
if ($('.benefits-slide').length) {
aboutUsSlider();
}
if ($('.our-offer-slide').length) {
ourOfferAnimation();
onLoadChildImages($('.our-offer-slider__wrapper'), function () {
$('.our-offer-slider__wrapper').css('height', $('.our-offer-slide').innerHeight());
})
}
}
})
function ourOfferAnimation() {
const slides = gsap.utils.toArray('.our-offer-slide');
let slide = $('.our-offer-slide');
if (slide.length && isPc) {
// Set height ot pinned block
let slideCount = slide.length;
let blockHeight;
slides.forEach(slide => {
let elObj = $(slide);
let index = elObj.index();
let slideWidth = Number(elObj.innerWidth());
let halfOfWindowWidth = Number(window.innerWidth) / 2;
let startTrigger = (slideWidth / 2 + (window.scrollbarWidth / 2)) + (halfOfWindowWidth * index);
if (index == slideCount - 2) {
blockHeight = startTrigger;
}
})
// Pin the container
let scrollContainer = gsap.to(".pinned-slider", {
x: `-${blockHeight}px`,
ease: "none",
scrollTrigger: {
trigger: ".pinned-slider",
start: "-140px top",
end: `+=${blockHeight}px`,
pin: true,
scrub: 0.5,
// markers: true,
}
});
// Pin slider container in other side
let scrollInner = gsap.to(".pinned-slider__wrapper", {
x: `${blockHeight}px`,
ease: "none",
scrollTrigger: {
trigger: ".pinned-slider",
start: "-140px top",
end: `+=${blockHeight}px`,
scrub: 0.5,
// markers: true,
}
});
// Animated slides
$('.our-offer-slider__wrapper').css('height', $('.our-offer-slide').innerHeight());
let startOffsetRight = 32;
let currentOffsetRight = 0;
let startScaleOffset = 1;
let blurOffset = 0;
slides.forEach(slide => {
let elObj = $(slide);
let index = elObj.index();
let lastSlide = index == slideCount - 1
let firstSlide = index == 0;
elObj.css('z-index', slides.length - index);
// Set slide position before animation start
let xStart = startOffsetRight;
if (index > 0) {
xStart = currentOffsetRight + startOffsetRight;
startOffsetRight -= 4;
}
if (firstSlide) {
xStart = 0;
}
currentOffsetRight = xStart;
elObj.css({
'transform': `translateX(${xStart}px) scale(${startScaleOffset})`,
'filter': `blur(${blurOffset}px)`,
});
startScaleOffset -= 0.04;
blurOffset += 0.5;
// Calculate trigger position when animation must start
let slideWidth = Number(elObj.innerWidth());
let halfOfWindowWidth = Number(window.innerWidth) / 2;
let startTrigger = (slideWidth / 2 + (window.scrollbarWidth / 2)) + (halfOfWindowWidth * index);
let endTrigger = startTrigger;
let sliderTopOffset = $('.pinned-slider').offset().top;
let anchorPosition = sliderTopOffset;
if (!firstSlide) {
endTrigger = startTrigger;
startTrigger = startTrigger - (halfOfWindowWidth / 2) * index;
anchorPosition = startTrigger + ((endTrigger - startTrigger) / 2) + (sliderTopOffset / 2) + 45;
}
if (lastSlide) {
anchorPosition += 200;
}
elObj.attr('data-anchor-position', anchorPosition);
const tl = gsap.timeline({
scrollTrigger: {
trigger: '.pinned-slider__wrapper',
containerAnimation: scrollContainer,
start: `${startTrigger}px 50%`,
end: `${endTrigger}px left`,
scrub: true,
// markers: true,
onUpdate: function (gsapObj) {
if (gsapObj.progress >= 0.4 && gsapObj.progress <= 0.6) {
updatePagination($('.our-offer-slider'), index);
}
}
}
}).to(slide, {
x: '0',
scale: 1,
filter: `blur(0px)`,
})
if (!lastSlide) {
tl.to(slide, {
x: '-150%',
})
} else {
tl.to(slide, {
x: '0',
scale: 1,
filter: `blur(0px)`,
})
}
});
// Create pagination fo slider
pinnedPagination($('.our-offer-slider'));
}
}
function aboutUsSlider() {
let slides = $('.benefits-slide');
let slidesLength = slides.length;
let InnerHeight = slides.eq(0).innerHeight();
let slideInnerWidth = slides.eq(0).innerWidth();
let AllHeight = slidesLength * InnerHeight;
if (slides && isPc) {
// Pin the container
let scrollContainer = gsap.to(".pinned-slider", {
x: 0,
ease: "none",
scrollTrigger: {
trigger: ".pinned-slider",
start: "-104px top",
end: `+=${AllHeight}`,
pin: true,
scrub: 0.5,
}
});
let scrollInner = gsap.to(".benefits__slider-wrapper", {
xPercent: -100 * (slidesLength - 1),
ease: "none",
scrollTrigger: {
trigger: ".pinned-slider",
start: "-104px top",
end: `+=${AllHeight}`,
scrub: 0.5,
// markers: true,
}
});
const slides = gsap.utils.toArray('.benefits-slide');
slides.forEach(slide => {
let index = $(slide).index();
// let anchorPosition = ;
let halfOfWindowWidth = Number(window.innerWidth) / 2;
let allBlockheight = $(slide).closest('.pin-spacer').innerHeight() / slidesLength;
let sliderTopOffset = $('.benefits-section').offset().top;
let anchorPosition = sliderTopOffset;
if (index == 0) {
anchorPosition = sliderTopOffset + 10;
}
if (index != 0) {
anchorPosition = sliderTopOffset + (allBlockheight * index);
}
if (index == slidesLength - 1) {
anchorPosition = anchorPosition - 20;
}
$(slide).attr('data-anchor-position', anchorPosition);
const tl = gsap.timeline({
scrollTrigger: {
trigger: slide,
containerAnimation: scrollInner,
start: `50% right`,
end: `50% left`,
scrub: 0.2,
onUpdate: function (gsapObj) {
if (gsapObj.progress >= 0.4 && gsapObj.progress <= 0.6) {
updatePagination($('.pinned-slider'), index);
}
}
}
}).to(slide, {
opacity: '1',
})
.to(slide, {
opacity: '1',
})
if (index != slidesLength - 1) {
tl.to(slide, {
opacity: '1',
})
tl.to(slide, {
opacity: '0.32',
})
} else {
tl.to(slide, {
opacity: '1',
})
tl.to(slide, {
opacity: '1',
})
}
})
pinnedPagination($(".pinned-slider"));
}
}
function pinnedPagination(slider) {
let pinSlider = slider;
let pinSlides = pinSlider.find('.pinned-slider__slide');
let pinSlidesCount = pinSlides.length;
let pinPaginationContainer = pinSlider.find('.pinned-slider__pagination');
if (!$('.pinned-slider__pagination .pagination-bullet').length) {
for (i = 1; i <= pinSlidesCount; i++) {
let paginationBullet = `<span class="pagination-bullet" ></span>`;
if (i == 1) {
paginationBullet = `<span class="pagination-bullet -active" ></span>`;
}
pinPaginationContainer.append(paginationBullet);
}
}
}
function updatePagination(slider, index) {
let pinSlider = slider;
let pinPaginationContainer = pinSlider.find('.pinned-slider__pagination');
pinPaginationContainer.find('.-active').removeClass('-active');
pinPaginationContainer.find('.pagination-bullet').eq(index).addClass('-active');
}
function paginationScroller(clickedElement) {
let index = clickedElement.index();
let pinSlider = clickedElement.closest('.pinned-slider');
let targetSlide = pinSlider.find('.pinned-slider__slide').eq(index);
let anchorPosition = targetSlide.attr('data-anchor-position');
$("body,html").animate({
scrollTop: anchorPosition,
},
400
);
}
$(document).on('click', '.pagination-bullet', function () {
paginationScroller($(this));
})
// 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.01
};
// 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) {
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 () {
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');
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);
});
}
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);