Created
May 18, 2012 14:57
Revisions
-
There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,522 @@ !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)