Let's port another Imba 1 app to Imba 2, this time Matrix Rain, a screensaver similar to the Matrix.
You can see it in action here, and the source code of Imba 1 version here.
Imba 1 app.imba
This app uses two components - App (top level) and Stream (a single stream of falling characters), and a few lifecycle hooks, with setInterval, and setup.
There's also a few loose functions with unusually looking let def.
let def random_int(min, max) min + Math.floor( Math.random() * (max - min + 1) ) let def random_katakana String.fromCharCode(random_int(0x30A0, 0x30FF)) let def random_symbols for i in [0..random_int(5, 30)] { v: random_katakana() } tag Stream def render <self css:top=data:y css:left=data:x> for symbol, index in data:symbols <div.symbol .first=(index==0)> symbol:v tag App def setup @streams = [] let x = 10 while x + 30 < window:inner-width @streams.push({ x: x, y: Math.random() * window:inner-height, speed: 10 + Math.random() * 20, symbols: random_symbols() }) x += 30 def mount setInterval(&,10) do for stream in @streams stream:y += stream:speed if stream:y > window:inner-height + stream:symbols:length * 20 stream:symbols = random_symbols() stream:speed = 10 + Math.random() * 20 stream:y = - stream:symbols:length * 20 for symbol in stream:symbols if Math.random() < 0.01 symbol:v = random_katakana() Imba.commit def render <self> for stream in @streams <Stream[stream]> Imba.mount <App> Imba 1 app.scss
There's a bit of unusual styling here, featuring rarely used flex-direction: column-reverse. As usual, SCSS used only for nesting, and not for anything fancy.
@import 'normalize-scss'; @include normalize(); body { overflow: hidden; } .App { background-color: black; height: 100vh; width: 100vw; overflow: hidden; .Stream { position: absolute; display: flex; flex-direction: column-reverse; .symbol { height: 20px; width: 20px; line-height: 20px; position: relative; font-size: 16px; text-align: center; color: #8f4; &.first { color: #dfa; } } } } Imba 2 app.imba
Here's the app ported to Imba 2:
global css body background-color: black overflow: hidden margin: 0 height: 100vh width: 100vw def random_int(min, max) min + Math.floor( Math.random() * (max - min + 1) ) def random_katakana String.fromCharCode(random_int(0x30A0, 0x30FF)) def random_symbols for i in [0 .. random_int(5, 30)] { v: random_katakana() } tag stream prop x prop y prop symbols <self[top:{y}px left:{x}px]> for symbol, index in symbols <div.symbol> symbol.v css position: absolute display: flex flex-direction: column-reverse .symbol height: 20px width: 20px line-height: 20px position: relative font-size: 16px text-align: center color: #8f4 &:first-child color: #dfa tag app def setup streams = [] let x = 10 while x + 30 < window.innerWidth streams.push({ x: x y: Math.random() * window.innerHeight speed: 3 + Math.random() * 5 symbols: random_symbols() }) x += 30 def mount imba.setInterval(&, 10) do for stream in streams stream.y += stream.speed if stream.y > window.innerHeight stream.symbols = random_symbols() stream.speed = 3 + Math.random() * 5 stream.y = - stream.symbols.length * 20 for symbol in stream.symbols if Math.random() < 0.01 symbol.v = random_katakana() <self> for stream in streams <stream x=stream.x y=stream.y symbols=stream.symbols> css height: 100vh width: 100vw overflow: hidden imba.mount <app> Some notes:
- syntax is a bit closer to standard JavaScript
-
imba.setIntervalis like regularsetInterval, except it also tells Imba that properties might have changed. It's a different model of reactivity than Svelte's. - each symbol is wrapped with
{v: ...}to make update in a loop easier - one baffling thing was
<self[top:{y}px left:{x}px]>- I first tried<self[top:{y} left:{x}]>expecting pixels to be the default units, as that's how everything about DOM works, but somehow Imba converted10to40px. Like what an actual fuck? It makes no sense whatsoever. It's some weird Tailwind nonsense, whereh-1meansheight: 0.25rem, and that's4px. That's just totally baffling at framework level. - Imba's CSS has enough SCSS features (like
&:first-child) that there's no need to use SCSS
Source code
Source code is in imba2-matrix-rain repository. At some point I'll try to add GitHub Pages support for it.
Coming next
In the next few episodes I'll try to port a few more Imba 1 apps to Imba 2, and then I guess I'll summarize my thoughts about Imba situation.
Top comments (0)