// ------------- JQUERY TYPED.JS -------------------------------------------- // // ============ https://github.com/mattboldt/typed.js/ ====================== // // -------------------------------------------------------------------------- // !function($){ "use strict"; var Typed = function(el, options){ this.el = $(el); this.options = $.extend({}, $.fn.typed.defaults, options); this.baseText = this.el.text() || this.el.attr('placeholder') || ''; this.typeSpeed = this.options.typeSpeed; this.startDelay = this.options.startDelay; this.backSpeed = this.options.backSpeed; this.backDelay = this.options.backDelay; this.strings = this.options.strings; this.strPos = 0; this.arrayPos = 0; this.stopNum = 0; this.loop = this.options.loop; this.loopCount = this.options.loopCount; this.curLoop = 0; this.stop = false; this.showCursor = this.isInput ? false : this.options.showCursor; this.cursorChar = this.options.cursorChar; this.isInput = this.el.is('input'); this.attr = this.options.attr || (this.isInput ? 'placeholder' : null); this.build(); }; Typed.prototype = { constructor: Typed , init: function(){ // begin the loop w/ first current string (global self.string) // current string will be passed as an argument each time after this var self = this; self.timeout = setTimeout(function() { // Start typing self.typewrite(self.strings[self.arrayPos], self.strPos); }, self.startDelay); } , build: function(){ // Insert cursor if (this.showCursor === true){ this.cursor = $("" + this.cursorChar + ""); this.el.after(this.cursor); } this.init(); } , typewrite: function(curString, curStrPos){ if(this.stop === true) return; var humanize = Math.round(Math.random() * (100 - 30)) + this.typeSpeed; var self = this; // ------------- optional ------------- // // backpaces a certain string faster // ------------------------------------ // // if (self.arrayPos == 1){ // self.backDelay = 50; // } // else{ self.backDelay = 500; } // contain typing function in a timeout humanize'd delay self.timeout = setTimeout(function() { // check for an escape character before a pause value // format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^ // single ^ are removed from string var charPause = 0; var substr = curString.substr(curStrPos); if (substr.charAt(0) === '^') { var skip = 1; // skip atleast 1 if(/^\^\d+/.test(substr)) { substr = /\d+/.exec(substr)[0]; skip += substr.length; charPause = parseInt(substr); } // strip out the escape character and pause value so they're not printed curString = curString.substring(0,curStrPos)+curString.substring(curStrPos+skip); } // timeout for any pause after a character self.timeout = setTimeout(function() { if(curStrPos === curString.length) { // fires callback function self.options.onStringTyped(self.arrayPos); // is this the final string if(self.arrayPos === self.strings.length-1) { // animation that occurs on the last typed string self.options.callback(); self.curLoop++; // quit if we wont loop back if(self.loop === false || self.curLoop === self.loopCount) return; } self.timeout = setTimeout(function(){ self.backspace(curString, curStrPos); }, self.backDelay); } else { /* call before functions if applicable */ if(curStrPos === 0) self.options.preStringTyped(self.arrayPos); // start typing each new char into existing string // curString: arg, self.baseText: original text inside element var nextString = self.baseText + curString.substr(0, curStrPos+1); if (self.attr) { self.el.attr(self.attr, nextString); } else { self.el.text(nextString); } // add characters one by one curStrPos++; // loop the function self.typewrite(curString, curStrPos); } // end of character pause }, charPause); // humanized value for typing }, humanize); } , backspace: function(curString, curStrPos){ // exit when stopped if (this.stop === true) { return; } // varying values for setTimeout during typing // can't be global since number changes each time loop is executed var humanize = Math.round(Math.random() * (100 - 30)) + this.backSpeed; var self = this; self.timeout = setTimeout(function() { // ----- this part is optional ----- // // check string array position // on the first string, only delete one word // the stopNum actually represents the amount of chars to // ------------- CUSTOM OPTIONS --------------------------------------------- // // ========================================================================== // // -------------------------------------------------------------------------- // if (self.arrayPos == 1) { self.stopNum = 17; self.backDelay = 500; } else if (self.arrayPos == 2) { self.stopNum = 54; } else{self.stopNum = 0;} // ----- continue important stuff ----- // // replace text with base text + typed characters var nextString = self.baseText + curString.substr(0, curStrPos); if (self.attr) { self.el.attr(self.attr, nextString); } else { self.el.text(nextString); } // if the number (id of character in current string) is // less than the stop number, keep going if (curStrPos > self.stopNum){ // subtract characters one by one curStrPos--; // loop the function self.backspace(curString, curStrPos); } // if the stop number has been reached, increase // array position to next string else if (curStrPos <= self.stopNum) { self.arrayPos++; if(self.arrayPos === self.strings.length) { self.arrayPos = 0; self.init(); } else self.typewrite(self.strings[self.arrayPos], curStrPos); } // humanized value for typing }, humanize); } // Start & Stop currently not working // , stop: function() { // var self = this; // self.stop = true; // clearInterval(self.timeout); // } // , start: function() { // var self = this; // if(self.stop === false) // return; // this.stop = false; // this.init(); // } // Reset and rebuild the element , reset: function(){ var self = this; clearInterval(self.timeout); var id = this.el.attr('id'); this.el.after('') this.el.remove(); this.cursor.remove(); // Send the callback self.options.resetCallback(); } }; $.fn.typed = function (option) { return this.each(function () { var $this = $(this) , data = $this.data('typed') , options = typeof option == 'object' && option; if (!data) $this.data('typed', (data = new Typed(this, options))); if (typeof option == 'string') data[option](); }); }; $.fn.typed.defaults = { strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"], // typing speed typeSpeed: 0, // time before typing starts startDelay: 0, // backspacing speed backSpeed: 0, // time before backspacing backDelay: 500, // loop loop: false, // false = infinite loopCount: false, // show cursor showCursor: true, // character for cursor cursorChar: "|", // attribute to type (null == text) attr: null, // call when done callback function callback: function() {}, // starting callback function before each string preStringTyped: function() {}, //callback for every typed string onStringTyped: function() {}, // callback for reset resetCallback: function() {} }; }(window.jQuery); // ------------- jQuery Cookie Plugin v1.4.1 -------------------------------- // // ============ https://github.com/carhartl/jquery-cookie =================== // // -------------------------------------------------------------------------- // (function (factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // CommonJS factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function ($) { var pluses = /\+/g; function encode(s) { return config.raw ? s : encodeURIComponent(s); } function decode(s) { return config.raw ? s : decodeURIComponent(s); } function stringifyCookieValue(value) { return encode(config.json ? JSON.stringify(value) : String(value)); } function parseCookieValue(s) { if (s.indexOf('"') === 0) { // This is a quoted cookie as according to RFC2068, unescape... s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); } try { // Replace server-side written pluses with spaces. // If we can't decode the cookie, ignore it, it's unusable. // If we can't parse the cookie, ignore it, it's unusable. s = decodeURIComponent(s.replace(pluses, ' ')); return config.json ? JSON.parse(s) : s; } catch(e) {} } function read(s, converter) { var value = config.raw ? s : parseCookieValue(s); return $.isFunction(converter) ? converter(value) : value; } var config = $.cookie = function (key, value, options) { // Write if (arguments.length > 1 && !$.isFunction(value)) { options = $.extend({}, config.defaults, options); if (typeof options.expires === 'number') { var days = options.expires, t = options.expires = new Date(); t.setTime(+t + days * 864e+5); } return (document.cookie = [ encode(key), '=', stringifyCookieValue(value), options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : '' ].join('')); } // Read var result = key ? undefined : {}; // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. Also prevents odd result when // calling $.cookie(). var cookies = document.cookie ? document.cookie.split('; ') : []; for (var i = 0, l = cookies.length; i < l; i++) { var parts = cookies[i].split('='); var name = decode(parts.shift()); var cookie = parts.join('='); if (key && key === name) { // If second argument (value) is a function it's a converter... result = read(cookie, value); break; } // Prevent storing a cookie that we couldn't decode. if (!key && (cookie = read(cookie)) !== undefined) { result[name] = cookie; } } return result; }; config.defaults = {}; $.removeCookie = function (key, options) { if ($.cookie(key) === undefined) { return false; } // Must not alter options, thus extending a fresh object... $.cookie(key, '', $.extend({}, options, { expires: -1 })); return !$.cookie(key); }; })); jQuery(document).ready(function($) { /*============================================ Welcome Cookies ==============================================*/ $(function dw_set_cookie() { var COOKIE = 'windhamdavid-cookie'; var dwcookie = $.cookie(COOKIE); if (dwcookie == null) { $.cookie(COOKIE, 'yum-cookies', { expires: 7, path: '/'}); $('.terminal-welcome').modal('show'); $('.welcome').typed({ strings: ['Hey,', 'Hello,\n^10Welcome to ^10my domain ^10...^10', 'Hello, \nWelcome to my little corner of the internet. \n^10It is nice to ', 'Hello, \nWelcome to my little corner of the internet. \nWhat is your name?^200\n'], typeSpeed: 30, backSpeed: 50, startDelay: 0, backDelay: 0, loop: false, loopCount: false, attr: null, callback: function(){ dw_terminal(); } }); } else { $('.terminal').modal('show'); if (localStorage.getItem('person') === null) { var person = 'anonymous person'; } else { var person = localStorage.getItem('person'); } $('.welcome-back-text').typed({ strings: ['...', 'Welcome back ' +person], typeSpeed: 30, backSpeed: 10, startDelay: 0, backDelay: 100, loop: false, loopCount: false, attr: null, callback: function(){ dw_terminal(); } }); } }); /*============================================ Terminal ==============================================*/ (function ($){ $.fn.cli = function(handler, prompt, effect){ if (!prompt) prompt = 'you@david > '; if (!effect) effect = $.fn.text; return this.each(function(){ var self = $(this); function newline(){ self. append('

