Published
Edited
Apr 27, 2021
2 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`----
## O K O K O K O K O
## K O K O K O K O K
## O K O K O K O K O
## K O K O K O K O K
## O K O K O K O K O
## K O K O K O K O K
## O K O K O K O K O
## K O K O K O K O K
## O K O K O K O K O
`
Insert cell
md`Then the attempt will be to flicker between *O K O* and *E Y E.* The letter **O** flips with **E** and **K** with **Y** at "random" rates. This is a poem that translates itself.

**OK NOT RANDOM RATES!** To get a timing on the flicker, I will make a recording of my face and then say "blink" every time I blink. **Update this is up on REDUCT under "blink"....now to get the timings over to here...** I will then put this recording into **reduct** and get the time stamps on each word. We can use that time stamp on a loop and have the letters click one at a time. at random or maybe two at a time (we can try and see what works!) until the entire *O K O* turns into *E Y E* and then we can click backwards and have it go back into *O K O*`
Insert cell
(eyopulse,
rs`----
## (O|E) (K|Y) (O|E) (K|Y) (O|E)
## (K|Y) (O|E) (K|Y) (O|E) (K|Y)
## (O|E) (K|Y) (O|E) (K|Y) (O|E)
`)
Insert cell
seconds = .5
Insert cell
eyopulse = pulse(seconds * 1000)
Insert cell
gridSize = 9
Insert cell
inflectedOko = true;
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
eyeClosed = (gi, blinkLang, factor = 1) => {
let p = new RegExp(langs[blinkLang].pattern);
let result = true;
for (let i = 0; i < (3 * factor); i = i + factor) {
if (p.test(textOf(gi + i))) {
result = false;
break;
}
}
return result;
}
Insert cell
Insert cell
langs = ({
en: { letter1: "E", pattern: "[EY]" },
po: { letter1: "O", pattern: "[OKUA]" }
})
Insert cell
textOf = (gi) => laob_display.children[gi].innerText
Insert cell
setHtmlOf = (gi, value) => laob_display.children[gi].innerHTML = value;
Insert cell
Insert cell
Insert cell
Insert cell
okoye = html`<div style="font: bold 5vw/1.4 Didot">EY<span style="color: red">OKO</span></div>`
Insert cell
okoye.innerText
Insert cell
{ let i = 0;
while (true) {
await Promises.tick(3000).then(() => {okoye.innerHTML = (okoye.innerText == "EYEKO") ? `EY<span style="color: red">OKO</span>` : `EYE<span style="color: red">KO</span>`; return "working"});
}
}
Insert cell
Insert cell
css = html`
<style>

h2 {
font-family: "Courier New";
}

.display {
white-space: break-spaces;
font-family: "Courier New";
font-size: 5vw;
}

.grid {
display: grid;
color: red;
font-family: Didot;
font-size: 5vw;
font-weight: bold;
line-height: 1em;
grid-template-columns: 1em 1em 1em 1em 1em 1em 1em 1em 1em;
}

.gridItem {
overflow: hidden:
height: 1em;
transition: height 1s linear;
}

.gridItem.squish {
height: 1px;
}

</style>
`
Insert cell
display = // making this 'display' in html cause it is easier to control
// style as needed with css
html`
<hr>
<div class="display">O K O K O
O K O K O
O K O K O
O K O K O</div>
<hr>`
Insert cell
Insert cell
// just to show what this evaluates to:
swap(display.innerText)
Insert cell
swap = function(eyeText, lang) {
// following line is a quick hack for grid-based blink piece
// would not work for eyeText longer than one letter
if (lang !== undefined && new RegExp(langs[lang].pattern).test(eyeText)) return eyeText;
let oldText = Array.from(eyeText)
let newText = [];
for (let i = 0; i < oldText.length; i++) {
// could be done more 'elegantly'
switch (oldText[i]) {
case "K":
newText.push("Y");
break;
case "E":
newText.push("O");
break;
case "Y":
newText.push("K");
break;
default:
newText.push("E"); // for O, A or U
}
}
return newText.join("");
}
Insert cell
reductJson = ({"segments": [{"speaker_id": "Speaker 1", "speaker_name": "Speaker 1", "wdlist": [{"start": 6.35, "end": 6.79, "word": "blink "}, {"start": 7.989999999999999, "end": 8.309999999999999, "word": "blink, "}, {"start": 9.41, "end": 9.86, "word": "blink "}, {"start": 11.309999999999999, "end": 11.739999999999998, "word": "blink, "}, {"start": 14.43, "end": 14.79, "word": "blink, "}, {"start": 14.84, "end": 15.28, "word": "blink, "}, {"start": 15.58, "end": 16.009999999999998, "word": "blink, "}, {"start": 16.35, "end": 16.759999999999998, "word": "blink, "}, {"start": 16.93, "end": 17.4, "word": "blink, "}, {"start": 17.68, "end": 18.11, "word": "blink, "}, {"start": 20.119999999999997, "end": 20.54, "word": "blink, "}, {"start": 21.79, "end": 22.229999999999997, "word": "blink, "}, {"start": 23.259999999999998, "end": 23.68, "word": "blink, "}, {"start": 24.719999, "end": 25.119999, "word": "blink, "}, {"start": 25.28, "end": 25.659999999999997, "word": "blink, "}, {"start": 26.47, "end": 26.810000000000002, "word": "blink, "}, {"start": 28.25, "end": 28.629999999999995, "word": "blink, "}, {"start": 31.869999999999997, "end": 32.3, "word": "blink, "}, {"start": 32.46, "end": 32.76, "word": "blink, "}, {"start": 33.11, "end": 33.47, "word": "blink, "}, {"start": 33.47, "end": 33.519999999999996, "word": "blink, "}, {"start": 33.519999999999996, "end": 33.57, "word": "blink, ", "unaligned": true}, {"start": 33.57, "end": 33.62, "word": "blink, ", "unaligned": true}, {"start": 33.62, "end": 33.67, "word": "blink. ", "unaligned": true}], "start": 6.35, "end": 33.67, "tx_id": "1619107914032635331", "media_id": "8816b49c1341"}]})
Insert cell
makeAlignedWordedFrom = function(reductJson, secondsAtEndOfText = 3) {
let a = [];
Object.keys(reductJson).forEach(segments => {
reductJson[segments].forEach(speech => {
a = a.concat(speech.wdlist);
});
});
a.forEach((word, index) => {
word.word = word.word.trim();
index < a.length - 1
? (word.gap = a[index + 1].start - word.end)
: (word.gap = secondsAtEndOfText);
word.unit = "u" + index;
});
return a;
}
Insert cell
Insert cell
pauses = makeBlinkPausesFrom(makeAlignedWordedFrom(reductJson))
Insert cell
import { pulse, rs, heads, shuffle } from "@dla/imports"
Insert cell
import { randIntBetween } from "@dla/functions"
Insert cell
import { Button } from "@observablehq/inputs"
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more