You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

347 lines
13 KiB

  1. // The MIT License (MIT)
  2. // Typed.js | Copyright (c) 2014 Matt Boldt | www.mattboldt.com
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy
  4. // of this software and associated documentation files (the "Software"), to deal
  5. // in the Software without restriction, including without limitation the rights
  6. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. // copies of the Software, and to permit persons to whom the Software is
  8. // furnished to do so, subject to the following conditions:
  9. // The above copyright notice and this permission notice shall be included in
  10. // all copies or substantial portions of the Software.
  11. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. // THE SOFTWARE.
  18. !function($){
  19. "use strict";
  20. var Typed = function(el, options){
  21. // chosen element to manipulate text
  22. this.el = $(el);
  23. // options
  24. this.options = $.extend({}, $.fn.typed.defaults, options);
  25. // text content of element
  26. this.baseText = (this.options.baseText !== undefined) ? this.options.baseText : this.el.text() || this.el.attr('placeholder') || '';
  27. // replace base text on first word
  28. this.replaceBaseText = this.options.replaceBaseText;
  29. // typing speed
  30. this.typeSpeed = this.options.typeSpeed;
  31. // add a delay before typing starts
  32. this.startDelay = this.options.startDelay;
  33. // backspacing speed
  34. this.backSpeed = this.options.backSpeed;
  35. // amount of time to wait before backspacing
  36. this.backDelay = this.options.backDelay;
  37. // input strings of text
  38. this.strings = this.options.strings;
  39. // character number position of current string
  40. this.strPos = (this.replaceBaseText) ? this.baseText.length : 0;
  41. // current array position
  42. this.arrayPos = 0;
  43. // number to stop backspacing on.
  44. // default 0, can change depending on how many chars
  45. // you want to remove at the time
  46. this.stopNum = 0;
  47. // Looping logic
  48. this.loop = this.options.loop;
  49. this.loopCount = this.options.loopCount;
  50. this.curLoop = 0;
  51. // for stopping
  52. this.stop = false;
  53. // show cursor
  54. this.showCursor = this.isInput ? false : this.options.showCursor;
  55. // custom cursor
  56. this.cursorChar = this.options.cursorChar;
  57. // attribute to type
  58. this.isInput = this.el.is('input');
  59. this.attr = this.options.attr || (this.isInput ? 'placeholder' : null);
  60. // All systems go!
  61. this.build();
  62. };
  63. Typed.prototype = {
  64. constructor: Typed
  65. , init: function(){
  66. // begin the loop w/ first current string (global self.string)
  67. // current string will be passed as an argument each time after this
  68. var self = this;
  69. // Adds base text to strings array if user replace setting enabled
  70. if(this.replaceBaseText) {
  71. this.strings.unshift(self.baseText);
  72. }
  73. self.timeout = setTimeout(function() {
  74. var currentWord = (self.arrayPos === 0 && self.replaceBaseText) ? (self.baseText) : self.strings[self.arrayPos];
  75. // Start typing
  76. self.typewrite(currentWord, self.strPos);
  77. }, self.startDelay);
  78. }
  79. , build: function(){
  80. // Insert cursor
  81. if (this.showCursor === true){
  82. this.cursor = $("<span class=\"typed-cursor\">" + this.cursorChar + "</span>");
  83. this.el.after(this.cursor);
  84. }
  85. this.init();
  86. }
  87. // pass current string state to each function, types 1 char per call
  88. , typewrite: function(curString, curStrPos){
  89. // exit when stopped
  90. if(this.stop === true)
  91. return;
  92. // varying values for setTimeout during typing
  93. // can't be global since number changes each time loop is executed
  94. var humanize = Math.round(Math.random() * (100 - 30)) + this.typeSpeed;
  95. var self = this;
  96. // ------------- optional ------------- //
  97. // backpaces a certain string faster
  98. // ------------------------------------ //
  99. // if (self.arrayPos == 1){
  100. // self.backDelay = 50;
  101. // }
  102. // else{ self.backDelay = 500; }
  103. // contain typing function in a timeout humanize'd delay
  104. self.timeout = setTimeout(function() {
  105. // check for an escape character before a pause value
  106. // format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^
  107. // single ^ are removed from string
  108. var charPause = 0;
  109. var substr = curString.substr(curStrPos);
  110. // console.log(curString, substr, curStrPos);
  111. if (substr.charAt(0) === '^') {
  112. var skip = 1; // skip atleast 1
  113. if(/^\^\d+/.test(substr)) {
  114. substr = /\d+/.exec(substr)[0];
  115. skip += substr.length;
  116. charPause = parseInt(substr);
  117. }
  118. // strip out the escape character and pause value so they're not printed
  119. curString = curString.substring(0,curStrPos)+curString.substring(curStrPos+skip);
  120. }
  121. // timeout for any pause after a character
  122. self.timeout = setTimeout(function() {
  123. if(curStrPos === curString.length) {
  124. // fires callback function
  125. self.options.onStringTyped(self.arrayPos);
  126. // is this the final string
  127. if(self.arrayPos === self.strings.length-1) {
  128. // animation that occurs on the last typed string
  129. self.options.callback();
  130. self.curLoop++;
  131. // quit if we wont loop back
  132. if(self.loop === false || self.curLoop === self.loopCount)
  133. return;
  134. }
  135. self.timeout = setTimeout(function(){
  136. self.backspace(curString, curStrPos);
  137. }, self.backDelay);
  138. } else {
  139. /* call before functions if applicable */
  140. if(curStrPos === 0)
  141. self.options.preStringTyped(self.arrayPos);
  142. // start typing each new char into existing string
  143. // curString: arg, self.baseText: original text inside element
  144. var nextSubString = curString.substr(0, curStrPos+1);
  145. var nextString = (self.replaceBaseText) ? nextSubString : (self.baseText + nextSubString);
  146. if (self.attr) {
  147. self.el.attr(self.attr, nextString);
  148. } else {
  149. self.el.text(nextString);
  150. }
  151. // add characters one by one
  152. curStrPos++;
  153. // loop the function
  154. self.typewrite(curString, curStrPos);
  155. }
  156. // end of character pause
  157. }, charPause);
  158. // humanized value for typing
  159. }, humanize);
  160. }
  161. , backspace: function(curString, curStrPos){
  162. // exit when stopped
  163. if (this.stop === true) {
  164. return;
  165. }
  166. // varying values for setTimeout during typing
  167. // can't be global since number changes each time loop is executed
  168. var humanize = Math.round(Math.random() * (100 - 30)) + this.backSpeed;
  169. var self = this;
  170. self.timeout = setTimeout(function() {
  171. // ----- this part is optional ----- //
  172. // check string array position
  173. // on the first string, only delete one word
  174. // the stopNum actually represents the amount of chars to
  175. // keep in the current string. In my case it's 14.
  176. // if (self.arrayPos == 1){
  177. // self.stopNum = 14;
  178. // }
  179. //every other time, delete the whole typed string
  180. // else{
  181. // self.stopNum = 0;
  182. // }
  183. // ----- continue important stuff ----- //
  184. // replace text with base text + typed characters
  185. var curSubString = curString.substr(0, curStrPos+1);
  186. var nextString = (self.replaceBaseText) ? curSubString : (self.baseText + curSubString);
  187. if (self.attr) {
  188. self.el.attr(self.attr, nextString);
  189. } else {
  190. self.el.text(nextString);
  191. }
  192. // if the number (id of character in current string) is
  193. // less than the stop number, keep going
  194. if (curStrPos > self.stopNum){
  195. // subtract characters one by one
  196. curStrPos--;
  197. // loop the function
  198. self.backspace(curString, curStrPos);
  199. }
  200. // if the stop number has been reached, increase
  201. // array position to next string
  202. else if (curStrPos <= self.stopNum) {
  203. self.arrayPos++;
  204. if(self.arrayPos === self.strings.length) {
  205. self.arrayPos = 0;
  206. self.init();
  207. } else
  208. self.typewrite(self.strings[self.arrayPos], curStrPos);
  209. }
  210. // humanized value for typing
  211. }, humanize);
  212. }
  213. // Start & Stop currently not working
  214. // , stop: function() {
  215. // var self = this;
  216. // self.stop = true;
  217. // clearInterval(self.timeout);
  218. // }
  219. // , start: function() {
  220. // var self = this;
  221. // if(self.stop === false)
  222. // return;
  223. // this.stop = false;
  224. // this.init();
  225. // }
  226. // Reset and rebuild the element
  227. , reset: function(){
  228. var self = this;
  229. clearInterval(self.timeout);
  230. var id = this.el.attr('id');
  231. this.el.after('<span id="' + id + '"/>')
  232. this.el.remove();
  233. this.cursor.remove();
  234. // Send the callback
  235. self.options.resetCallback();
  236. }
  237. };
  238. $.fn.typed = function (option) {
  239. return this.each(function () {
  240. var $this = $(this)
  241. , data = $this.data('typed')
  242. , options = typeof option == 'object' && option;
  243. if (!data) $this.data('typed', (data = new Typed(this, options)));
  244. if (typeof option == 'string') data[option]();
  245. });
  246. };
  247. $.fn.typed.defaults = {
  248. // Typewrite away original text on start
  249. replaceBaseText: false,
  250. strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"],
  251. // typing speed
  252. typeSpeed: 0,
  253. // time before typing starts
  254. startDelay: 0,
  255. // backspacing speed
  256. backSpeed: 0,
  257. // time before backspacing
  258. backDelay: 500,
  259. // loop
  260. loop: false,
  261. // false = infinite
  262. loopCount: false,
  263. // show cursor
  264. showCursor: true,
  265. // character for cursor
  266. cursorChar: "|",
  267. // attribute to type (null == text)
  268. attr: null,
  269. // call when done callback function
  270. callback: function() {},
  271. // starting callback function before each string
  272. preStringTyped: function() {},
  273. //callback for every typed string
  274. onStringTyped: function() {},
  275. // callback for reset
  276. resetCallback: function() {}
  277. };
  278. }(window.jQuery);