Skip to content

Instantly share code, notes, and snippets.

@leochocolat
Last active November 4, 2020 18:15
Show Gist options
  • Save leochocolat/5a781a365891745dcdd762573568972f to your computer and use it in GitHub Desktop.
Save leochocolat/5a781a365891745dcdd762573568972f to your computer and use it in GitHub Desktop.
import Flickity from 'flickity'
import { TweenLite, Power4, TimelineLite } from 'gsap';
import mod from '../utils/mod';
class MissionsSlider {
constructor(el) {
this.el = el
this.dom()
}
dom() {
this.dom = {
text: [...this.el.querySelectorAll('.missions__content')],
sliderContainer: this.el.querySelector('.missions__slider'),
prevArrow: this.el.querySelector('.js-prev'),
nextArrow: this.el.querySelector('.js-next'),
totalNumber: this.el.querySelector('.js-total-number'),
slideNumber: this.el.querySelector('.js-slide-number')
}
setTimeout(() => {
this.dom.text.forEach(paragraph => {
new SplitText(paragraph, {
type: 'lines',
linesClass: 'line line++'
})
})
const lines = [...document.querySelectorAll('.line')]
lines.forEach(line => {
new SplitText(line, {
type: 'lines',
linesClass: 'line-animated'
})
})
this.init()
}, 50)
}
init() {
this.flkty = new Flickity(this.dom.sliderContainer, {
cellAlign: 'left',
draggable: false,
pageDots: false,
prevNextButtons: false,
selectedAttraction: 0.06,
friction: 1.005,
wrapAround: true
})
this.tweakDom()
this.initEvents()
}
tweakDom() {
// Create span for numbers of slides
this.flkty.cells.forEach((cell, index) => {
const span = document.createElement('span')
span.innerHTML = `${index + 1}`
this.dom.slideNumber.appendChild(span)
})
this.dom.numbers = this.dom.slideNumber.querySelectorAll('span')
// Set total count of slides
this.dom.totalNumber.innerHTML = `- ${this.flkty.cells.length.toString()}`
// Show texts for first slide
TweenLite.set(this.dom.text[0].querySelectorAll('.line-animated'), { y: 0 });
TweenLite.set(this.dom.slideNumber.querySelector('span'), { y: 0 });
}
initEvents() {
this.dom.prevArrow.addEventListener('click', () => {
if (this._isSliding) return;
this._slideTo(-1);
})
this.dom.nextArrow.addEventListener('click', () => {
if (this._isSliding) return;
this._slideTo(1);
})
}
_slideTo(direction) {
const selectedIndex = this.flkty.selectedIndex;
const nextIndex = mod(selectedIndex + direction, this.dom.text.length);
const currentLines = [...this.dom.text[selectedIndex].querySelectorAll('.line-animated')];
const nextLines = [...this.dom.text[nextIndex].querySelectorAll('.line-animated')];
this._isSliding = true;
direction === 1 ? this.flkty.next(true, false) : this.flkty.previous(true, false);
let timeline = new TimelineLite({ onComplete: () => { this._isSliding = false } });
timeline.staggerFromTo(currentLines, 0.6, { y: '0%' }, { y: '-100%', ease: Power4.easeIn }, 0.15, 0);
timeline.staggerFromTo(nextLines, 0.6, { y: '100%' }, { y: '0%', ease: Power4.easeOut }, 0.15, 0.7);
timeline.fromTo(this.dom.numbers[selectedIndex], 0.6, { y: '0%' }, { y: '-100%', ease: Power4.easeIn }, 0);
timeline.fromTo(this.dom.numbers[nextIndex], 0.6, { y: '100%' }, { y: '0%', ease: Power4.easeOut }, 0.8);
}
}
export default MissionsSlider
<template>
<section class="missions" data-component="missions-slider">
<span class="missions__subtitle show-on-mobile">{{ data.heading }}</span>
<div class="missions__controls missions__container">
<div class="missions__count">
<div class="missions__numbers">
<div class="js-slide-number"></div>
<span class="js-total-number">-</span>
</div>
<span class="missions__subtitle hide-on-mobile">{{ data.heading }}</span>
</div>
<div class="missions__arrows">
{% include "components/round-button.twig" with { color: 'white', direction: 'left', class: 'js-prev' } %}
{% include "components/round-button.twig" with { color: 'white', direction: 'right', class: 'js-next' } %}
{# <div class="arrow arrow--reverse js-prev">
<div class="arrow-circle" style="background-image: url({{ theme.path }}/assets/img/icons/arrow-green.svg)"></div>
</div>
<div class="arrow js-next">
<div class="arrow-circle" style="background-image: url({{ theme.path }}/assets/img/icons/arrow-green.svg)"></div>
</div> #}
</div>
</div>
<div class="missions__slider">
{% for item in data.slide %}
<div class="missions__slide">
<h2 class="missions__title">{{ item.title }}</h2>
</div>
{% endfor %}
</div>
<div class="missions__content-container">
{% for item in data.slide %}
<p class="missions__content">{{ item.description }}</p>
{% endfor %}
</div>
</section>
<template/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment