Advertisement
Guest User

Read.js

a guest
Dec 6th, 2016
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ( function ( window, $ ){
  2.     "use strict";
  3.  
  4.     /*jshint multistr: true */
  5.     var ele = '<div class="__read">\
  6.             <div class="__read_bar progrecss">\
  7.                 <div class="__read_position">\
  8.                     <div class="__read_indicator"></div>\
  9.                     <div class="__read_display"></div>\
  10.                     <div class="__read_before"></div>\
  11.                     <div class="__read_letter"></div>\
  12.                 </div>\
  13.                 <div class="__read_config"></div>\
  14.                 <div class="__read_restart"></div>\
  15.                 <div class="__read_close_read"></div>\
  16.             </div>\
  17.             <div class="__read_settings">\
  18.                 <div class="__read_setting __read_wpm">\
  19.                     <label class="__read_label">Words Per Minute</label>\
  20.                     <input class="__read_input __read_speed" type="text"/>\
  21.                     <div class="__read_slider __read_speed_slider"></div>\
  22.                 </div>\
  23.                 <div class="__read_setting __read_slowstart">\
  24.                     <label class="__read_label">Slow Start Speed</label>\
  25.                     <input class="__read_input __read_slow_start" type="text"/>\
  26.                     <div class="__read_slider __read_slow_start_slider"></div>\
  27.                 </div>\
  28.                 <div class="__read_setting __read_sentencedelay">\
  29.                     <label class="__read_label">Sentence Delay</label>\
  30.                     <input class="__read_input __read_sentence_delay" type="text"/>\
  31.                     <div class="__read_slider __read_sentence_delay_slider"></div>\
  32.                 </div>\
  33.                 <div class="__read_setting __read_puncdelay">\
  34.                     <label class="__read_label">Other Punctuation Delay</label>\
  35.                     <input class="__read_input __read_punc_delay" type="text"/>\
  36.                     <div class="__read_slider __read_punc_delay_slider"></div>\
  37.                 </div>\
  38.                 <div class="__read_setting __read_shortworddelay">\
  39.                     <label class="__read_label">Short Word Delay</label>\
  40.                     <input class="__read_input __read_short_word_delay" type="text"/>\
  41.                     <div class="__read_slider __read_short_word_delay_slider"></div>\
  42.                 </div>\
  43.                 <div class="__read_setting __read_longworddelay">\
  44.                     <label class="__read_label">Long Word Delay</label>\
  45.                     <input class="__read_input __read_long_word_delay" type="text"/>\
  46.                     <div class="__read_slider __read_long_word_delay_slider"></div>\
  47.                 </div>\
  48.                 <div class="__read_setting __read_numericdelay">\
  49.                     <label class="__read_label">Numeric Delay</label>\
  50.                     <input class="__read_input __read_numeric_delay" type="text"/>\
  51.                     <div class="__read_slider __read_numeric_delay_slider"></div>\
  52.                 </div>\
  53.             </div>\
  54.         </div>';
  55.  
  56.     $.fn.textWidth = function(){
  57.         var self = $(this),
  58.             children = self.contents(),
  59.             calculator = $('<span style="display: inline-block;" />'),
  60.             width;
  61.  
  62.         children.wrap(calculator);
  63.         width = children.parent().width();
  64.         children.unwrap();
  65.         console.log('width:', width);
  66.         return width;
  67.     };
  68.  
  69.     var defaultOptions = {
  70.         wpm: 300,
  71.         slowStartCount: 5,
  72.         sentenceDelay: 2.5,
  73.         otherPuncDelay: 1.5,
  74.         shortWordDelay: 1.3,
  75.         longWordDelay: 1.4,
  76.         numericDelay: 2.0
  77.  
  78.     };
  79.  
  80.     var whiteSpace = /[\n\r\s]/;
  81.  
  82.     function Read ( block, options ) { //element, wpm ) {
  83.  
  84.         // Defaults
  85.         this._parentElement = null;
  86.         this._barElement = null;
  87.         this._settingsElement = null;
  88.         this._configElement = null;
  89.         this._restartElement = null;
  90.         this._displayElement = null;
  91.         this._closeElement = null;
  92.  
  93.         this._speedElement = null;
  94.         this._speedSliderElement = null;
  95.  
  96.         this._slowStartElement = null;
  97.         this._slowStartCount = null;
  98.         this._slowStartSliderElement = null;
  99.  
  100.         this._sentenceDelayElement = null;
  101.         this._sentenceDelaySliderElement = null;
  102.  
  103.         this._puncDelayElement = null;
  104.         this._puncDelaySliderElement = null;
  105.  
  106.         this._shortWordDelayElement = null;
  107.         this._shortWordDelaySliderElement = null;
  108.  
  109.         this._longWordDelayElement = null;
  110.         this._longWordDelaySliderElement = null;
  111.  
  112.         this._numericDelayElement = null;
  113.         this._numericDelaySliderElement = null;
  114.  
  115.         this._currentWord = null;
  116.         this._delay = 0;
  117.         this._timer = null;
  118.         this._isPlaying = false;
  119.         this._isEnded = false;
  120.  
  121.         this._options = $.extend( {}, defaultOptions, options );
  122.  
  123.         Read.enforceSingleton(this);
  124.  
  125.         // Configured
  126.         this.setWPM(this._options.wpm);
  127.         this.setText(block);
  128.         this.setElement();
  129.     }
  130.  
  131.     Read.enforceSingleton = function (inst) {
  132.         if (Read.instance) {
  133.             Read.instance.destroy();
  134.             Read.instance = null;
  135.         }
  136.         Read.instance = inst;
  137.     };
  138.  
  139.     var p = Read.prototype;
  140.  
  141.     p._display = function () {
  142.         this._currentWord = this._block.getWord();
  143.         if (this._currentWord) {
  144.             this._showWord();
  145.  
  146.             var time = this._delay;
  147.  
  148.             if ( this._currentWord.hasPeriod ) time *= this._options.sentenceDelay;
  149.             if ( this._currentWord.hasOtherPunc ) time *= this._options.otherPuncDelay;
  150.             if ( this._currentWord.isShort ) time *= this._options.shortWordDelay;
  151.             if ( this._currentWord.isLong ) time *= this._options.longWordDelay;
  152.             if ( this._currentWord.isNumeric ) time *= this._options.numericDelay;
  153.  
  154.             this._slowStartCount = (this._slowStartCount - 1 ) || 1;
  155.             time = time * this._slowStartCount;
  156.  
  157.             this._timer = setTimeout($.proxy(this._next, this),time);
  158.         } else {
  159.             this.clearDisplay();
  160.             this._isPlaying = false;
  161.             this._isEnded = true;
  162.             this._barElement.attr('data-progrecss', 100 );
  163.         }
  164.     };
  165.  
  166.     p._showWord = function () {
  167.         if (this._displayElement) {
  168.             var word = this._currentWord.val;
  169.  
  170.             var before = word.substr(0, this._currentWord.index);
  171.             var letter = word.substr(this._currentWord.index, 1);
  172.  
  173.             // fake elements
  174.             var $before = this._options.element.find('.__read_before').html(before).css("opacity","0");
  175.             var $letter = this._options.element.find('.__read_letter').html(letter).css("opacity","0");
  176.  
  177.             // START CUSTOM CODE FOR GREEK
  178.             var calc = 0;
  179.             // END CUSTOM CODE FOR GREEK
  180.  
  181.             if (!this._currentWord.val.match(whiteSpace)){
  182.                 this._displayElement.html(this._currentWord.val);
  183.                 this._displayElement.css("margin-left", -calc);
  184.                 console.log( 'actual margin:', this._displayElement.css('margin-left') );
  185.             }
  186.         }
  187.  
  188.         if (this._options.element && this._block) {
  189.             this._barElement.attr('data-progrecss', parseInt(this._block.getProgress() * 100, 10) );
  190.         }
  191.     };
  192.  
  193.     p._initSettings = function () {
  194.  
  195.         // WPM
  196.         this._speedSliderElement.noUiSlider({
  197.             range: [300,1500],
  198.             start: this._options.wpm,
  199.             step: 25,
  200.             connect: 'lower',
  201.             handles: 1,
  202.             behaviour: 'extend-tap',
  203.             serialization: {
  204.                 to: [ this._speedElement ],
  205.                 resolution: 1
  206.             },
  207.             set: $.proxy( function() {
  208.                 this.setWPM( this._speedElement.val() );
  209.                 this._speedElement.blur();
  210.             }, this )
  211.         });
  212.  
  213.         // Slow Start
  214.         this._slowStartSliderElement.noUiSlider({
  215.             range: [0,5],
  216.             start: this._options.slowStartCount,
  217.             step: 1,
  218.             connect: 'lower',
  219.             handles: 1,
  220.             behaviour: 'extend-tap',
  221.             serialization: {
  222.                 to: [ this._slowStartElement ],
  223.                 resolution: 1
  224.             },
  225.             set: $.proxy( function() {
  226.                 this.setSlowStartCount( this._slowStartElement.val() );
  227.                 this._slowStartElement.blur();
  228.             },this )
  229.         });
  230.  
  231.         // Sentence Delay
  232.         this._sentenceDelaySliderElement.noUiSlider({
  233.             range: [0,5],
  234.             start: this._options.sentenceDelay,
  235.             step: 0.1,
  236.             connect: 'lower',
  237.             handles: 1,
  238.             behaviour: 'extend-tap',
  239.             serialization: {
  240.                 to: [ this._sentenceDelayElement ],
  241.                 resolution: 0.1
  242.             },
  243.             set: $.proxy( function() {
  244.                 this.setSentenceDelay( this._sentenceDelayElement.val() );
  245.                 this._sentenceDelayElement.blur();
  246.             },this )
  247.         });
  248.  
  249.         // Other Punctuation Delay
  250.         this._puncDelaySliderElement.noUiSlider({
  251.             range: [0,5],
  252.             start: this._options.otherPuncDelay,
  253.             step: 0.1,
  254.             connect: 'lower',
  255.             handles: 1,
  256.             behaviour: 'extend-tap',
  257.             serialization: {
  258.                 to: [ this._puncDelayElement ],
  259.                 resolution: 0.1
  260.             },
  261.             set: $.proxy( function() {
  262.                 this.setOtherPuncDelay( this._puncDelayElement.val() );
  263.                 this._puncDelayElement.blur();
  264.             },this )
  265.         });
  266.  
  267.         // Short Word Delay
  268.         this._shortWordDelaySliderElement.noUiSlider({
  269.             range: [0,5],
  270.             start: this._options.shortWordDelay,
  271.             step: 0.1,
  272.             connect: 'lower',
  273.             handles: 1,
  274.             behaviour: 'extend-tap',
  275.             serialization: {
  276.                 to: [ this._shortWordDelayElement ],
  277.                 resolution: 0.1
  278.             },
  279.             set: $.proxy( function() {
  280.                 this.setShortWordDelay( this._shortWordDelayElement.val() );
  281.                 this._shortWordDelayElement.blur();
  282.             },this )
  283.         });
  284.  
  285.         // Long word Delay
  286.         this._longWordDelaySliderElement.noUiSlider({
  287.             range: [0,5],
  288.             start: this._options.longWordDelay,
  289.             step: 0.1,
  290.             connect: 'lower',
  291.             handles: 1,
  292.             behaviour: 'extend-tap',
  293.             serialization: {
  294.                 to: [ this._longWordDelayElement ],
  295.                 resolution: 0.1
  296.             },
  297.             set: $.proxy( function() {
  298.                 this.setLongWordDelay( this._longWordDelayElement.val() );
  299.                 this._longWordDelayElement.blur();
  300.             },this )
  301.         });
  302.  
  303.         // Numeric Delay
  304.         this._numericDelaySliderElement.noUiSlider({
  305.             range: [0,5],
  306.             start: this._options.numericDelay,
  307.             step: 0.1,
  308.             connect: 'lower',
  309.             handles: 1,
  310.             behaviour: 'extend-tap',
  311.             serialization: {
  312.                 to: [ this._numericDelayElement ],
  313.                 resolution: 0.1
  314.             },
  315.             set: $.proxy( function() {
  316.                 this.setNumericDelay( this._numericDelayElement.val() );
  317.                 this._numericDelayElement.blur();
  318.             },this )
  319.         });
  320.  
  321.     };
  322.  
  323.     p.toggleSettings = function () {
  324.         if (this._configElement.hasClass('active')) {
  325.             this.hideSettings();
  326.         } else {
  327.             this.showSettings();
  328.         }
  329.     };
  330.  
  331.     p.showSettings = function () {
  332.         this._options.element.addClass('open');
  333.         this._configElement.addClass('active');
  334.     };
  335.  
  336.     p.hideSettings = function () {
  337.         this._options.element.removeClass('open');
  338.         this._configElement.removeClass('active');
  339.     };
  340.  
  341.     p.destroy = function () {
  342.         p.pause();
  343.         this._speedElement.off ( "blur" );
  344.         this._speedElement.off ( "keydown" );
  345.         this._parentElement.find('.__read').remove();
  346.         this._parentElement.css( "padding-top", "-=50" );
  347.         this._configElement.off();
  348.         this._restartElement.off();
  349.         this._displayElement.off();
  350.         this._closeElement.off();
  351.         this._speedElement.off();
  352.     };
  353.  
  354.     p.setText = function (val) {
  355.         if (val) {
  356.             this.pause();
  357.             this.restart();
  358.             this._block = new ReadBlock(val);
  359.             this._currentWord = this._block.getWord();
  360.         }
  361.     };
  362.  
  363.     p._next = function() {
  364.         this._block.next();
  365.         this._display();
  366.     };
  367.  
  368.     p.setElement = function (val) {
  369.         if (!val) {
  370.             val = 'body';
  371.         }
  372.  
  373.         this.clearDisplay();
  374.  
  375.         // unbind old binds
  376.         if (this._parentElement) {
  377.             this._parentElement.find('.__read').remove();
  378.             this._parentElement.css( "padding-top", "-=50" );
  379.         }
  380.  
  381.         if (val instanceof $) {
  382.             this._parentElement = val;
  383.         } else {
  384.             this._parentElement = $(val);
  385.         }
  386.  
  387.  
  388.         // bind new binds
  389.         this._options.element = $(ele);
  390.         this._parentElement.animate( { "padding-top": "+=50" }, 400);
  391.         this._parentElement.prepend(this._options.element);
  392.         this._options.element.slideDown();
  393.  
  394.         this._barElement = this._options.element.find('.__read_bar');
  395.  
  396.         this._settingsElement = this._options.element.find('.__read_settings');
  397.  
  398.         this._configElement = this._options.element.find('.__read_config');
  399.         this._configElement.on ( "touchend click", $.proxy(this.toggleSettings, this) );
  400.  
  401.         this._restartElement = this._options.element.find('.__read_restart');
  402.         this._restartElement.on ( "touchend click", $.proxy(this.restart, this) );
  403.  
  404.         this._displayElement = this._options.element.find('.__read_display');
  405.         this._displayElement.on ( "touchend click", $.proxy(this.playPauseToggle, this) );
  406.  
  407.         this._closeElement = this._options.element.find('.__read_close_read');
  408.         this._closeElement.on ( "touchend click", $.proxy(this.destroy, this) );
  409.  
  410.         this._slowStartElement = this._options.element.find('.__read_slow_start');
  411.         this._slowStartSliderElement = this._options.element.find('.__read_slow_start_slider');
  412.  
  413.         this._sentenceDelayElement = this._options.element.find('.__read_sentence_delay');
  414.         this._sentenceDelaySliderElement = this._options.element.find('.__read_sentence_delay_slider');
  415.  
  416.         this._puncDelayElement = this._options.element.find('.__read_punc_delay');
  417.         this._puncDelaySliderElement = this._options.element.find('.__read_punc_delay_slider');
  418.  
  419.         this._shortWordDelayElement = this._options.element.find('.__read_short_word_delay');
  420.         this._shortWordDelaySliderElement = this._options.element.find('.__read_short_word_delay_slider');
  421.  
  422.         this._longWordDelayElement = this._options.element.find('.__read_long_word_delay');
  423.         this._longWordDelaySliderElement = this._options.element.find('.__read_long_word_delay_slider');
  424.  
  425.         this._numericDelayElement = this._options.element.find('.__read_numeric_delay');
  426.         this._numericDelaySliderElement = this._options.element.find('.__read_numeric_delay_slider');
  427.  
  428.         this._speedElement = this._options.element.find('.__read_speed');
  429.         this._speedElement.on ( "blur", $.proxy(this.updateWPMFromUI, this) );
  430.         this._speedElement.on ( "keydown", function(e) { if (e.keyCode == 13) { $(this).blur(); } });
  431.         this._speedSliderElement = this._options.element.find('.__read_speed_slider');
  432.  
  433.         this._initSettings();
  434.     };
  435.  
  436.     p.playPauseToggle = function () {
  437.         if (this._isPlaying) {
  438.             this.pause();
  439.         } else {
  440.             this.play();
  441.         }
  442.     };
  443.  
  444.     p.play = function () {
  445.         if (this._block) {
  446.             if (this._isEnded) {
  447.                 return;
  448.             }
  449.             if (this._options.slowStartCount) {
  450.                 this._slowStartCount = this._options.slowStartCount;
  451.             }
  452.             this._display();
  453.             this._isPlaying = true;
  454.         }
  455.     };
  456.  
  457.     p.clearDisplay = function () {
  458.         if (this._displayElement) this._displayElement.html("");
  459.     };
  460.  
  461.     p.pause = function () {
  462.         clearTimeout(this._timer);
  463.         this._isPlaying = false;
  464.     };
  465.  
  466.     p.restart = function () {
  467.         if (this._block) {
  468.             if (!this._isEnded) {
  469.                 this.pause();
  470.             }
  471.             if (this._options.slowStartCount) {
  472.                 this._slowStartCount = this._options.slowStartCount;
  473.             }
  474.             this._block.restart();
  475.             this._currentWord = this._block.getWord();
  476.             this._isEnded = false;
  477.             this.play();
  478.         }
  479.     };
  480.  
  481.     p.setWPM = function ( val ) {
  482.         val = Number(val);
  483.         val = Math.max (1, val);
  484.         val = Math.min (1500, val);
  485.         this._wpm = val;
  486.         this._delay = 1/(val/60)*1000;
  487.     };
  488.  
  489.     p.setSentenceDelay = function ( val ) {
  490.         val = Number(val);
  491.         val = Math.max (1, val);
  492.         val = Math.min (10, val);
  493.         this._options.sentenceDelay = val;
  494.     };
  495.  
  496.     p.setOtherPuncDelay = function ( val ) {
  497.         val = Number(val);
  498.         val = Math.max (1, val);
  499.         val = Math.min (10, val);
  500.         this._options.otherPuncDelay = val;
  501.     };
  502.  
  503.     p.setShortWordDelay = function ( val ) {
  504.         val = Number(val);
  505.         val = Math.max (1, val);
  506.         val = Math.min (10, val);
  507.         this._options.shortWordDelay = val;
  508.     };
  509.  
  510.     p.setLongWordDelay = function ( val ) {
  511.         val = Number(val);
  512.         val = Math.max (1, val);
  513.         val = Math.min (10, val);
  514.         this._options.longWordDelay = val;
  515.     };
  516.  
  517.     p.setNumericDelay = function ( val ) {
  518.         val = Number(val);
  519.         val = Math.max (1, val);
  520.         val = Math.min (10, val);
  521.         this._options.numericDelay = val;
  522.     };
  523.  
  524.     p.setSlowStartCount = function ( val ) {
  525.         val = Number(val);
  526.         val = Math.max(0,val);
  527.         val = Math.min(10,val);
  528.         this._options.slowStartCount = val;
  529.     };
  530.  
  531.     p.updateWPMFromUI = function () {
  532.         var newWPM = this._speedElement.val();
  533.         newWPM = newWPM.match(/[\d]+/g);
  534.         newWPM = parseInt(newWPM, 10);
  535.         this.setWPM(newWPM);
  536.     };
  537.  
  538.     window.Read = Read;
  539.  
  540. }(window, jQuery) );
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement