// import $ from 'jquery';
import Hammer from 'hammerjs';
const $ = require('jquery');
class Slider {
constructor(section) {
this.section = section.addClass('initiated');
this.slides = section.children();
this.slideOverflow = $('
').appendTo(section);
this.slideWrapper = $('').appendTo(this.slideOverflow).append(this.slides);
this.currentSlide = 0;
this.autoplayTimeout = 0;
this.isHovered = false;
this.sectionInitialClicked = false;
this.dragging = false;
this.inViewport = false;
this.positionAnimation = {
x: 0
}
this.settings = {
loop: false,
autoplay: this.section.data('autoplay'),
infinite: true,
autoplaySpeed: this.section.data('autoplay-speed') ? this.section.data('autoplay-speed') : 5000,
animationSpeed: 600,
startSlide: 0,
};
this.initSlides();
if (this.settings.infinite) {
this.initInfinity();
}
this.initUI();
this.checkSize();
if (this.slides.length > 1) {
this.initHammerDragging();
this.initTabbing();
}
this.changeSlide(this.settings.startSlide);
this.initAutoplay();
this.checkSize();
$(window).on('resize', () => {
this.checkSize();
})
}
initSlides() {
this.slides.each(function (i) {
const slide = $(this).attr('data-index', i);
const h3 = slide.find('h3');
const p = h3.next('p');
const dotsString = '…'
if (!slide.find('.image-box').length) {
slide.addClass('text-only');
}
if (h3.text().length > 48) {
h3.html( h3.text().substr(0, 48) + dotsString );
}
if (p.text().length > 148) {
p.html( p.text().substr(0, 148) + dotsString );
}
})
}
checkSize () {
if (this.controls.find('.tabs').width() > this.slideOverflow.width() * 0.6) {
this.section.addClass('many-slides');
}
else {
this.section.removeClass('many-slides');
}
}
initInfinity() {
this.nextWrapper = this.slideWrapper.clone();
this.prevWrapper = this.slideWrapper.clone();
this.nextWrapper
.removeClass('slide-wrapper')
.addClass('next-clone')
.appendTo(this.slideWrapper)
.css({'left': this.slides.length + '%'});
this.prevWrapper
.removeClass('slide-wrapper')
.addClass('prev-clone')
.appendTo(this.slideWrapper);
this.nextWrapper.find('a, button, input, select, textarea').attr('tabindex', -1);
this.prevWrapper.find('a, button, input, select, textarea').attr('tabindex', -1);
}
initUI() {
this.count = $('');
const prevButton = $('');
const nextButton = $('');
const tabs = $('');
const count = $('')
.html('/' + this.slides.length + '')
.prepend(this.count);
this.slides.each(function (i) {
const s = $(this);
const li = $('').appendTo(tabs);
$('').appendTo(li).text(s.data('title') ? s.data('title') : i + 1);
});
this.tabs = tabs.children();
tabs.find('button').on('click', (e) => {
e.preventDefault();
this.sectionInitialClicked = true;
this.changeSlide($(e.currentTarget).parent().index());
});
prevButton.on('click', (e) => {
e.preventDefault();
this.sectionInitialClicked = true;
this.onPrev();
});
nextButton.on('click', (e) => {
e.preventDefault();
this.sectionInitialClicked = true;
this.onNext();
});
this.controls = $('').append(prevButton).append(tabs).append(count).append(nextButton).appendTo(this.section);
}
changeSlide(index, offset, transition = true) {
const t = this;
const prevIndex = index === 0 ? this.slides.length - 1 : index - 1;
const nextIndex = index === this.slides.length - 1 ? 0 : index + 1;
const allWidth = t.nextWrapper.position().left;
if (!offset) {
offset = 0;
}
t.positionAnimation = {
x: this.slideWrapper.position().left
}
let target = (index + offset) / -100 * this.slideWrapper.width();
let time = Math.round(Math.abs(this.positionAnimation.x - target) / 5 + 300);
if (time > 800) {
time = 800;
}
if (!transition) {
time = 0;
}
t.slideOverflow.css({
'transition-duration': time + 'ms',
'height': this.slideOverflow.outerHeight() + 'px'
});
t.slideWrapper.find('.current').removeClass('current');
t.slideWrapper.find('[data-index="' + index + '"]').addClass('current');
t.slideWrapper.find('.is-prev').removeClass('is-prev');
t.slideWrapper.find('[data-index="' + prevIndex + '"]').addClass('is-prev');
t.slideWrapper.find('.is-next').removeClass('is-next');
t.slideWrapper.find('[data-index="' + nextIndex + '"]').addClass('is-next');
if (target > 0) {
target = target - allWidth;
this.positionAnimation.x = this.positionAnimation.x - allWidth;
}
if (target <= allWidth * -1 + 1) {
target = target + allWidth;
this.positionAnimation.x = this.positionAnimation.x + allWidth;
}
requestAnimationFrame(() => {
this.slideOverflow.css({
'height': this.slides.eq(index).outerHeight() + 'px'
});
})
$(this.positionAnimation).animate({
x: target
}, {
duration: time,
easing: 'easeOutCubic',
step: (now) => {
this.slideWrapper.css({'transform': 'translate3d(' + Math.round(now) + 'px, 0, 0)'});
},
complete: () => {
this.slideWrapper.css({'transform': 'translate3d(' + (index * -1) + '%, 0, 0)'});
this.slideOverflow.css('height', 'auto');
}
})
this.tabs.eq(index).addClass('active').siblings('.active').removeClass('active');
this.count.text(index + 1);
if (this.settings.autoplay && !this.isHovered) {
this.handleAutoplay();
}
if (offset !== 0) {
setTimeout(() => {
this.slideWrapper.addClass('no-transition');
this.slideWrapper.css({'transform': 'translate3d(' + (index * -1) + '%, 0, 0)'});
setTimeout(() => {
this.slideWrapper.removeClass('no-transition');
},20);
}, this.settings.animationSpeed);
}
this.currentSlide = index;
this.section.trigger('slide-change');
if (this.section.closest('.steps').length && this.sectionInitialClicked) {
this.scrollToTop();
}
}
goTo(index, transition) {
if (transition === false) {
this.slideWrapper.addClass('no-transition');
}
this.sectionInitialClicked = true;
this.changeSlide(index,0, transition);
setTimeout(() => {
this.slideWrapper.removeClass('no-transition');
}, 20);
}
onNext() {
const nextSlide = this.currentSlide === this.slides.length - 1 ? 0 : this.currentSlide + 1;
const offset = this.settings.infinite && nextSlide === 0 ? this.slides.length : 0;
this.changeSlide(nextSlide, offset);
}
onPrev() {
const prevSlide = this.currentSlide === 0 ? this.slides.length - 1 : this.currentSlide - 1;
const offset = this.settings.infinite && prevSlide === this.slides.length - 1 ? this.slides.length * -1 : 0;
this.changeSlide(prevSlide, offset);
}
initAutoplay() {
this.section.on('mouseenter', () => {
this.isHovered = true;
clearTimeout(this.autoplayTimeout);
})
this.section.on('mouseleave', () => {
this.isHovered = false;
this.handleAutoplay();
})
this.initScrollCheck();
this.handleAutoplay();
}
handleAutoplay() {
if (this.dragging) {
return false;
}
clearTimeout(this.autoplayTimeout);
if (this.settings.autoplaySpeed > 0 && this.settings.autoplay) {
this.autoplayTimeout = setTimeout(() => {
if (this.inViewport) {
this.onNext();
} else {
this.handleAutoplay();
}
}, this.settings.autoplaySpeed);
}
}
initScrollCheck() {
window.addEventListener("scroll", () => {
window.requestAnimationFrame(() => {
this.scrollCheck();
})
}, {passive: true});
window.requestAnimationFrame(() => {
this.scrollCheck();
})
}
scrollCheck() {
const w = $(window);
if (w.scrollTop() + w.height() - 200 > this.section.offset().top && w.scrollTop() < this.section.offset().top + this.section.outerHeight() / 2) {
if (!this.inViewport) {
this.inViewport = true;
this.section.addClass('in-viewport').trigger('in-viewport');
}
}
else if (this.inViewport) {
this.inViewport = false;
this.section.removeClass('in-viewport');
}
}
initHammerDragging() {
const hammer = new Hammer(this.slideWrapper.get(0));
let sliderWidth = 0;
let startValue = 0;
this.dragging = false;
this.slideWrapper.find('img, a').attr('draggable', 'false').attr('ondragstart', 'return false;');
hammer.on('panstart', (e) => {
sliderWidth = this.slideOverflow.width();
this.dragging = true;
startValue = this.slideWrapper.position().left;
$(this.positionAnimation).stop();
requestAnimationFrame(() => {
$('html').addClass('slider-dragging');
})
if (e.center.x !== 0 && e.center.y !== 0) {
clearTimeout(this.autoplayTimeout);
}
});
hammer.on('pan', (e) => {
if (e.center.x !== 0 && e.center.y !== 0) {
const transformX = Math.round(startValue + e.deltaX);
this.slideWrapper.css({'transform': 'translate3d(' + transformX + 'px, 0, 0)'});
}
});
hammer.on('panend',(e) => {
this.dragging = false;
requestAnimationFrame(() => {
$('html').removeClass('slider-dragging');
if (e.deltaX > sliderWidth / 5) {
this.onPrev();
} else if (e.deltaX < sliderWidth / -5) {
this.onNext();
} else {
this.changeSlide(this.currentSlide);
}
})
});
}
initTabbing() {
$(window).keydown((e) => {
const code = (e.keyCode ? e.keyCode : e.which);
if (code === 9 && this.slideWrapper.find(':focus').length) {
this.tabScrollActive = true;
this.resetTabScroll();
}
})
$(window).keyup((e) => {
const code = (e.keyCode ? e.keyCode : e.which);
if (code === 9 && this.slideWrapper.find(':focus').length) {
const slide = this.section.find(':focus').closest('.slide');
this.slideOverflow.scrollLeft(0).scrollTop(0).find('.outer, .text-box').scrollLeft(0).scrollTop(0);
this.goTo(parseInt(slide.attr('data-index')), true);
this.tabScrollActive = false;
}
});
}
loadImage(index) {
const t = this;
if (!index) {
index = this.currentSlide;
}
if (t.slides.eq(index).hasClass('preload') && !t.slides.eq(index).find('img').length) {
const ib = t.slides.eq(index).find('.image-box');
const img = $('
').one('load', function (e) {
const loadedImage = $(this);
const slide = loadedImage.closest('.slide').removeClass('preload');
const index = parseInt(slide.attr('data-index'));
t.nextWrapper.find('[data-index="' + index + '"]').removeClass('preload').find('.image-box').append(loadedImage.clone());
t.prevWrapper.find('[data-index="' + index + '"]').removeClass('preload').find('.image-box').append(loadedImage.clone());
})
img.attr('src', ib.attr('data-src')).appendTo(ib);
img.attr('data-download', ib.attr('data-download')).appendTo(ib);
img.attr('draggable', 'false').attr('ondragstart', 'return false;');
}
}
resetTabScroll() {
this.slideOverflow.scrollLeft(0).scrollTop(0).find('.outer, .text-box').scrollLeft(0).scrollTop(0);
if (this.tabScrollActive) {
window.requestAnimationFrame(() => {
this.resetTabScroll();
})
}
}
scrollToTop() {
const target = this.section.closest('.steps').offset().top - 120;
const time = 600;
$('html, body').animate({'scrollTop': target}, time, 'easeOutQuad');
};
}
export default Slider;
$('body').on('ihk-init dynamic-component-loaded gfi-dynamic-init', function (e) {
$('.rotation .slider:not(.initiated), .steps .slider:not(.initiated)').each((i, el) => {
const selector = $(el);
if (!selector.find('dynamic-content').length) {
new Slider(selector);
}
})
/*
let slidersSelector;
if (e.type === "ihk-init") {
slidersSelector = $('.rotation .slider:not(.initiated):not(:has(dynamic-content)), .steps .slider:not(.initiated):not(:has(dynamic-content))')
} else {
slidersSelector = $('.rotation .slider:not(.initiated), .steps .slider:not(.initiated)');
}
slidersSelector.each(function () {
new Slider($(this));
});
*/
});