Created
May 18, 2012 14:57
-
-
Save flukeout/2725711 to your computer and use it in GitHub Desktop.
Blam
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
!function($,window,undefined){ | |
var AdvancedFader = WidgetBaseView.extend({ | |
name : 'Advanced Message Fader', | |
setup : function(options){ | |
WidgetBaseView.prototype.setup.call(this); | |
this.div = $('<div class="AdvancedFader"></div>'); | |
this.$el.append(this.div); | |
this.adjust(_.extend({ | |
handleColor : "white", | |
bodyColor : "white", | |
showHandle : true, | |
top : 100, | |
left : 100, | |
width : 800, | |
height: 200, | |
bodyFontSize : 100, | |
senderFontSize : 100, | |
showDuration : 2000, | |
pauseDuration : 100 | |
},options)); | |
}, | |
load : function(){ | |
this.box = new messageBox(this); | |
this.box.setOptions(this.serialize()); | |
this.box.init(); | |
}, | |
start : function(){ | |
this.div.trigger('start'); | |
}, | |
pause : function(){ | |
this.div.trigger('pause'); | |
}, | |
getMessage : function(){ | |
if(!this._madeEditable){ | |
return WidgetBaseView.prototype.getMessage.call(this) || {sender:"",body:""}; | |
} | |
return {body: "Like Butter, Man! Like Butter, Man! Like Butter", sender : "@flukeout"}; | |
// if(this._madeEditable){ | |
// return "Like Butter, Man! Like Butter, Man! Like Butter, Man! Like Butter, Man! Like Butter, Man! "; | |
// return {body:"Like Butter, Man! Like Butter, Man! Like Butter, Man! Like Butter, Man! Like Butter, Man! " }; | |
// } else { | |
// return WidgetBaseView.prototype.getMessage.call(this); | |
// return {body: "Like Butter, Man! Like Butter, Man! Like Butter, Man! Like Butter, Man! Like Butter, Man!"}; | |
// } | |
}, | |
adjust : function(options){ | |
options.bodyColor && this.$el.data("bodyColor" , options.bodyColor); | |
options.handleColor && this.$el.data("handleColor" , options.handleColor); | |
options.showHandle && this.$el.data("showHandle" , options.showHandle); | |
options.top !== undefined && this.$el.css("top" , parseInt(options.top,10) + 'px'); | |
options.left !== undefined && this.$el.css("left" , parseInt(options.left,10) + 'px'); | |
options.width !== undefined && this.$el.css("width",options.width) | |
options.height !== undefined && this.$el.css("height",options.height); | |
options.animationType !== undefined && this.$el.data("animationType", parseInt(options.animationType,10)); | |
options.senderFontSize !== undefined && this.$el.data("senderFontSize", parseInt(options.senderFontSize,10)); | |
options.bodyFontSize !== undefined && this.$el.data("bodyFontSize", parseInt(options.bodyFontSize,10)); | |
options.showDuration !== undefined && this.$el.data("showDuration", parseInt(options.showDuration,10) ); | |
options.pauseDuration !== undefined && this.$el.data("pauseDuration", parseInt(options.pauseDuration,10) ); | |
options.channels !== undefined && this.$el.data("channels", options.channels); | |
WidgetBaseView.prototype.adjust.call(this,options); | |
this.box && this.box.setOptions(options); | |
}, | |
serialize : function(){ | |
return _.extend({ | |
animationType : this.$el.data("animationType"), | |
handleColor : this.$el.data("handleColor"), | |
showHandle : this.$el.data("showHandle"), | |
bodyColor : this.$el.data("bodyColor"), | |
top : this.$el.css("top"), | |
left : this.$el.css("left"), | |
width : this.$el.css("width"), | |
height : this.$el.css("height"), | |
bodyFontSize : this.$el.data("bodyFontSize"), | |
senderFontSize : this.$el.data("senderFontSize"), | |
showDuration : this.$el.data('showDuration'), | |
pauseDuration : this.$el.data('pauseDuration'), | |
channels : this.$el.data('channels') | |
},WidgetBaseView.prototype.serialize.call(this)); | |
}, | |
widgetChannels : function(){ | |
return this._widgetChannels = this._widgetChannels || _(this.serialize().channels).map(function(channel){ | |
return new MessageChannel({channel_description:channel}); | |
}); | |
}, | |
configPanel : function(){ | |
var items = [ | |
new SelectConfigItemView({model:this.model, label : "Animation", key: "animationType", step: 5, | |
options : [ | |
{name: "Random" , value : "random"}, | |
{name: "Bubbles" , value : "8"}, | |
{name: "Domino" , value : "11"}, | |
{name: "Fade" , value : "7"}, | |
{name: "Falling" , value : "0"}, | |
{name: "Flip" , value : "2"}, | |
{name: "Float" , value : "5"}, | |
{name: "Grow" , value : "12"}, | |
{name: "Page" , value : "9"}, | |
{name: "Pop" , value : "10"}, | |
{name: "Rain" , value : "4"}, | |
{name: "Spin" , value : "3"}, | |
{name: "Water" , value : "1"}, | |
{name: "Wave" , value : "6"}, | |
{name: "Wind" , value : "13"}] | |
}), | |
new NumberConfigItemView({model:this.model, label : "Top", key: "top", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Left", key: "left", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Width", key: "width", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Height", key: "height", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Handle Font Size", key: "senderFontSize", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Body Size", key: "bodyFontSize", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Show for", key: "showDuration", step: 5}), | |
new NumberConfigItemView({model:this.model, label : "Pause for", key: "pauseDuration", step: 5}), | |
new ColorConfigItemView( {model:this.model, label : "Handle Color", key: "handleColor"}), | |
new ColorConfigItemView( {model:this.model, label : "Body Color", key: "bodyColor"}), | |
new ButtonsConfigItemView({model:this.model, label: "Show Handle", key: "showHandle", | |
options : [{value : true , label: "Show"}, | |
{value : false , label: "Hide"}] | |
}), | |
new ListConfigItemView( {model:this.model, label : "Channels", key:"channels", | |
item : function(value) { | |
return new TextConfigItemView({model:this.model, label : "Channel Description", key: this.key+'[]', value:value}) | |
} | |
}) | |
]; | |
retDiv = $('<div />'); | |
for(var i=0,iLen = items.length;i<iLen;i++){ | |
retDiv.append(items[i].$el); | |
items[i].setup(); | |
} | |
return retDiv.children(); | |
} | |
}); | |
WidgetViewFactory.register('advanced_fader',AdvancedFader); | |
function messageBox(w) { | |
var messageBox = { | |
widget: w, | |
messageContainer : w.div, | |
time : 0, | |
animation : "", | |
state : "", | |
messageLength : 0, | |
lettersArray : [], | |
letterIndex : 0, | |
letterDelay : 0, // Duration between each letter animation | |
getDelay : 100, | |
running : 0, | |
options : { | |
top : 0, | |
handleColor : "", | |
bodyColor : "", | |
left : 0, | |
width : 0, | |
height : 0, | |
showHandle : true, | |
bodyFontSize : 0, | |
senderFontSize : 0, | |
showDuration : 0, | |
pauseDuration : 0, | |
animationType : 0 | |
}, | |
//Timing | |
searchTerm : "", //Placeholder for twitter query | |
customTerm : "", //User specified search term | |
// animationType Explained... | |
// terms -> the list of search terms this animation is associated with | |
// name -> the animation-name in the CSS | |
// order -> in which the letters are added to the screen | |
// origin -> the transform-origin for each letter animated | |
animationType : [ | |
{ terms : ["falling","dropping","drop","fall","down"] , name: "falling", order : "random"}, | |
{ terms : ["water","pond","liquid"] , name : "water", order : "forward"}, | |
{ terms : ["flip","flipping","backflip"] , name : "flip", order : "forward"}, | |
{ terms : ["spin","spinning"] , name : "spin", order : "forward"}, | |
{ terms : ["rain","raining"] , name : "rain", order : "random"}, | |
{ terms : ["float","floating","rising","rises","up","upwards"] , name : "rising", order : "random"}, | |
{ terms : ["wave","waving","ocean"] , name : "wave", order : "forward"}, | |
{ terms : ["fade","fading","faded"] , name : "fading", order : "forward"}, | |
{ terms : ["bubbles","bubble"] , name : "bubble", order : "forward"}, | |
{ terms : ["page"] , name : "page", order : "forward", origin: "left"}, | |
{ terms : ["pop","burst"] , name : "pop", order : "random"}, | |
{ terms : ["domino"] , name : "domino", order : "forward", origin: "bottom"}, | |
{ terms : ["grow","sprout","growing"] , name : "grow", order : "random", origin: "bottom"}, | |
{ terms : ["wind","windy"] , name: "wind", order : "random"} | |
], | |
// Placeholder for testing a single animation | |
// animationType : [ | |
// { terms : ["wind","windy"] , name: "wind", order : "random"}, | |
// ], | |
setOptions : function(new_options){ | |
this.options = $.extend({},this.options||{}, new_options); | |
}, | |
searchFor : function(term){ | |
this.customTerm = term; | |
}, | |
init : function(){ | |
this.changeState("getting"); | |
this.getMessage(); | |
this.animate(); | |
}, | |
animate : function(){ | |
this.move(); | |
running = window.webkitRequestAnimationFrame($.proxy(this.animate,this)); | |
}, | |
getMessage : function() { | |
//Sets the animation type for this message | |
console.log(this.options.animationType); | |
if(this.options.animationType == "random") { | |
this.animation = this.animationType[Math.floor((Math.random()*this.animationType.length))]; | |
} else { | |
this.animation = this.animationType[this.options.animationType]; | |
} | |
// if (this.customTerm == ""){ | |
// var numTerms = this.animation.terms.length; | |
// var termNumber = Math.floor(Math.random()*numTerms); | |
// this.searchTerm = this.animation.terms[termNumber]; | |
// | |
// } else { | |
// this.searchTerm = this.customTerm; | |
// } | |
this.lettersArray = []; | |
this.letterIndex = 0; | |
this.messageContainer.find("*").remove(); | |
//Regular single line message | |
var message = w.getMessage(); | |
//message = $("<div />").html(message).text(); // Converts html entities to their text value | |
//Construct message components array | |
var messageSender = $("<div />").html(message.sender).text(); | |
var messageBody = $("<div />").html(message.body).text(); | |
var messageComponents = [ | |
{ "type" : "sender", "body" : messageSender }, | |
{ "type" : "body", "body" : messageBody }]; | |
this.buildLettersArray(messageComponents); // Build lettersArray when done | |
}, | |
changeState : function(state){ | |
this.time = 0; | |
this.state = state; | |
}, | |
move : function(){ | |
//Animating | |
if(this.state == "animating") { | |
if(this.time > this.letterDelay) { | |
if(this.letterIndex < this.messageLength) { | |
this.addLetter(); | |
this.letterIndex++; | |
this.time = 0; | |
} else { | |
this.changeState("showing"); | |
} | |
} | |
} | |
//Getting | |
if(this.state == "getting") { | |
if(this.time > this.getDelay) { | |
this.changeState("animating"); | |
} | |
} | |
//Showing | |
if(this.state == "showing") { | |
if(this.time > this.options.showDuration) { | |
this.changeState("removing"); | |
this.letterIndex = 0; | |
} | |
} | |
//Removing | |
if(this.state == "removing") { | |
if(this.time > this.letterDelay) { | |
if(this.letterIndex < this.messageLength+1) { | |
this.removeLetter(); | |
this.letterIndex++; | |
} else { | |
this.changeState("intermission"); | |
} | |
} | |
} | |
//Intermission (between messages) | |
if(this.state == "intermission") { | |
if(this.time > this.options.pauseDuration) { | |
this.getMessage(); | |
this.changeState("getting"); | |
} | |
} | |
this.time++; | |
}, | |
buildLettersArray : function(messageComponents){ | |
var that = this; | |
var messageElements = []; | |
var word = ""; | |
$(messageComponents).each(function(j,obj){ | |
var messageText = obj.body; | |
var messageType = obj.type; | |
var sectionHolder = document.createElement("div"); | |
$(sectionHolder).addClass("Section"); | |
for(i=0;i <= messageText.length ; i ++) { | |
var char = messageText.charAt(i); | |
// If the character is not a space, or we've reached the end of a message | |
if(char == " " || i == messageText.length){ | |
//Make a word div, then put all the letters in there in divs | |
var wordHolder = document.createElement("div"); | |
$(wordHolder).addClass("Word") | |
for (j=0;j < word.length; j++) { | |
var letterHolder = document.createElement("span"); | |
$(letterHolder).html(word.charAt(j)).addClass("Letter"); | |
$(wordHolder).append(letterHolder); | |
} | |
$(sectionHolder).append(wordHolder); | |
word = ""; | |
//Create a space div and add it to the message elements array | |
var wordHolder = document.createElement("div"); | |
$(wordHolder).addClass("Word"); | |
var letterHolder = document.createElement("div"); | |
$(wordHolder).append(letterHolder); | |
$(letterHolder).html(" ").addClass("Letter"); | |
$(sectionHolder).append(wordHolder); | |
} else { | |
word = word + char; | |
} | |
}// /for | |
$(sectionHolder).find(".Letter").attr("messageType",messageType); | |
if (messageType == "sender") { | |
$(sectionHolder).find(".Letter").css("font-size",that.options.senderFontSize + "px"); | |
} | |
if (messageType == "body") { | |
$(sectionHolder).find(".Letter").css("font-size",that.options.bodyFontSize + "px"); | |
} | |
messageElements.push(sectionHolder); | |
}); // /messageComponents.each | |
// messageElements.pop(); // <- nukes out the last space that gets added | |
//Make a new string to find the highlighted word | |
var highlightString = ""; | |
//This grabs the scale of the parent slide and adjsuts the letter positions! | |
//It necessary!!! It is known | |
var matrix = $("#slide").css("-webkit-transform"); | |
var scale = matrix.substr(7, matrix.length - 8).split(', ')[0]; | |
//Append all the word divs to the message area | |
// and create the finalMessage array with letters & positions | |
$(messageElements).each(function(i,w){ | |
//Adds each WORD div to the message area | |
that.messageContainer.append(w); | |
$(w).find(".Letter").each(function(i,l){ | |
var pos = $(l).position(); | |
var insert = { | |
character : $(l).text(), | |
x : pos.left / scale, | |
y : pos.top / scale, | |
highlight : false, | |
messageType : $(l).attr("messageType") | |
} | |
//Remove each character if it's an opening space | |
if (insert.character.trim() == "" && insert.x == 0 ) { | |
$(l).remove(); | |
} else { | |
that.lettersArray.push(insert); | |
highlightString = highlightString + insert.character; | |
} | |
}) | |
}); | |
that.messageLength = that.lettersArray.length; | |
//This will tell the lettersArray which letters need to be highlighted | |
highlightString = highlightString.toLowerCase(); | |
var keyword = that.searchTerm.toLowerCase(); | |
var keywordStart = highlightString.indexOf(keyword); | |
var keywordEnd = keywordStart + keyword.length - 1; | |
$(that.lettersArray).each(function(i,l){ | |
if (i >= keywordStart && i <= keywordEnd) { | |
l.highlight = "White"; | |
} | |
}); | |
//After adding all the words and thier positions, remove everything in the messages div | |
that.messageContainer.find("*").remove(); | |
}, | |
removeLetter : function(){ | |
var that = this; | |
that.messageContainer.find("div.FinalLetter:nth-child("+this.letterIndex+") div").css("-webkit-animation-timing-function","ease-in"); | |
that.messageContainer.find("div.FinalLetter:nth-child("+this.letterIndex+") div").css("-webkit-transform","scale(0)"); | |
that.messageContainer.find("div.FinalLetter:nth-child("+this.letterIndex+") div").css("-webkit-animation-name",this.animation.name+"OUT"); | |
}, | |
addLetter : function(){ | |
var that = this; | |
if (that.animation.order == "random") { | |
var randomC = Math.floor(Math.random()*that.lettersArray.length); | |
var l = that.lettersArray[randomC]; | |
that.lettersArray.splice(randomC,1); | |
} | |
if(that.animation.order == "forward") { | |
var l = that.lettersArray[0]; | |
that.lettersArray.splice(0,1); | |
} | |
var letter = document.createElement("div"); | |
var letterHolder = document.createElement("div"); | |
//Set color and font-size | |
var messageType = $(l).attr("messageType"); | |
if (messageType == "sender") { | |
$(letterHolder).css("font-size",that.options.senderFontSize + "px"); | |
$(letterHolder).css("color",this.options.handleColor); | |
} | |
if (messageType == "body") { | |
$(letterHolder).css("font-size",that.options.bodyFontSize + "px"); | |
$(letterHolder).css("color",this.options.bodyColor); | |
} | |
$(letter).addClass("FinalLetter"); | |
if (l.highlight){ | |
$(letter).addClass(l.highlight); | |
} | |
$(letterHolder).text(l.character); | |
$(letter).append(letterHolder); | |
$(letter).css("-webkit-transform","translateX("+ l.x +"px) translateY("+l.y +"px)"); | |
//Changes the animation origin if needed | |
if(that.animation.origin) { | |
$(letterHolder).css("-webkit-transform-origin",that.animation.origin); | |
} | |
$(letterHolder).css("-webkit-animation-name",that.animation.name); | |
var next = that.lettersArray[1] || 0; | |
// Add the letter to the message area | |
// Unless it's the last character of a line and a space | |
//Something's going wrong here | |
//I think when it tries to check the next char when there isn't one | |
if(l.character.trim() == "" && l.y < next.y){ | |
} else { | |
that.messageContainer.append(letter); | |
} | |
} | |
} | |
return messageBox; | |
} | |
}(jQuery,this) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment