Comments + other janitorial edits
This commit is contained in:
parent
e77f431fba
commit
7866a4dffb
176
js/RSVP.js
176
js/RSVP.js
@ -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
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user