Skip to content

Commit

Permalink
format, refactor, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
Rudxain authored Jan 24, 2024
1 parent 529fef6 commit a7702fd
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 67 deletions.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@
</div>

## ▶️Demo
### Desktop
![](res/demo_horizontal.png)
### Mobile
![](res/demo_vertical.png)
![](res/demo.png)

## ℹUsage
You can [go to the website](https://Rudxain.github.io/RGB-digital-rain), or [⬇download](https://github.com/Rudxain/RGB-digital-rain/archive/refs/heads/main.zip) this branch as a zip. If you downloaded the zip, then extract it, then open `src/index.html` in your 🌐browser of choice.
Expand Down
Binary file added res/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 2 additions & 6 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,15 @@
<meta property=og:image:width content=1920>
<meta property=og:image:height content=1080>
<meta property=og:image:alt content='Desktop demo of The Matrix RGB digital rain'>
<meta property=og:image content=https://Rudxain.github.io/RGB-digital-rain/res/demo_vertical.png>
<meta property=og:image:width content=720>
<meta property=og:image:height content=1280>
<meta property=og:image:alt content='Mobile demo of The Matrix RGB digital rain'>

<meta name=color-scheme content='light dark'>
<meta name=theme-color content=#0f0>
<link rel=stylesheet href=style.css>
</head>

<body>
<canvas id=c>Update browser or enable JS</canvas>
<canvas id=c>Enable JS Canvas</canvas>
<script src=main.js></script>
</body>

</HTML>
</HTML>
19 changes: 5 additions & 14 deletions src/m.webmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,11 @@
"background_color": "#000",
"theme_color": "#0f0",
"display": "fullscreen",
"screenshots": [
{
"src": "/res/demo_horizontal.png",
"screenshots": [{
"src": "/res/demo.png",
"type": "image/png",
"sizes": "1920x1080",
"platform": "wide",
"label": "Desktop demo of RGB digital rain"
},
{
"src": "/res/demo_vertical.png",
"type": "image/png",
"sizes": "720x1280",
"platform": "narrow",
"label": "Mobile demo of RGB digital rain"
}
]
}
"label": "Demo of RGB-DR"
}]
}
80 changes: 37 additions & 43 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@
'use strict'
// global/public, for debugging/testing purposes
const RGBDR_anim = (() => {
const rng = Math.random

/** Returns a pseudorandom 32-bit unsigned integer between `min` and `max`. */
const randomUint32 = (min = 0, max = 2 ** 32) => (rng() * (max - min) + min) >>> 0

/**
Get a pseudo-random UTF-16 code-unit from a `string`.
@param {string} s
*/
const rand_CU_pick = s => s[rng() * s.length >>> 0]
// To simplify optimization by the engine,
// I call `rng`, rather than `randomUint32`.
// `trunc`/`floor` are misleading since index is always a u32,
// that's I use `>>>0`.

/**
Convert Hertz to corresponding mili-seconds
@param {number} f frequency
@return interval
*/
const Hz_to_ms = f => 1000 / f

/**
coerce `x` to u8, then hex-encode it with padding
@param {number} x
*/
const hex_byte = x => (x & 0xff).toString(16).padStart(2, '0')


const DOC = document, RAF = requestAnimationFrame

const canv = /**@type {HTMLCanvasElement}*/(DOC.getElementById('c'))
Expand Down Expand Up @@ -30,15 +59,10 @@ const RGBDR_anim = (() => {
playing = b

if (!prev && b) {
/**
Convert Hertz to corresponding mili-seconds
@param {number} f frequency
@return interval
*/
const Hz_to_ms = f => 1000 / f
// order matters
RAF(full_dimmer)
// the interval ensures `drawChars` is independent of FPS
it_ID = setInterval(draw_chars, Hz_to_ms(a.settings.char_speed_Hz))
RAF(full_dimmer)
}
if (prev && !b)
clearInterval(it_ID)
Expand All @@ -49,7 +73,7 @@ const RGBDR_anim = (() => {
it's defined here, instead of outside the IIFE's closure.
*/
settings: {
/** `Array` of CSS hex colors */
/** hex */
colors: ['f00', 'ff0', '0f0', '0ff', '00f', 'f0f'],//🌈RYGCBM
/** character-set/alphabet */
charset:
Expand All @@ -65,7 +89,7 @@ const RGBDR_anim = (() => {
/** dimming coefficient */
dim_factor: 1 * (is_dark ? 1 : -1),
/** miliseconds to debounce until `resize` is called */
resize_delay_ms: 1500
resize_delay_ms: 750
}
}
return a
Expand All @@ -85,7 +109,7 @@ const RGBDR_anim = (() => {
/**
Set `canv` dimensions to fill the full viewport.
Resize `height_ls` accordingly, padding with 0.
Resize `height_ls` accordingly, padding with `0`.
Resize `color_i_ls` accordingly, padding with `index mod colors.length`.
*/
Expand All @@ -95,8 +119,9 @@ const RGBDR_anim = (() => {
// calculate how many columns in the grid are necessary to fill the whole canvas
const columns = Math.ceil(canv.width / anim.settings.grid_px)

// prevent memory/CPU leak caused by race condition
const prev = anim.playing
anim.playing = false // prevent memory/CPU leak caused by race condition
anim.playing = false

//const sleep = (/**@type {number|undefined}*/ ms) => new Promise(_ => setTimeout(_, ms))
/*
Expand All @@ -114,24 +139,15 @@ const RGBDR_anim = (() => {
color_i_ls.push(color_i_ls.length % anim.settings.colors.length)
color_i_ls.length = columns

anim.playing = prev // revert to previous play-state
anim.playing = prev
}

const draw_chars = () => {
const
rng = Math.random,
{ colors, grid_px, charset } = anim.settings

ctx.font = `bold ${grid_px}px monospace`

/** Returns a pseudorandom 32-bit unsigned integer between `min` and `max`. */
const randomUint32 = (min = 0, max = 2 ** 32) => (rng() * (max - min) + min) >>> 0

/**
Get a pseudo-random UTF-16 code-unit from a `string`.
@param {string} s
*/
const rand_CU_pick = s => s[rng() * s.length >>> 0]

// according to MDN docs, `forEach` seems to be thread-safe here (I guess)
height_ls.forEach((y, i) => {
Expand Down Expand Up @@ -166,30 +182,8 @@ const RGBDR_anim = (() => {
/** u8 that specifies how much to dim the canvas */
const dim = Math.round(Math.min((now - t) * Math.abs(df), 0xff))

{
/**
Check if `x` is `-0`, without `Object.is`, for purity.
@param {*} x
*/
const is_neg_zero = x => x === 0 && 1 / x == -Infinity

/**
Check if `x` is an unsigned 8bit int. Returns `false` for `BigInt`s.
@param {*} x
*/
const is_u8 = x => typeof x == 'number' && x == (x & 0xff) && !is_neg_zero(x)
console.assert(is_u8(dim))
}

// performance...
if (dim) {
const HEX_TABLE = '0123456789abcdef'

/**
coerce `x` to u8, then hex-encode it with padding
@param {number} x
*/
const hex_byte = x => HEX_TABLE[(x & 0xff) >> 4] + HEX_TABLE[x & 0xf]

// does hex really has better performance here?
// should I change it to `rgb()` or `hsl()`?
Expand Down

0 comments on commit a7702fd

Please sign in to comment.