Comments + other janitorial edits

This commit is contained in:
Joe Adams 2019-06-21 03:13:36 +01:00
parent e77f431fba
commit 7866a4dffb

View File

@ -1,5 +1,6 @@
function sReader_randomTimer() function sReader_randomTimer()
{ {
// Generates random variables for the CSS animations
el = document.querySelectorAll("#sReader_outputText .indicator .i"); el = document.querySelectorAll("#sReader_outputText .indicator .i");
for (i=0; i<el.length; ++i) for (i=0; i<el.length; ++i)
{ {
@ -10,12 +11,14 @@ function sReader_randomTimer()
function sReader_stripPunctuation(_word) function sReader_stripPunctuation(_word)
{ {
pre = ""; // Strip away leading punctuation and trailing punctuation,
main = ""; // as we don't want it to factor into the ORP calculation
post = ""; pre = ""; // Prefix characters
stage = 0; main = ""; // Main characters (for ORP)
lookBehind = 0; post = ""; // Postfix characters
i = 0; stage = 0; // Keep track of how far we've gotten
lookBehind = 0; // Keep track of no. of trailing symbols
i = 0; // Loop counter
while (i<_word.length) while (i<_word.length)
{ {
switch(stage) switch(stage)
@ -23,12 +26,16 @@ function sReader_stripPunctuation(_word)
case 0: case 0:
{ {
if (/^[A-Za-z0-9]/.test(_word.charAt(i))) if (/^[A-Za-z0-9]/.test(_word.charAt(i)))
{ {
++stage; ++stage;
// Current character is a letter/number,
// so we're looking at the start of the
// relavent block of text...
} }
else else
{ {
pre += _word.charAt(i++); pre += _word.charAt(i++);
// Append to prefix string
} }
break; break;
} }
@ -38,11 +45,20 @@ function sReader_stripPunctuation(_word)
{ {
lookBehind = 0; lookBehind = 0;
main += _word.charAt(i++); main += _word.charAt(i++);
// Still looking at relavent characters,
// so we reset the lookBehind counter
// (embedded symbols are considered
// relavent also)
} }
else else
{ {
++lookBehind; ++lookBehind;
main += _word.charAt(i++); main += _word.charAt(i++);
// Here we are continuing to append to
// the main string, but noting how many
// symbols we have seen in a row last.
// This way we know to move them to the
// suffix in a bit
} }
break; break;
} }
@ -54,6 +70,7 @@ function sReader_stripPunctuation(_word)
} }
if (lookBehind > 0) if (lookBehind > 0)
{ {
// There are trailing symbols to process
for (i=0; i<main.length; ++i) for (i=0; i<main.length; ++i)
{ {
if (i >= (main.length - lookBehind)) if (i >= (main.length - lookBehind))
@ -64,55 +81,58 @@ function sReader_stripPunctuation(_word)
main = main.slice(0, -lookBehind); main = main.slice(0, -lookBehind);
} }
returnVal = [pre, main, post]; returnVal = [pre, main, post];
// Bundle everything together in an array to return
return returnVal; return returnVal;
} }
function sReader_calculateOrp(_word, _symbols = false) function sReader_calculateOrp(_word, _symbols = false)
{ {
//// Naive approximation of Spritz's ORP algorithm
//// Naive approximation of Spritz's ORP algorithm //// https://www.spritz.com/faqs
//// ////
//// wordCount -> wordCenter -> ORP //// wordCount -> wordCenter -> ORP
//// (deviation from center) -> deviation with //// (deviation from center) -> deviation with
//// ceil() on center //// ceil() on center
// //
// 1 -> 1.0 -> 1 ( 0.0) -> 0 // 1 -> 1.0 -> 1 ( 0.0) -> 0
// 2 -> 1.5 -> 2 (+0.5) -> 0 // 2 -> 1.5 -> 2 (+0.5) -> 0
// 3 -> 2.0 -> 2 ( 0.0) -> 0 // 3 -> 2.0 -> 2 ( 0.0) -> 0
// 4 -> 2.5 -> 2 (-0.5) -> -1 // 4 -> 2.5 -> 2 (-0.5) -> -1
// 5 -> 3.0 -> 2 (-1.0) -> -1 // 5 -> 3.0 -> 2 (-1.0) -> -1
// 6 -> 3.5 -> 3 (-0.5) -> -1 // 6 -> 3.5 -> 3 (-0.5) -> -1
// 7 -> 4.0 -> 3 (-1.0) -> -1 // 7 -> 4.0 -> 3 (-1.0) -> -1
// 8 -> 4.5 -> 3 (-1.5) -> -2 // 8 -> 4.5 -> 3 (-1.5) -> -2
// 9 -> 5.0 -> 3 (-2.0) -> -2 // 9 -> 5.0 -> 3 (-2.0) -> -2
// 10 -> 5.5 -> 4 (-1.5) -> -2 // 10 -> 5.5 -> 4 (-1.5) -> -2
// 11 -> 6.0 -> 4 (-2.0) -> -2 // 11 -> 6.0 -> 4 (-2.0) -> -2
// 12 -> 6.5 -> 4 (-2.5) -> -3 // 12 -> 6.5 -> 4 (-2.5) -> -3
// 13 -> 7.0 -> 4 (-3.0) -> -3 // 13 -> 7.0 -> 4 (-3.0) -> -3
// //
//// Punctuation appears to be ignored (prepended/appended //// Punctuation appears to be ignored (prepended/appended
//// without affecting ORP). //// without affecting ORP).
//// Using floor() or floats the pattern is confusing as //// Using floor() or floats the pattern is confusing as
//// it appears to both ascend and descend in integer //// it appears to both ascend and descend in integer
//// steps. Using rounding doesn't help, but using ceil //// steps. Using rounding doesn't help, but using ceil
//// there appears to be a pattern of $ (n-(n%4))/4 $. //// there appears to be a pattern of $ (n-(n%4))/4 $.
//// Switching to German gives us a few longer words, //// Switching to German gives us a few longer words,
//// and it appears to hold true for all the examples I //// and it appears to hold true for all the examples I
//// ran through. //// ran through.
if (_symbols) if (_symbols)
{ {
// If _symbols is true, we're considering all characters
// in the word (including symbols) when calculating ORP
strippedWord = ["", _word, ""]; strippedWord = ["", _word, ""];
} }
else else
{ {
strippedWord = sReader_stripPunctuation(_word); strippedWord = sReader_stripPunctuation(_word);
} }
wordCount = strippedWord[1].length; wordLength = strippedWord[1].length; // Length of the word
wordCenter = (wordCount+1)/2; wordCenter = (wordLength+1)/2; // Center of the word
orpBias = -1*(wordCount - wordCount%4)/4; orpBias = -1*(wordLength - wordLength%4)/4; // Offset (see above comment block)
orp = Math.ceil(wordCenter) + orpBias; orp = Math.ceil(wordCenter) + orpBias; // Return value
orp += strippedWord[0].length; orp += strippedWord[0].length; // Account for prefixing symbols
if (debug) if (debug)
{ {
@ -120,30 +140,42 @@ function sReader_calculateOrp(_word, _symbols = false)
console.log("sReader_calculateOrp :: \""+ _word +"\""); console.log("sReader_calculateOrp :: \""+ _word +"\"");
console.log("sReader_calculateOrp :: "+ " ".repeat(orp-1) +"^"); console.log("sReader_calculateOrp :: "+ " ".repeat(orp-1) +"^");
} }
return orp; return orp;
} }
function sReader_printWord(_word, _symbols = false, _iType = "Solid", _iSym = "^", _iCount = 1, _hideText = false) function sReader_printWord(_word, _symbols = false, _iType = "Solid", _iSym = "^", _iCount = 1, _hideText = false)
{ {
// TODO: @sumptum reduce the insane number of parameters being passed in...
// and/or OOPify this mess
indicator = true; indicator = true;
// Redundant variable at the moment
orp = sReader_calculateOrp(_word, _symbols); orp = sReader_calculateOrp(_word, _symbols);
word = [_word.slice(0, orp-1), _word.charAt(orp-1), _word.slice(orp, _word.length)]; word = [_word.slice(0, orp-1), _word.charAt(orp-1), _word.slice(orp, _word.length)];
// Splitting up the word for printing with different colours
htmlBuffer = htmlBuffer =
'<span class="sReader_text" style="color: #111;">'+ word[0].trim() +'</span>'+ '<span class="sReader_text" style="color: #111;">'+ word[0].trim() +'</span>'+
'<span class="sReader_text" style="color: #333;">'+ word[1].trim() +'</span>'+ '<span class="sReader_text" style="color: #333;">'+ word[1].trim() +'</span>'+
'<span class="sReader_text" style="color: #111;">'+ word[2].trim() +'</span>'+ '<span class="sReader_text" style="color: #111;">'+ word[2].trim() +'</span>'+
'<br>' ; '<br>' ;
if (indicator) if (indicator)
{ {
indicatorBuffer = '<span class="i">'+ _iSym +'</span>'; indicatorBuffer = '<span class="i">'+ _iSym +'</span>';
// Each indicator symbol is given it's own class for animation/styling purposes
htmlBuffer += '<span class="indicator indicator'+_iType+'">'+ " ".repeat(orp-1) + indicatorBuffer.repeat(_iCount) +'</span>'; htmlBuffer += '<span class="indicator indicator'+_iType+'">'+ " ".repeat(orp-1) + indicatorBuffer.repeat(_iCount) +'</span>';
// Here the indicator is offset by the ORP value as well, so that it lines up
// underneath the word at the ORP
} }
document.getElementById("sReader_outputText").innerHTML = htmlBuffer; document.getElementById("sReader_outputText").innerHTML = htmlBuffer;
document.getElementById("sReader_outputTextDiv").style.marginLeft = -1*((document.getElementById("sReader_outputText").clientWidth/_word.length)*orp) +"px"; document.getElementById("sReader_outputTextDiv").style.marginLeft = -1*((document.getElementById("sReader_outputText").clientWidth/_word.length)*orp) +"px";
// Not sure this was necessary, appeared when doing some CSS wrangling
// TODO: @sumptum remove/clean up extra div if unnecessary
if (_hideText) if (_hideText)
{ {
el = document.getElementsByClassName("sReader_text"); el = document.getElementsByClassName("sReader_text");
// Hide each part of the text
// TODO: @sumptum maybe this could be used for some interesting flickering transition?
// (if not too distracting)
for (i=0; i<el.length; ++i) for (i=0; i<el.length; ++i)
{ {
el[i].style.opacity = "0.00"; el[i].style.opacity = "0.00";
@ -153,41 +185,57 @@ function sReader_printWord(_word, _symbols = false, _iType = "Solid", _iSym = "^
function sReader_printString(_str) function sReader_printString(_str)
{ {
// The useful part! Let's print a sentence.
relativeSpeedPenalty = true; relativeSpeedPenalty = true;
// Fine tuning the speed penalty doesn't seem
// to be necessary, keeping it relative to
// the reading speed works okay. But it could
// be good to set manually with some inputs,
// e.g. numerical / mathematical, although
// the suitability of such data for RSVP is
// debatable
readingSpeed = 120; // Base reading speed in ms readingSpeed = 120; // Base reading speed in ms
speedPenalty = 25; // Used to slow down for longer words speedPenalty = 25; // Used to slow down for longer words
// (applied per character) // (applied per character)
if (relativeSpeedPenalty) if (relativeSpeedPenalty)
{ {
speedPenalty = readingSpeed/4.5; speedPenalty = readingSpeed/4.5;
} }
str = _str.split(" "); str = _str.split(" "); // Get the printable parts of the string
delays = 0; delays = 0; // Keep track of the accumulated delays
for (let i=0; i<=str.length; ++i) for (let i=0; i<=str.length; ++i)
{ {
let subStr = str[i]; let subStr = str[i]; // New variable to stay in scope
let delay = delays; let delay = delays; // Delay to be added when triggering the timer
if (i == str.length) if (i == str.length)
{ {
// We've reached the end of the string
setTimeout( setTimeout(
function() function()
{ {
sReader_printWord("...", true, "Fade", "^", 1, true); sReader_printWord("...", true, "Fade", "^", 1, true);
// Prints an invisible elipsis and uses a Fading animation
// on the indicator
sReader_randomTimer(); sReader_randomTimer();
// Sets up the timer because we'll need it in a second
}, i*readingSpeed+500+delay }, i*readingSpeed+500+delay
); );
setTimeout( setTimeout(
function() function()
{ {
sReader_printWord("...", true, "Blink", ".", 5, true); sReader_printWord("...", true, "Blink", ".", 5, true);
// Changes the indicator to a series of 5 periods,
// randomly blinking
sReader_randomTimer(); sReader_randomTimer();
}, i*readingSpeed+500+1500+delay }, i*readingSpeed+500+1500+delay
); );
} }
else else
{ {
// Printing words
setTimeout( setTimeout(
function() function()
{ {
@ -197,33 +245,33 @@ function sReader_printString(_str)
} }
if (/[,.;-]/g.test(subStr)) if (/[,.;-]/g.test(subStr))
{ {
// We've got a character here, pausing
// to allow the reader to get their
// bearings
delays += speedPenalty*12; delays += speedPenalty*12;
// 12 is a totally arbitrary number,
// but seems about right to me
} }
if (i==0) if (i==0)
{ {
delays += speedPenalty*24; delays += speedPenalty*24;
// Pauses for twice the length of a normal / "symbol" pause at the
// beginning of a string, so the reader doesn't miss the first word
} }
if (subStr!==undefined) if (subStr!==undefined)
{ {
// Making sure we're not about to throw an exception because we've
// hit the end of the array
if (subStr.length > 0) if (subStr.length > 0)
{ {
// At first this only applied to words longer than 4 characters,
// but that resulted in words with fewer than 4 characters being
// hard to adjust independently of longer words.
// Left it here in case I change my mind about relative speed
// penalties per character
delays += (subStr.length)*speedPenalty; delays += (subStr.length)*speedPenalty;
// Adds a speed penalty per character to slow down longer words
} }
} }
} }
}
function printHelloWorld() {
setInterval(
function()
{
sReader_printWord("Hello,");
setTimeout(
function()
{
sReader_printWord("world!");
}, 1000
);
}, 2000
);
} }