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.setInterval
is 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 converted10
to40px
. Like what an actual fuck? It makes no sense whatsoever. It's some weird Tailwind nonsense, whereh-1
meansheight: 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)