By adamlubek​
This recipe demonstrates RxJS implementation of Matrix Digital Rain.
​​​​
( StackBlitz )
// RxJS v6+import { interval } from 'rxjs';import { scan } from 'rxjs/operators';import { render } from './html-renderer';import { markForRemoval, updateDrops, updateMatrix } from './matrix';​interval(300).pipe(scan<number, any[]>(matrix => (markForRemoval(matrix),updateDrops(matrix),updateMatrix(matrix)), [])).subscribe(render);
const drop = (x: number, y: number) => ({ x, y, d: [], remove: false });const random = (max: number) => Math.floor(Math.random() * Math.floor(max));const ranodmChar = () => String.fromCharCode(random(128));​export const markForRemoval = matrix =>matrix.forEach(drop => (drop.remove = drop.remove ? true : drop.d.length > 20));export const updateDrops = matrix =>matrix.forEach(drop =>(drop.d = drop.remove? drop.d.slice(1).map(e => ranodmChar()): [ranodmChar(), ...drop.d.map(e => ranodmChar())]));export const updateMatrix = matrix => [...matrix,drop(random(window.innerHeight) / 4, random(window.innerWidth))];
const createElem = drop => {const elem = document.createElement('div');elem.style.position = 'absolute';elem.style.marginTop = drop.x + 'px';elem.style.marginLeft = drop.y + 'px';elem.style.fontSize = '12px';elem.innerHTML = drop.d.reduce((acc, c) => (acc += '<br/>' + c), '');elem.style['color'] = `rgb(21, ${100 + drop.d.length * 10}, 21)`;return elem;};​export const render = matrix => {document.body.innerHTML = '';const container = document.createElement('div');container.style.position = 'relative';matrix.forEach(m => container.appendChild(createElem(m)));document.body.appendChild(container);};