nathanjchapman/scripts/carousel.js
2021-12-13 10:13:26 -07:00

111 lines
3.4 KiB
JavaScript

export default class Carousel {
constructor (element) {
this.element = element;
this.itemClassName = 'carousel__photo';
this.items = this.element.querySelectorAll(`.${this.itemClassName}`);
this.totalItems = this.items.length;
this.slide = 0;
this.moving = true;
this.start();
}
setInitialClasses () {
this.items[0].classList.add('active');
this.items[1].classList.add('next');
}
attachEventListeners () {
const next = this.element.querySelector('.carousel__button--next');
const prev = this.element.querySelector('.carousel__button--prev');
next.addEventListener('click', this.moveNext.bind(this));
prev.addEventListener('click', this.movePrev.bind(this));
}
moveCarouselTo (slide) {
// Check if carousel is moving, if not, allow interaction
if (!this.moving) {
// temporarily disable interactivity
this.disableInteraction();
// Update the 'old' adjacent slides with 'new' ones
let newPrevious = slide - 1,
newNext = slide + 1,
oldPrevious = slide - 2,
oldNext = slide + 2;
// Test if carousel has more than three items
if ((this.totalItems - 1) > 2) {
// Checks and updates if the new slides are out of bounds
if (newPrevious <= 0) {
oldPrevious = (this.totalItems - 1);
} else if (newNext >= (this.totalItems - 1)) {
oldNext = 0;
}
// Checks and updates if slide is at the beginning/end
if (slide === 0) {
newPrevious = (this.totalItems - 1);
oldPrevious = (this.totalItems - 2);
oldNext = (slide + 1);
} else if (slide === (this.totalItems - 1)) {
newPrevious = (slide - 1);
newNext = 0;
oldNext = 1;
}
// Now we've worked out where we are and where we're going,
// by adding/removing classes we'll trigger the transitions.
// Reset old next/prev elements to default classes
this.items[oldPrevious].className = this.itemClassName;
this.items[oldNext].className = this.itemClassName; // Add new classes
this.items[newPrevious].className = this.itemClassName + ' prev';
this.items[slide].className = this.itemClassName + ' active';
this.items[newNext].className = this.itemClassName + ' next';
}
}
}
moveNext () {
// Check if moving
if (!this.moving) {
// If it's the last slide, reset to 0, else +1
if (this.slide === (this.totalItems - 1)) {
this.slide = 0;
} else {
this.slide++;
}
// Move carousel to updated slide
this.moveCarouselTo(this.slide);
}
}
movePrev () {
// Check if moving
if (!this.moving) {
// If it's the first slide, set as the last slide, else -1
if (this.slide === 0) {
this.slide = (this.totalItems - 1);
} else {
this.slide--;
}
// Move carousel to updated slide
this.moveCarouselTo(this.slide);
}
}
disableInteraction () {
// Set 'moving' to true for the same duration as our transition.
// (0.5s = 500ms)
this.moving = true;
// setTimeout runs its function once after the given time
setTimeout(() => {
this.moving = false
}, 500);
}
start () {
this.setInitialClasses();
this.attachEventListeners();
// Set moving to false so that the carousel becomes interactive
this.moving = false;
}
}