Skip to content

Instantly share code, notes, and snippets.

@awps
Created Aug 17, 2018
Embed
What would you like to do?
import Util from './util'
import Swipe from './swipe'
class Slider {
constructor( slider_el, options = {} ) {
// Default options
this.opt = {
inactiveClass: 'inactive-slide',
speed: 5000,
startAt: 0,
}
// Extend default options
this.opt = Object.assign( this.opt, options )
// Fix the slider speed if the user enters a low value.
if ( this.opt.speed < 100 ) {
this.opt.speed = this.opt.speed * 1000
}
// Set the slider container(direct parent of slides)
this._slider = slider_el
// Have a slider on this page?
if ( !this._slider ) {
return
}
// Setup the variables
this._slider_wrapper = this._slider.parentNode
this._slides = this._slider.children
this._total = this._slides.length
this._current_slide = this.opt.startAt
this._prev_arrow = null
this._next_arrow = null
this._interval = null
// Build the slider
this.makeAllInactive()
this.setCurrentActive()
this.addArrow( 'prev' )
this.addArrow( 'next' )
this.setArrowBg()
this.createEvents()
this.createTouchEvents()
this.start()
}
start() {
this._interval = setInterval( () => {
this.updateCurrent()
this.makeAllInactive()
this.setCurrentActive()
this.setArrowBg()
}, this.opt.speed )
}
stop() {
clearInterval( this._interval )
}
restart() {
this.stop()
this.start()
}
createEvents() {
this._prev_arrow.addEventListener( 'click', () => {
this.goToPrevSlide()
} )
this._next_arrow.addEventListener( 'click', () => {
this.goToNextSlide()
} )
document.addEventListener( 'visibilitychange', () => {
if ( document.hidden ) {
this.stop()
}
else {
this.start()
}
}, false )
}
createTouchEvents() {
let swipe = new Swipe( this._slider )
swipe.onLeft( () => {
this.goToNextSlide()
} )
swipe.onRight( () => {
this.goToPrevSlide()
} )
}
addArrow( dir ) {
let arrow = document.createElement( 'div' )
Util.addClass( arrow, 'slider-arrow' )
Util.addClass( arrow, 'slider-arrow--' + dir )
this._slider_wrapper.appendChild( arrow )
let icon = document.createElement( 'i' )
if ( 'prev' === dir ) {
this._prev_arrow = arrow
Util.addClass( icon, 'fas' ).addClass( icon, 'fa-chevron-left' )
}
else if ( 'next' === dir ) {
this._next_arrow = arrow
Util.addClass( icon, 'fas' ).addClass( icon, 'fa-chevron-right' )
}
arrow.appendChild( icon )
}
makeAllInactive() {
for ( let slide of this._slides ) {
Util.addClass( slide, this.opt.inactiveClass )
}
}
setActive( slide_index ) {
this.makeAllInactive()
Util.removeClass( this._slides[slide_index], this.opt.inactiveClass )
}
setCurrentActive() {
this.setActive( this._current_slide )
}
setArrowBg() {
Util.addClass( this._next_arrow, 'arrow-hide-right' )
Util.addClass( this._prev_arrow, 'arrow-hide-left' )
this._next_arrow.style.backgroundImage = 'url(' + this.getNextSlideImage() + ')'
this._prev_arrow.style.backgroundImage = 'url(' + this.getPrevSlideImage() + ')'
Util.removeClass( this._next_arrow, 'arrow-hide-right' )
Util.removeClass( this._prev_arrow, 'arrow-hide-left' )
}
goToPrevSlide() {
this.setActive( this.getPrevSlideIndex() )
this.updateCurrent()
this.setArrowBg()
this.restart()
}
goToNextSlide() {
this.setActive( this.getNextSlideIndex() )
this.updateCurrent()
this.setArrowBg()
this.restart()
}
updateCurrent() {
this._current_slide++
if ( this._current_slide >= this._total ) {
this._current_slide = 0
}
}
getNextSlideIndex() {
if ( this._current_slide + 1 >= this._total ) {
return 0
}
return this._current_slide + 1
}
getPrevSlideIndex() {
if ( this._current_slide - 1 < 0 ) {
return this._total - 1
}
return this._current_slide - 1
}
getNextSlideImage() {
let index = this.getNextSlideIndex()
return this._slides[index].getAttribute( 'data-slide-image' )
}
getPrevSlideImage() {
let index = this.getPrevSlideIndex()
return this._slides[index].getAttribute( 'data-slide-image' )
}
}
export default Slider
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment