import $ from 'jquery'; import Hammer from 'hammerjs'; require('jquery.easing'); class IHKSlider { 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(); if (this.section.closest('.steps').length) { this.setupSteps(); } $(window).on('resize', () => { this.checkSize(); }) } initSlides() { this.slides.each(function (i) { const slide = $(this).attr('data-index', i); const h3 = slide.find('h3, .like-h2, .like-h3').first(); const p = h3.next('p'); const dotsString = '…' if (!slide.find('.image-box').length) { slide.addClass('text-only'); } else { if (h3.text().length > 48) { h3.html(h3.text().substring(0, 48) + dotsString); } if (p.text().length > 148) { p.html(p.text().substring(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); this.nextWrapper.find('img').removeClass('loading'); this.prevWrapper.find('img').removeClass('loading'); } initUI() { this.count = $(''); this.prevButton = $(''); this.nextButton = $(''); const tabsWrapper = $(''); const countWrapper = $('') .html('/' + this.slides.length + '') .prepend(this.count); this.tabs = tabsWrapper.children(); if (this.slides.length > 1) { this.slides.each(function (i) { const s = $(this); const li = $('').appendTo(tabsWrapper); var button = $('').addClass('btn').appendTo(li); const span = $('').appendTo(button); span.text(s.data('title') ? s.data('title') : i + 1); }); this.tabs = tabsWrapper.children(); tabsWrapper.find('button').on('click', (e) => { e.preventDefault(); this.sectionInitialClicked = true; this.changeSlide($(e.currentTarget).parent().index()); }); this.prevButton.on('click', (e) => { e.preventDefault(); this.sectionInitialClicked = true; this.onPrev(); }); this.nextButton.on('click', (e) => { e.preventDefault(); this.sectionInitialClicked = true; this.onNext(); }); this.controls = $('') .append(this.prevButton) .append(tabsWrapper) .append(countWrapper) .append(this.nextButton) .appendTo(this.section); } else { this.controls = $('') .append(countWrapper) .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; } if (index === this.currentSlide && this.slideOverflow.outerHeight() === 0) { transition = false; } 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 + 200); if (time > 500) { time = 500; } 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: () => { requestAnimationFrame(() => { 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.removeClass("btnanimation"); }) this.section.on('mouseleave', () => { this.isHovered = false; this.handleAutoplay(); this.section.addClass("btnanimation"); }) 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(); // Disable click on drag this.slideWrapper.find('a').css('pointer-events', 'none'); 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.slideWrapper.find('a').addClass('dragging'); 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); } }); // Enable click on drag this.slideWrapper.find('a').css('pointer-events', 'all'); }); } 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 = $('