JSFiddle - React, Tailwind, and code Playground

by dmosher

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.1.7/underscore-min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.5.3/backbone-min.js"></script>
<div id="slideshow">
    <ul class="slides"></ul>
    <ul class="controls">
        <li class="slide-control toggle-play-pause icon">&nbsp;</li>
    </ul>
    <span class="toggler icon"></span>
</div>

CSS

.icon {
    background-image: url(http://davemo.com/jsfiddle/slideshow/icons-v.png);
    background-repeat: no-repeat;
}

#slideshow {
    height: 150px;
    border: 1px solid #ccc;
    position: relative;
    width: 750px;
}

#slideshow.collapsed {
    height: 20px;
    border: none;
}

.slides {
    overflow: hidden;
}

.slide {
    height: 150px;
    position: relative;
    display: none; /** slides are hidden by default **/
}

.slide.right {
    background-position: right !important;
}

.slide.left {
    background-position: left !important;
}

.slide .headline {
    font-size: xx-large;
    font-weight: bold;
}

.slide .caption {
    color: #999;
}

.slide .headline,
.slide .caption {
    position: absolute;
}

.slide.right .headline {
    top: 30px;
    left: 30px;
}

.slide.right .caption {
    left: 30px;
    top: 70px;
}

.slide.left .headline {
    top: 30px;
    right: 30px;
}

.slide.left .caption {
    top: 70px;
    right: 30px;
}

#slideshow .toggler {
    display: block;
    height: 19px;
    width: 19px;
    background-color: white;
    background-position: 0 -493px;
    border: 1px solid #CCCCCC;
    bottom: -1px;
    color: black;
    position: absolute;
    right: -1px;
}

#slideshow.collapsed .toggler {
    right: 0;
    bottom: 0;
    background-position: 0 -438px;
}

#slideshow .controls {
    position: absolute;
    bottom: -1px;
    left: -1px;
}

#slideshow.collapsed .controls {
    display: none;
}

#slideshow .toggler:hover,
.slide-control:hover,
.jump-to.current {
    cursor: pointer;
    background-color: #333;
    color: white;
}

.toggle-play-pause {
    background-position: 0 -527px;
}

.toggle-play-pause.playing {
    background-position: 0 -509px;
}

.slide-control {
    display: inline-block;
    width: 20px;
    height: 17px;
    padding-top: 3px;
    text-align: center;
    margin-right: 2px;
    border: 1px solid #ccc;
    background-color: white;
}

JavaScript

// configuration for underscores template syntax
_.templateSettings = {
    interpolate: /\{\{(.+?)\}\}/g
};

// app namespace setup
APP = {
    Views: {},
    Models: {},
    Collections: {}
};

// a simple slide model
APP.Models.Slide = Backbone.Model.extend({
    defaults: {
        id: 1,
        headline: 'Welcome to APP',
        caption: 'This is an awesome slide',
        layout: 'right'
    },

    show: function() {
        this.getEl().show();
    },

    getEl: function() {
        return $('#slide-' + this.id);
    },

    getControl: function() {
        return $('.jump-to').eq(this.id - 1);
    }
});

// and a simple collection that holds slides
APP.Collections.Slides = Backbone.Collection.extend({
    model: APP.Models.Slide
});

// the meat of the logic, defines the slideshow, hooks into existing dom elements representing slides and controls
// handles events and timing, play, pause, jumpto
APP.Views.Slideshow = Backbone.View.extend({

    el: '#slideshow',
    slides: '#slideshow .slides',
    controls: '#slideshow .controls',
    playPauseControl: '#slideshow .controls .toggle-play-pause',

    delay: 10000,
    currentIndex: 0,

    events: {
        'click .toggler': 'toggleVisibility',
        'click .toggle-play-pause': 'togglePlayPause',
        'click .jump-to': 'jumpTo'
    },

    slideTemplate: _.template('<li id="slide-{{ id }}" class="slide {{ layout }}" style="background: url(http://davemo.com/jsfiddle/slideshow/{{ id }}.jpg) no-repeat;">' + '<p class="headline">{{ headline }}</p>' + '<p class="caption">{{ caption }}</p>' + '</li>'),

    controlTemplate: _.template('<li class="slide-control jump-to" data-index="{{ index }}">{{ human_readable_index }}</li>'),

    initialize: function() {
        _.bindAll(this, 'render', 'rotateSlides', 'togglePlayPause', 'play', 'pause', 'initialPlay', 'transition', 'jumpTo');
    },

    render: function() {
        var self = this;
        this.collection.each(function(slide, i) {
           ...