Created
September 1, 2015 15:43
-
-
Save mattkelley/678e93a3b0615fc07f34 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Carousel = (function(){ | |
// faux jquery object | |
// mostly based on http://youmightnotneedjquery.com/ | |
var jq = function (el) { | |
var self = {0: el, el: el}; | |
self.findChild = function (selector) { | |
var results = el.querySelectorAll(selector); | |
if (results.length > 0) { | |
return jq(results[0]); | |
} else { | |
return undefined; | |
} | |
}; | |
self.children = function () { | |
return _.map(el.children, function (child) { | |
return jq(child); | |
}); | |
}; | |
self.first = function () { | |
if (el.children.length > 0) { | |
return jq(el.children[0]); | |
} else { | |
return undefined; | |
} | |
}; | |
self.getStyle = function (ruleName) { | |
return getComputedStyle(el)[ruleName]; | |
}; | |
self.setStyle = function (ruleName, value) { | |
el.style[ruleName] = value; | |
}; | |
self.click = function (callback) { | |
el.onclick = callback; | |
}; | |
self.addClass = function (className) { | |
if (el.classList) | |
el.classList.add(className); | |
else | |
el.className += ' ' + className; | |
}; | |
self.removeClass = function (className) { | |
if (el.classList) | |
el.classList.remove(className); | |
else | |
el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); | |
}; | |
return self; | |
}; | |
var Carousel = { | |
cache: {} | |
}; | |
Carousel.move = function (elementId, slideNumber, skipAnimation) { | |
if (Carousel.cache[elementId]) { | |
Carousel.cache[elementId].move(slideNumber, skipAnimation); | |
} | |
}; | |
Carousel.create = function (elementId) { | |
var self = {}; | |
var element = document.getElementById(elementId), | |
$carousel = jq(element); | |
var $viewport = $carousel.findChild('.viewport'), | |
$overview = $carousel.findChild('.slider'), | |
slides = null, | |
$next = $carousel.findChild('.next'), | |
$prev = $carousel.findChild('.prev'), | |
viewportSize = 0, | |
slidesVisible = 0, | |
slideSize = 0, | |
slideIndex = 0, | |
posiLabel = 'left', | |
sizeLabel = 'width'; | |
self.slideCurrent = 0; | |
self.slidesTotal = 0; | |
var init = function () { | |
self.update(); | |
self.move(self.slideCurrent); | |
_setEvents(); | |
Carousel.cache[elementId] = self; | |
return self; | |
}; | |
// setup | |
self.update = function() { | |
slides = $overview.children(); | |
viewportSize = $viewport.el.offsetWidth; | |
slideSize = slides[0].el.offsetWidth; | |
self.slidesTotal = slides.length; | |
self.slideCurrent = 0; | |
slidesVisible = Math.ceil(viewportSize / slideSize); | |
$overview.setStyle(sizeLabel, slideSize * self.slidesTotal + 'px'); | |
_setButtons(); | |
}; | |
var _setEvents = function () { | |
// button events | |
$prev.click(function() { | |
self.move(--slideIndex); | |
return false; | |
}); | |
$next.click(function() { | |
self.move(++slideIndex); | |
return false; | |
}); | |
var indicators = $carousel.findChild('.carousel-indicators').children(); | |
_.each(indicators, function ($indicator, key) { | |
$indicator.click(function () { | |
self.move(slideIndex = key); | |
}); | |
}); | |
}; | |
// move to a specific slide | |
self.move = function(index, instant) { | |
slideIndex = isNaN(index) ? self.slideCurrent : index; | |
self.slideCurrent = slideIndex % self.slidesTotal; | |
// if some how slideIndex goes out of bounds | |
if(slideIndex < 0) { | |
self.slideCurrent = slideIndex = self.slidesTotal - 1; | |
$overview.setStyle(posiLabel, -(self.slidesTotal) * slideSize); | |
} | |
if(slideIndex > self.slidesTotal) { | |
self.slideCurrent = slideIndex = 1; | |
$overview.setStyle(posiLabel, 0); | |
} | |
if (instant) { | |
// instantly change slide position | |
$overview.addClass('skipanimation'); | |
} else { | |
$overview.removeClass('skipanimation'); | |
} | |
// start animation | |
var newXPos = -1 * self.slideCurrent * viewportSize; | |
$overview.setStyle('transform', 'translate3d(' + newXPos + 'px, 0px, 0px)'); | |
$overview.setStyle('-webkit-transform', 'translate3d(' + newXPos + 'px, 0px, 0px)'); | |
$overview.setStyle('-ms-transform', 'translateX(' + newXPos + 'px)'); | |
_setButtons(); | |
}; | |
// update buttons (disable if at end or beginning of slides) | |
var _setButtons = function () { | |
if (self.slideCurrent <= 0) { | |
$prev.addClass('disable'); | |
} else { | |
$prev.removeClass('disable') | |
} | |
if (self.slideCurrent >= self.slidesTotal - slidesVisible) { | |
$next.addClass('disable'); | |
} else { | |
$next.removeClass('disable'); | |
} | |
var indicators = $carousel.findChild('.carousel-indicators').children(); | |
_.each(indicators, function ($indicator) { | |
$indicator.removeClass('active'); | |
}); | |
indicators[self.slideCurrent].addClass('active'); | |
}; | |
return init(); | |
}; | |
return Carousel; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment