|
- 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 = $('<div class="slide-overflow" />').appendTo(section);
- this.slideWrapper = $('<div class="slide-wrapper" />').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');
- 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 = $('<span />');
-
- this.prevButton = $('<button class="prev" aria-label="Previous Slide" />');
- this.nextButton = $('<button class="next" aria-label="Next Slide" />');
- const tabsWrapper = $('<ul class="slider-tabs" />');
- const countWrapper = $('<span class="count" />')
- .html('/<span class="total">' + this.slides.length + '</span></span>')
- .prepend(this.count);
-
- this.tabs = tabsWrapper.children();
-
- if (this.slides.length > 1) {
- this.slides.each(function (i) {
- const s = $(this);
- const li = $('<li/>').appendTo(tabsWrapper);
-
- var button = $('<button />').addClass('btn').appendTo(li);
- const span = $('<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 = $('<div class="controls" />')
- .append(this.prevButton)
- .append(tabsWrapper)
- .append(countWrapper)
- .append(this.nextButton)
- .appendTo(this.section);
- } else {
- this.controls = $('<div class="controls" />')
- .append(tabsWrapper)
- .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 = $('<img/>').one('load', function (e) {
- const loadedImage = $(this).removeClass('loading');
- 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');
- };
-
- setupSteps() {
- this.nextButton.text('Weiter').addClass('btn').addClass('has-icon').addClass('icon-right').addClass('icon-pfeil-rechts');
- }
- }
-
- export default IHKSlider;
-
- $('body').on('ihk-init dynamic-component-loaded gfi-dynamic-init', () => {
- $('.rotation .slider:not(.initiated), .steps .slider:not(.initiated)').each((i, el) => {
- const selector = $(el);
- if (!selector.find('dynamic-content').length) {
- new IHKSlider(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));
- });
- */
- });
|