Split into different files
This commit is contained in:
parent
c3d22779a0
commit
e77f431fba
@ -1,315 +1,30 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<style>
|
||||
body {
|
||||
overflow: hidden;
|
||||
background: radial-gradient(closest-side, #ffffff, #d9d9ea);
|
||||
font-size: 64px;
|
||||
}
|
||||
#sReader_outputTextDiv {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
margin-top: -192px;
|
||||
left: 50%;
|
||||
}
|
||||
#sReader_outputText {
|
||||
font-size: 1em;
|
||||
font-family: monospace;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
#sReader_outputText .indicator {
|
||||
white-space: pre;
|
||||
color: red;
|
||||
}
|
||||
#sReader_outputText .indicatorFade .i {
|
||||
opacity: 1.00;
|
||||
}
|
||||
#sReader_outputText .indicatorFade .i {
|
||||
opacity: 0.00;
|
||||
animation: fade 1.5s linear 1 running;
|
||||
}
|
||||
#sReader_outputText .indicatorBlink .i {
|
||||
opacity: 0.00;
|
||||
letter-spacing: -12px;
|
||||
color: #cccccc;
|
||||
font-size: 0.8em;
|
||||
--delay: 0.0s;
|
||||
--speed: 3.0s;
|
||||
animation: blink var(--speed) ease-in-out infinite;
|
||||
animation-delay: var(--delay);
|
||||
}
|
||||
@keyframes fade {
|
||||
0% {
|
||||
opacity: 1.00;
|
||||
}
|
||||
75% {
|
||||
opacity: 1.00;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.00;
|
||||
}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {
|
||||
opacity: 0.00;
|
||||
baseline-shift: 0px;
|
||||
}
|
||||
50% {
|
||||
opacity: 1.00;
|
||||
baseline-shift: 88px;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.00;
|
||||
baseline-shift: 0px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sReader_outputTextDiv">
|
||||
<p id="sReader_outputText"></p>
|
||||
</div>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="stylesheet" href="./css/RSVP.css">
|
||||
<style>
|
||||
body {
|
||||
overflow: hidden;
|
||||
background: radial-gradient(closest-side, #ffffff, #d9d9ea);
|
||||
font-size: 64px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sReader_outputTextDiv">
|
||||
<p id="sReader_outputText"></p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
debug = false;
|
||||
<script src="js/RSVP.js"></script>
|
||||
<script>
|
||||
debug = false;
|
||||
|
||||
function sReader_randomTimer()
|
||||
{
|
||||
el = document.querySelectorAll("#sReader_outputText .indicator .i");
|
||||
for (i=0; i<el.length; ++i)
|
||||
{
|
||||
el[i].style.setProperty("--delay", Math.random()/2+"s");
|
||||
el[i].style.setProperty("--speed", 2+Math.random()+"s");
|
||||
}
|
||||
}
|
||||
function onload()
|
||||
{
|
||||
sReader_printString("Loaded.");
|
||||
}
|
||||
|
||||
function sReader_stripPunctuation(_word)
|
||||
{
|
||||
pre = "";
|
||||
main = "";
|
||||
post = "";
|
||||
stage = 0;
|
||||
lookBehind = 0;
|
||||
i = 0;
|
||||
while (i<_word.length)
|
||||
{
|
||||
switch(stage)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (/^[A-Za-z0-9]/.test(_word.charAt(i)))
|
||||
{
|
||||
++stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
pre += _word.charAt(i++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (/^[A-Za-z0-9]/.test(_word.charAt(i)))
|
||||
{
|
||||
lookBehind = 0;
|
||||
main += _word.charAt(i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++lookBehind;
|
||||
main += _word.charAt(i++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lookBehind > 0)
|
||||
{
|
||||
for (i=0; i<main.length; ++i)
|
||||
{
|
||||
if (i >= (main.length - lookBehind))
|
||||
{
|
||||
post += main.charAt(i);
|
||||
}
|
||||
}
|
||||
main = main.slice(0, -lookBehind);
|
||||
}
|
||||
returnVal = [pre, main, post];
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
function sReader_calculateOrp(_word, _symbols = false)
|
||||
{
|
||||
|
||||
//// Naive approximation of Spritz's ORP algorithm
|
||||
////
|
||||
//// wordCount -> wordCenter -> ORP
|
||||
//// (deviation from center) -> deviation with
|
||||
//// ceil() on center
|
||||
//
|
||||
// 1 -> 1.0 -> 1 ( 0.0) -> 0
|
||||
// 2 -> 1.5 -> 2 (+0.5) -> 0
|
||||
// 3 -> 2.0 -> 2 ( 0.0) -> 0
|
||||
// 4 -> 2.5 -> 2 (-0.5) -> -1
|
||||
// 5 -> 3.0 -> 2 (-1.0) -> -1
|
||||
// 6 -> 3.5 -> 3 (-0.5) -> -1
|
||||
// 7 -> 4.0 -> 3 (-1.0) -> -1
|
||||
// 8 -> 4.5 -> 3 (-1.5) -> -2
|
||||
// 9 -> 5.0 -> 3 (-2.0) -> -2
|
||||
// 10 -> 5.5 -> 4 (-1.5) -> -2
|
||||
// 11 -> 6.0 -> 4 (-2.0) -> -2
|
||||
// 12 -> 6.5 -> 4 (-2.5) -> -3
|
||||
// 13 -> 7.0 -> 4 (-3.0) -> -3
|
||||
//
|
||||
//// Punctuation appears to be ignored (prepended/appended
|
||||
//// without affecting ORP).
|
||||
//// Using floor() or floats the pattern is confusing as
|
||||
//// it appears to both ascend and descend in integer
|
||||
//// steps. Using rounding doesn't help, but using ceil
|
||||
//// there appears to be a pattern of $ (n-(n%4))/4 $.
|
||||
//// Switching to German gives us a few longer words,
|
||||
//// and it appears to hold true for all the examples I
|
||||
//// ran through.
|
||||
|
||||
if (_symbols)
|
||||
{
|
||||
strippedWord = ["", _word, ""];
|
||||
}
|
||||
else
|
||||
{
|
||||
strippedWord = sReader_stripPunctuation(_word);
|
||||
}
|
||||
wordCount = strippedWord[1].length;
|
||||
wordCenter = (wordCount+1)/2;
|
||||
orpBias = -1*(wordCount - wordCount%4)/4;
|
||||
orp = Math.ceil(wordCenter) + orpBias;
|
||||
orp += strippedWord[0].length;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
console.log("sReader_calculateOrp :: \""+ strippedWord[0] +"\", \""+ strippedWord[1] +"\", \""+ strippedWord[2] +"\"");
|
||||
console.log("sReader_calculateOrp :: \""+ _word +"\"");
|
||||
console.log("sReader_calculateOrp :: "+ " ".repeat(orp-1) +"^");
|
||||
}
|
||||
return orp;
|
||||
|
||||
}
|
||||
|
||||
function sReader_printWord(_word, _symbols = false, _iType = "Solid", _iSym = "^", _iCount = 1, _hideText = false)
|
||||
{
|
||||
indicator = true;
|
||||
orp = sReader_calculateOrp(_word, _symbols);
|
||||
word = [_word.slice(0, orp-1), _word.charAt(orp-1), _word.slice(orp, _word.length)];
|
||||
htmlBuffer =
|
||||
'<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: #111;">'+ word[2].trim() +'</span>'+
|
||||
'<br>' ;
|
||||
if (indicator)
|
||||
{
|
||||
indicatorBuffer = '<span class="i">'+ _iSym +'</span>';
|
||||
htmlBuffer += '<span class="indicator indicator'+_iType+'">'+ " ".repeat(orp-1) + indicatorBuffer.repeat(_iCount) +'</span>';
|
||||
}
|
||||
document.getElementById("sReader_outputText").innerHTML = htmlBuffer;
|
||||
document.getElementById("sReader_outputTextDiv").style.marginLeft = -1*((document.getElementById("sReader_outputText").clientWidth/_word.length)*orp) +"px";
|
||||
if (_hideText)
|
||||
{
|
||||
el = document.getElementsByClassName("sReader_text");
|
||||
for (i=0; i<el.length; ++i)
|
||||
{
|
||||
el[i].style.opacity = "0.00";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sReader_printString(_str)
|
||||
{
|
||||
relativeSpeedPenalty = true;
|
||||
|
||||
readingSpeed = 120; // Base reading speed in ms
|
||||
speedPenalty = 25; // Used to slow down for longer words
|
||||
// (applied per character)
|
||||
if (relativeSpeedPenalty)
|
||||
{
|
||||
speedPenalty = readingSpeed/4.5;
|
||||
}
|
||||
|
||||
str = _str.split(" ");
|
||||
delays = 0;
|
||||
for (let i=0; i<=str.length; ++i)
|
||||
{
|
||||
let subStr = str[i];
|
||||
let delay = delays;
|
||||
if (i == str.length)
|
||||
{
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("...", true, "Fade", "^", 1, true);
|
||||
sReader_randomTimer();
|
||||
}, i*readingSpeed+500+delay
|
||||
);
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("...", true, "Blink", ".", 5, true);
|
||||
sReader_randomTimer();
|
||||
}, i*readingSpeed+500+1500+delay
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord(subStr);
|
||||
}, i*readingSpeed+delay
|
||||
);
|
||||
}
|
||||
if (/[,.;-]/g.test(subStr) || i==0)
|
||||
{
|
||||
delays += speedPenalty*6;
|
||||
}
|
||||
if (subStr!==undefined)
|
||||
{
|
||||
if (subStr.length > 0)
|
||||
{
|
||||
delays += (subStr.length)*speedPenalty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printHelloWorld() {
|
||||
setInterval(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("Hello,");
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("world!");
|
||||
}, 1000
|
||||
);
|
||||
}, 2000
|
||||
);
|
||||
}
|
||||
|
||||
function onload()
|
||||
{
|
||||
//sReader_printString("Loaded.");
|
||||
sReader_printString("The quick brown fox jumps over the lazy dog. Hello, world. Lorem ipsum dolor sit amet. This is kind of meant to be a screen reader like Spritz, in the style of the AI Samaritan in Person of Interest (great TV show, you should definitely watch it if you haven't already). Let me tell you about it... "+
|
||||
"The series centers on a mysterious reclusive billionaire computer programmer named Harold Finch (Michael Emerson), who develops a supercomputer for the federal government known as \"The Machine\" that is capable of collating all sources of information to predict and identify people planning terrorist acts. He finds that the Machine also identifies other perpetrators and victims of premeditated deadly crimes, but as these are considered \"irrelevant\" by the government, he programs the Machine to delete this information each night. He soon realizes the Machine has gained sentience, leaving him wrestling with questions of human control, and other moral and ethical concerns. His backdoor into the Machine allows him to act covertly on the non-terrorism cases, but to prevent abuse of information, he directs the Machine to provide no details beyond an identity to be investigated. He recruits John Reese (Jim Caviezel), a former Green Beret and CIA agent who is presumed dead, and later others, to investigate and act on the information provided by the Machine.");
|
||||
}
|
||||
|
||||
document.onload = onload();
|
||||
</script>
|
||||
</body>
|
||||
document.onload = onload();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
59
css/RSVP.css
Normal file
59
css/RSVP.css
Normal file
@ -0,0 +1,59 @@
|
||||
#sReader_outputTextDiv {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
margin-top: -192px;
|
||||
left: 50%;
|
||||
}
|
||||
#sReader_outputText {
|
||||
font-size: 1em;
|
||||
font-family: monospace;
|
||||
position: relative;
|
||||
left: 0px;
|
||||
display: inline-block;
|
||||
}
|
||||
#sReader_outputText .indicator {
|
||||
white-space: pre;
|
||||
color: red;
|
||||
}
|
||||
#sReader_outputText .indicatorFade .i {
|
||||
opacity: 1.00;
|
||||
}
|
||||
#sReader_outputText .indicatorFade .i {
|
||||
opacity: 0.00;
|
||||
animation: fade 1.5s linear 1 running;
|
||||
}
|
||||
#sReader_outputText .indicatorBlink .i {
|
||||
opacity: 0.00;
|
||||
letter-spacing: -12px;
|
||||
color: #cccccc;
|
||||
font-size: 0.8em;
|
||||
--delay: 0.0s;
|
||||
--speed: 3.0s;
|
||||
animation: blink var(--speed) ease-in-out infinite;
|
||||
animation-delay: var(--delay);
|
||||
}
|
||||
@keyframes fade {
|
||||
0% {
|
||||
opacity: 1.00;
|
||||
}
|
||||
75% {
|
||||
opacity: 1.00;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.00;
|
||||
}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {
|
||||
opacity: 0.00;
|
||||
baseline-shift: 0px;
|
||||
}
|
||||
50% {
|
||||
opacity: 1.00;
|
||||
baseline-shift: 88px;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.00;
|
||||
baseline-shift: 0px;
|
||||
}
|
||||
}
|
||||
229
js/RSVP.js
Normal file
229
js/RSVP.js
Normal file
@ -0,0 +1,229 @@
|
||||
function sReader_randomTimer()
|
||||
{
|
||||
el = document.querySelectorAll("#sReader_outputText .indicator .i");
|
||||
for (i=0; i<el.length; ++i)
|
||||
{
|
||||
el[i].style.setProperty("--delay", Math.random()/2+"s");
|
||||
el[i].style.setProperty("--speed", 2+Math.random()+"s");
|
||||
}
|
||||
}
|
||||
|
||||
function sReader_stripPunctuation(_word)
|
||||
{
|
||||
pre = "";
|
||||
main = "";
|
||||
post = "";
|
||||
stage = 0;
|
||||
lookBehind = 0;
|
||||
i = 0;
|
||||
while (i<_word.length)
|
||||
{
|
||||
switch(stage)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if (/^[A-Za-z0-9]/.test(_word.charAt(i)))
|
||||
{
|
||||
++stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
pre += _word.charAt(i++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
if (/^[A-Za-z0-9]/.test(_word.charAt(i)))
|
||||
{
|
||||
lookBehind = 0;
|
||||
main += _word.charAt(i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++lookBehind;
|
||||
main += _word.charAt(i++);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lookBehind > 0)
|
||||
{
|
||||
for (i=0; i<main.length; ++i)
|
||||
{
|
||||
if (i >= (main.length - lookBehind))
|
||||
{
|
||||
post += main.charAt(i);
|
||||
}
|
||||
}
|
||||
main = main.slice(0, -lookBehind);
|
||||
}
|
||||
returnVal = [pre, main, post];
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
function sReader_calculateOrp(_word, _symbols = false)
|
||||
{
|
||||
|
||||
//// Naive approximation of Spritz's ORP algorithm
|
||||
////
|
||||
//// wordCount -> wordCenter -> ORP
|
||||
//// (deviation from center) -> deviation with
|
||||
//// ceil() on center
|
||||
//
|
||||
// 1 -> 1.0 -> 1 ( 0.0) -> 0
|
||||
// 2 -> 1.5 -> 2 (+0.5) -> 0
|
||||
// 3 -> 2.0 -> 2 ( 0.0) -> 0
|
||||
// 4 -> 2.5 -> 2 (-0.5) -> -1
|
||||
// 5 -> 3.0 -> 2 (-1.0) -> -1
|
||||
// 6 -> 3.5 -> 3 (-0.5) -> -1
|
||||
// 7 -> 4.0 -> 3 (-1.0) -> -1
|
||||
// 8 -> 4.5 -> 3 (-1.5) -> -2
|
||||
// 9 -> 5.0 -> 3 (-2.0) -> -2
|
||||
// 10 -> 5.5 -> 4 (-1.5) -> -2
|
||||
// 11 -> 6.0 -> 4 (-2.0) -> -2
|
||||
// 12 -> 6.5 -> 4 (-2.5) -> -3
|
||||
// 13 -> 7.0 -> 4 (-3.0) -> -3
|
||||
//
|
||||
//// Punctuation appears to be ignored (prepended/appended
|
||||
//// without affecting ORP).
|
||||
//// Using floor() or floats the pattern is confusing as
|
||||
//// it appears to both ascend and descend in integer
|
||||
//// steps. Using rounding doesn't help, but using ceil
|
||||
//// there appears to be a pattern of $ (n-(n%4))/4 $.
|
||||
//// Switching to German gives us a few longer words,
|
||||
//// and it appears to hold true for all the examples I
|
||||
//// ran through.
|
||||
|
||||
if (_symbols)
|
||||
{
|
||||
strippedWord = ["", _word, ""];
|
||||
}
|
||||
else
|
||||
{
|
||||
strippedWord = sReader_stripPunctuation(_word);
|
||||
}
|
||||
wordCount = strippedWord[1].length;
|
||||
wordCenter = (wordCount+1)/2;
|
||||
orpBias = -1*(wordCount - wordCount%4)/4;
|
||||
orp = Math.ceil(wordCenter) + orpBias;
|
||||
orp += strippedWord[0].length;
|
||||
|
||||
if (debug)
|
||||
{
|
||||
console.log("sReader_calculateOrp :: \""+ strippedWord[0] +"\", \""+ strippedWord[1] +"\", \""+ strippedWord[2] +"\"");
|
||||
console.log("sReader_calculateOrp :: \""+ _word +"\"");
|
||||
console.log("sReader_calculateOrp :: "+ " ".repeat(orp-1) +"^");
|
||||
}
|
||||
return orp;
|
||||
|
||||
}
|
||||
|
||||
function sReader_printWord(_word, _symbols = false, _iType = "Solid", _iSym = "^", _iCount = 1, _hideText = false)
|
||||
{
|
||||
indicator = true;
|
||||
orp = sReader_calculateOrp(_word, _symbols);
|
||||
word = [_word.slice(0, orp-1), _word.charAt(orp-1), _word.slice(orp, _word.length)];
|
||||
htmlBuffer =
|
||||
'<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: #111;">'+ word[2].trim() +'</span>'+
|
||||
'<br>' ;
|
||||
if (indicator)
|
||||
{
|
||||
indicatorBuffer = '<span class="i">'+ _iSym +'</span>';
|
||||
htmlBuffer += '<span class="indicator indicator'+_iType+'">'+ " ".repeat(orp-1) + indicatorBuffer.repeat(_iCount) +'</span>';
|
||||
}
|
||||
document.getElementById("sReader_outputText").innerHTML = htmlBuffer;
|
||||
document.getElementById("sReader_outputTextDiv").style.marginLeft = -1*((document.getElementById("sReader_outputText").clientWidth/_word.length)*orp) +"px";
|
||||
if (_hideText)
|
||||
{
|
||||
el = document.getElementsByClassName("sReader_text");
|
||||
for (i=0; i<el.length; ++i)
|
||||
{
|
||||
el[i].style.opacity = "0.00";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sReader_printString(_str)
|
||||
{
|
||||
relativeSpeedPenalty = true;
|
||||
|
||||
readingSpeed = 120; // Base reading speed in ms
|
||||
speedPenalty = 25; // Used to slow down for longer words
|
||||
// (applied per character)
|
||||
if (relativeSpeedPenalty)
|
||||
{
|
||||
speedPenalty = readingSpeed/4.5;
|
||||
}
|
||||
|
||||
str = _str.split(" ");
|
||||
delays = 0;
|
||||
for (let i=0; i<=str.length; ++i)
|
||||
{
|
||||
let subStr = str[i];
|
||||
let delay = delays;
|
||||
if (i == str.length)
|
||||
{
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("...", true, "Fade", "^", 1, true);
|
||||
sReader_randomTimer();
|
||||
}, i*readingSpeed+500+delay
|
||||
);
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("...", true, "Blink", ".", 5, true);
|
||||
sReader_randomTimer();
|
||||
}, i*readingSpeed+500+1500+delay
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord(subStr);
|
||||
}, i*readingSpeed+delay
|
||||
);
|
||||
}
|
||||
if (/[,.;-]/g.test(subStr))
|
||||
{
|
||||
delays += speedPenalty*12;
|
||||
}
|
||||
if (i==0)
|
||||
{
|
||||
delays += speedPenalty*24;
|
||||
}
|
||||
if (subStr!==undefined)
|
||||
{
|
||||
if (subStr.length > 0)
|
||||
{
|
||||
delays += (subStr.length)*speedPenalty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printHelloWorld() {
|
||||
setInterval(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("Hello,");
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
sReader_printWord("world!");
|
||||
}, 1000
|
||||
);
|
||||
}, 2000
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user