Skip to content

Instantly share code, notes, and snippets.

@kwhitaker
Created December 3, 2014 19:29
Show Gist options
  • Save kwhitaker/957252ade8e8ea617fc8 to your computer and use it in GitHub Desktop.
Save kwhitaker/957252ade8e8ea617fc8 to your computer and use it in GitHub Desktop.
Slideshow/carousel plugin for jQuery
###
Multi-item carousel.
Written by Kevin Whitaker
Apply to a div to create a carousel out of a contained UL.
Animation is handled by CSS.
HTML structure looks like this:
<div id="#some-id">
<div class="carousel-wrap">
<ul class="carousel-list">
<li class="carousel-item">Some content</li>
</ul>
</div>
</div>
Execute it with $('#some-id').docCarousel();
###
(($, window, document, undefined_) ->
DocCarousel = (element, options) ->
# jQuery boilerplate
@options = $.extend({}, defaults, options)
# DOM Stuff we need before we build the carousel
@el = $ element
@wrap = @el.find '> .carousel-wrap'
@list = @el.find 'ul'
items = @list.find '> li'
@childCount = items.length
@childWidth = items.first().outerWidth true
@list.width "#{parseInt(@childCount * @childWidth)}px"
# jQuery boilerplate
@_defaults = defaults
@_name = pluginName
@init() #init the plugin
return
pluginName = "docCarousel"
defaults = {}
DocCarousel:: =
# Set up the carousel
init: ->
# Don't generate a carousel if we don't need the scrolling
unless @list.outerWidth() <= @wrap.outerWidth()
@currentTarget = 0
# Append nav buttons
@el.append '<a href="#" class="carousel-nav" data-toggle="prev">&#9664;</a>'
@el.append '<a href="#" class="carousel-nav" data-toggle="next">&#9654;</a>'
# Handler for nav click
@el.find('.carousel-nav').on 'click', (e) =>
@handleOnClick e
# Teardown the carousel
destroy: ->
@el.find('.carousel-nav').off 'click', (e) =>
@handleOnClick e
$.DocCarousel.prototype.destroy.call this
# Navigation click handler
handleOnClick: (e) ->
e.preventDefault()
btn = $ e.currentTarget
direction = btn.data 'toggle'
switch direction
when 'prev'
if @currentTarget is 0
@slideTo @childCount - 1
else
@slideTo @currentTarget - 1
else
if @currentTarget is @childCount - 1
@slideTo 0
else
# Do some math to see if we need to slide, because we could
# be seeing all available items already.
elWidth = @el.outerWidth()
maxVisible = Math.floor elWidth / @childWidth
if @childCount - maxVisible < @currentTarget + 1
target = 0
else
target = @currentTarget + 1
@slideTo target
# Calculate where to slide, and change the CSS.
# Animation is handled in the CSS
slideTo: (target) ->
numToGo = Math.abs target - @currentTarget
direction = if @currentTarget > target then 1 else -1
currentPos = -1 * @currentTarget * @childWidth
newPos = (currentPos + direction * @childWidth * numToGo) + 'px'
@list.css left: newPos
@currentTarget = target
return
# jQuery boilerplate for exporting the plugin
$.fn[pluginName] = (options) ->
@each ->
unless $.data(this, "docCarousel_" + pluginName)
$.data this, "docCarousel_" + pluginName, new DocCarousel(this, options)
return
return
) jQuery, window, document
<div id="#carousel">
<div class="carousel-wrap">
<ul class="carousel-list">
<li class="carousel-item">Some content...</li>
<li class="carousel-item">Some content...</li>
<li class="carousel-item">Some content...</li>
</ul>
</div>
</div>
/* Document Carousel */
.carousel-wrap
position: relative
width: 100%
overflow: hidden
top: auto
ul.carousel-list
position: absolute
left: 0
margin: 0
padding: 0 0 0 10px
list-style: none
+clearfix
+transition-property(all)
+transition-duration(0.25s)
+transition-timing-function(ease-in)
li.carousel-item
position: relative
cursor: pointer
margin: 0 10px
padding: 10px
float: left
.carousel-nav
position: absolute
top: 0
height: 100%
width: 30px
padding: $pad
line-height: 6.5em
color: #666
background-color: white
z-index: 5
+transition-property(all)
+transition-duration(0.25s)
&:hover
color: cornflowerblue
&[data-toggle="prev"]
left: 0
&[data-toggle="next"]
right: 0
// FIXME Wonkiness to deal with spacing
width: 35px
@kwhitaker
Copy link
Author

There's a lot of room for improvement/elegance in here. I might revisit as I get some more time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment