Created
September 24, 2012 17:48
-
-
Save perrupa/3777267 to your computer and use it in GitHub Desktop.
Song Carousel
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 Song = Backbone.Model.extend({ | |
defaults : { | |
selected : false, | |
active : false | |
}, | |
initialize : function(attributes) { | |
this.set("uniqueID", this.cid); | |
if(!this.get("voted")) { | |
this.set({"voted" : this.defaults.voted}); | |
} | |
} | |
}); | |
var SongCollection = Backbone.Collection.extend({ | |
Model : Song, | |
currentIndex : 0, | |
displayedSize : 5, | |
getCurrentSongs : function() { | |
var songs = this.toArray(), | |
interval = Math.floor(this.displayedSize / 2), | |
self = this; | |
// return songs.slice(this.currentIndex, this.currentIndex + this.displayedSize); | |
var range = _.range(this.currentIndex - interval, this.currentIndex + interval + 1); | |
var currentSongs = _.map(range, function(i) { | |
return self.getSongAt(i); | |
}); | |
return currentSongs; | |
}, | |
getCurrentSong : function() { | |
//return this.at(this.currentIndex + Math.floor(this.displayedSize / 2)); | |
return this.at(this.currentIndex); | |
}, | |
getPrevious : function() { | |
var interval = Math.floor(this.displayedSize / 2), | |
index = this.currentIndex - 1,//interval, | |
song = this.getSongAt(index); | |
return song; | |
}, | |
getNext : function() { | |
var interval = Math.floor(this.displayedSize / 2), | |
index = this.currentIndex + 1,// interval, | |
song = this.getSongAt(index); | |
return song; | |
}, | |
getSongAt : function(index) { | |
if(index > this.length - 1 || index < 0) | |
return {}; | |
else | |
return this.at(index); | |
}, | |
forward : function() { | |
if(this.currentIndex >= this.length) return this; | |
this.at(this.currentIndex).set("selected", false); | |
this.at(this.currentIndex).set("active", false); | |
this.currentIndex++; | |
this.at(this.currentIndex).set("selected", true); | |
return this; | |
}, | |
backward : function() { | |
if(this.currentIndex === 0) return this; | |
this.at(this.currentIndex).set("selected", false); | |
this.at(this.currentIndex).set("active", false); | |
this.currentIndex--; | |
this.at(this.currentIndex).set("selected", true); | |
return this; | |
} | |
}); | |
var SongView = Backbone.View.extend({ | |
events : { | |
"click em" : "authorClick", | |
"click .playBtn" : "openPlayer" | |
}, | |
// template : Handlebars.compile($("#songTemplate").html()), | |
// template : Handlebars.compile($("#smallSongTemplate").html()), | |
template : Handlebars.compile($("#largeSongTemplate").html()), | |
// songPlayerTemplate : Handlebars.compile($("#songPlayerTemplate").html()), | |
initialize : function() { | |
// _.bindAll(this, 'render', 'authorClick', 'openPlayer', 'test'); | |
//this.model.bind('change', this.render, this); | |
//this.model.bind('destroy', this.remove, this); | |
}, | |
render : function() { | |
//this.model.view = this; | |
this.$el.html(this.template(this.model.toJSON())).addClass("song"); | |
if(this.model.get("selected")) { | |
this.$el.addClass("selected"); | |
createJplayer($("#"+this.model.cid), this.model.get("song_path"), "#jPlayerControls") | |
} else { | |
this.$el.removeClass("selected"); | |
} | |
this.delegateEvents(this.events); | |
return this; | |
}, | |
openPlayer : function() { | |
this.model.set("active", true); | |
this.render(); | |
var $target = $("#"+this.model.cid); | |
createJplayer($target, this.model.get("song_path"), "#jPlayerControls"); | |
}, | |
authorClick : function() { | |
alert(this.model.get("composer")); | |
} | |
}); | |
var App = Backbone.View.extend({ | |
events : { | |
"click .forward" : "forward", | |
"click .backward" : "backward" | |
}, | |
initialize : function() { | |
_.bindAll(this, 'render', 'forward', 'backward'); | |
var self = this; | |
this.collection.each(function(song) { | |
if(!self.songViews.hasOwnProperty(song.cid)) { | |
self.songViews[song.cid] = new SongView({model : song}); | |
} | |
}); | |
this.render(); | |
}, | |
songContainerTemplate : Handlebars.compile($("#songContainerTemplate").html()), | |
songTemplate : Handlebars.compile($("#smallSongTemplate").html()), | |
songViews : {}, | |
render : function() { | |
var self = this, | |
songs = this.collection.getCurrentSongs(), | |
$songContainer = self.$el.find(".songContainer"); | |
// var songs = [].concat(this.collection.getPrevious(), this.collection.getCurrentSongs(), this.collection.getNext()); | |
$songContainer.empty().transition({x : 0}, 0); | |
_.each(songs, function(song) { | |
var view; | |
if(song.hasOwnProperty("cid")) { | |
//song.createView(); | |
song.set("selected", song.cid == self.collection.getCurrentSong().cid) | |
view = self.songViews[song.cid].render().$el; | |
} else { | |
view = $("<div/>").html(self.songTemplate(song)).addClass("song"); | |
} | |
$(view).detach(); | |
$songContainer.append(view); | |
}); | |
//this.collection.getCurrentSong().view.$el.addClass("selected"); | |
return this; | |
}, | |
destroyJPlayer : function(cid){ | |
var selector = "#"+cid; | |
if(this.$el.find(selector)){ | |
$(selector).jPlayer("destroy"); | |
} | |
}, | |
addWrappingSongs : function() { | |
var $songContainer = this.$el.find(".songContainer"); | |
//Adding a song to both ends so that "text-align: center" doesn't throw the layout off. | |
var nextSong = this.collection.getNext(), | |
prevSong = this.collection.getPrevious(), | |
emptySong = $("<div></div>").addClass("song"); | |
this.songViews[nextSong.cid] | |
var nextSongView = this.songViews.hasOwnProperty(nextSong.cid) ? this.songViews[nextSong.cid].render().$el : emptySong, | |
prevSongView = this.songViews.hasOwnProperty(prevSong.cid) ? this.songViews[prevSong.cid].render().$el : emptySong; | |
$songContainer | |
.append(nextSongView) | |
.prepend(prevSongView); | |
}, | |
forward : function(e) { | |
e.preventDefault(); | |
this.destroyJPlayer(this.collection.getCurrentSong().cid); | |
var self = this, | |
width = this.$el.find(".song").width(), | |
$songContainer = self.$el.find(".songContainer"), | |
next = this.collection.getNext(); | |
if(next.cid === undefined) { | |
$songContainer.transition({x : "-2%"}, function() { | |
$(this).transition({x : "0%"}); | |
}) | |
return this; | |
} | |
// this.$el.find(".selected").transition({scale : 0.5, y : "-30%", opacity : 0.5}); | |
this.addWrappingSongs(); | |
//handle shrinking the main guy here. | |
//shift list to the left | |
$songContainer.transition({x : -width}, 700, function() { | |
self.collection.forward(); | |
// self.$el.find(".song").transition({scale : 1, y : "0", opacity : 1}, 0); | |
//rerender, because our animation is done. | |
self.render(); | |
}); | |
return this; | |
}, | |
backward : function(e) { | |
e.preventDefault(); | |
this.destroyJPlayer(this.collection.getCurrentSong().cid); | |
var self = this, | |
width = this.$el.find(".song").width(), | |
$songContainer = self.$el.find(".songContainer"), | |
prev = this.collection.getPrevious(); | |
if(prev.cid === undefined) { | |
$songContainer.transition({x : "2%"}, function() { | |
$(this).transition({x : "0%"}); | |
}) | |
return this; | |
} | |
var oldSelected = this.$el.find(".selected"); | |
//oldSelected.prev().transition({scale:1.333,y:"0%"}); | |
// oldSelected.transition({scale : 0.5, y : "-30%", opacity : 0.5}); | |
this.addWrappingSongs(); | |
//handle shrinking the main guy here. | |
//shift list to the right | |
$songContainer.transition({x : width}, 700, function() { | |
self.collection.backward(); | |
// self.$el.find(".song").transition({scale : 1, y : "0", opacity : 1}, 0); | |
//rerender, because our animation is done. | |
self.render(); | |
}); | |
return this; | |
} | |
}); | |
// DOM is ready... | |
$(function() { | |
$(".navLink").click(function(e) { | |
e.preventDefault(); | |
var $chosenArea = $($(this).attr('data-reveal')), | |
wasClosed = !$chosenArea.is(":visible"), | |
$self = $(this), | |
visibleNoteAreas = $(".upperNoteArea:visible"), | |
showArea = function($link) { | |
($link || $("div")).addClass("active"); | |
$chosenArea.slideDown(300); | |
}; | |
$(".headerArea .navLink").removeClass("active"); | |
visibleNoteAreas.slideUp(300, function() { | |
if(wasClosed) { | |
showArea($self); | |
} | |
}); | |
if(wasClosed) { | |
showArea($self); | |
} | |
}); | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment