u(t) is called 60 times per second.
t: Elapsed time in seconds.
S: Shorthand for Math.sin.
C: Shorthand for Math.cos.
T: Shorthand for Math.tan.
R: Function that generates rgba-strings, usage ex.: R(255, 255, 255, 0.5)
c: A 1920x1080 canvas.
x: A 2D context for that canvas.
The cipher is the simplest way I could think of making a stream cipher, where the keystream is just one 32bit LFSR seeded with the "key". The key is the ascii encoding of a string truncated to 32bits. This is combined (ok it's XORed) with the plaintext, but something else is done to preserve the printability in ASCII encoding. So the unknowns here are message and key (but you can guess them, they are on the page) and the 32bit LFSR used and how it's combined with the plaintext.
As far as I understand this is fundamentally insecure because the PRNG is a single LFSR, which makes the entire keystream linear and susceptible to cryptanalysis methods i'm not familiar with.
Converting key from string to 32bit int for LFSR PRNG: x = parseInt([...key.slice(0,4)].map(c => c.charCodeAt(0).toString(2).padStart(8, 0)).join(''), 2)
Only piece left is which 32bit LFSR is used to generate keystream x.
u(t) is called 60 times per second.
t: elapsed time in seconds.
c: A 1920x1080 canvas.
x: A 2D context for that canvas.
S: Math.sin
C: Math.cos
T: Math.tan
R: Generates rgba-strings, ex.: R(255, 255, 255, 0.5)