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)