Skip to content

Instantly share code, notes, and snippets.

@flukeout
Created May 18, 2012 14:57

Revisions

  1. @invalid-email-address Anonymous created this gist May 18, 2012.
    522 changes: 522 additions & 0 deletions gistfile1.txt
    Original 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("&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)