'+prompt+'

'); try { $('[contenteditable]', self)[0].focus(); }catch(e){ } } newline(); self.on('keydown', '[contenteditable]', function(evt){ if (evt.keyCode === 13){ $(this).removeAttr('contenteditable'); effect.call($('

').appendTo(self),handler(this.textContent || this.innerText)); newline(); return false; } }); }); }; })(jQuery); function dw_shift() { $('.terminal-welcome').delay(5500).queue(function(thanks){ $(this).modal('hide'); thanks(); }); } function dw_contact() { $('.terminal-welcome').delay(2500).queue(function(thanks){ window.location.assign("/contact/"); }); } function dw_terminal(){ function type(text){ var span = $('').appendTo(this).after('  '); var style = $('').appendTo('head'); $('p.input').addClass('old'); var progress = 0; var timer = setInterval (function(){ span.text(text.substr(0, progress++)); if (progress > text.length){ $('#blinker').remove(); style.remove(); $('[contenteditable]')[0].focus(); clearInterval(timer); } },100); } $('.thermo-intro').cli(function(text){ if (text.length > 1) { localStorage.setItem('person', text), dw_shift(); }; return 'I will close this terminal now. Thank You ' +text; }, null, type); $('.thermo').cli(function(text){ if (/exit/i.test(text)) { $('.terminal').modal('hide'); } if (/contact/i.test(text)) { return "loading...", dw_contact(); }; if (/help/i.test(text)) return "I need somebody!"; if (/hello/i.test(text)) return "Hello to you!"; if (/what/i.test(text)) return "This is a website silly human"; if (/and/i.test(text)) return "and what?"; if (/who/i.test(text)) return "David A. Windham"; if (/when/i.test(text)) return "Yesterday"; if (/how/i.test(text)) return "JavaScript is a dynamic computer programming language"; if (/why/i.test(text)) return "For fun"; if (/you/i.test(text)) return "your mama"; if (/cd ../i.test(text)) return "Oh, I see"; if (/thermonuclear/i.test(text)) return "Wouldn't you prefer a nice game of chess?"; if (text.length < 3) return "type 'exit' to close"; return 'command not found: '+text; }, null, type); $('p.input').on('touchstart click', function(e) { e.preventDefault(); $('[contenteditable]')[0].focus(); }); } });