Skip to content

Instantly share code, notes, and snippets.

@flukeout
Created May 18, 2012 14:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flukeout/2725711 to your computer and use it in GitHub Desktop.
Save flukeout/2725711 to your computer and use it in GitHub Desktop.
Blam
!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("&nbsp").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