81 lines
2.6 KiB
Text
81 lines
2.6 KiB
Text
using Gtk, Colors, Cairo
|
|
import Base.iterate, Base.IteratorSize, Base.IteratorEltype
|
|
|
|
const caps = [c for c in "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
|
|
startfall() = rand() < 0.2
|
|
endfall() = rand() < 0.2
|
|
startblank() = rand() < 0.1
|
|
endblank() = rand() < 0.05
|
|
bechangingchar() = rand() < 0.03
|
|
|
|
struct RainChars chars::Vector{Char} end
|
|
Base.IteratorSize(s::RainChars) = Base.IsInfinite()
|
|
Base.IteratorEltype(s::RainChars) = Char
|
|
function Base.iterate(rain::RainChars, state = (true, false, 0))
|
|
c = '\0'
|
|
isfalling, isblank, blankcount = state
|
|
if isfalling # falling, so feed the column
|
|
if isblank
|
|
c = ' '
|
|
((blankcount += 1) > 12) && (isblank = endblank())
|
|
else
|
|
c = bechangingchar() ? '~' : rand(rain.chars)
|
|
isblank, blankcount = startblank(), 0
|
|
end
|
|
endfall() && (isfalling = false)
|
|
else
|
|
isfalling = startfall()
|
|
end
|
|
return c, (isfalling, isblank, blankcount)
|
|
end
|
|
|
|
function digitalrain()
|
|
mapwidth, mapheight, fontpointsize = 800, 450, 14
|
|
windowmaxx = div(mapwidth, Int(round(fontpointsize * 0.9)))
|
|
windowmaxy = div(mapheight, fontpointsize)
|
|
basebuffer = fill(' ', windowmaxy, windowmaxx)
|
|
bkcolor, rcolor, xcolor = colorant"black", colorant"green", colorant"limegreen"
|
|
|
|
columngenerators = [Iterators.Stateful(RainChars(caps)) for _ in 1:windowmaxx]
|
|
|
|
win = GtkWindow("Digital Rain Effect", mapwidth, mapheight) |>
|
|
(GtkFrame() |> (can = GtkCanvas()))
|
|
set_gtk_property!(can, :expand, true)
|
|
|
|
draw(can) do widget
|
|
ctx = Gtk.getgc(can)
|
|
select_font_face(ctx, "Leonardo\'s mirrorwriting", Cairo.FONT_SLANT_NORMAL,
|
|
Cairo.FONT_WEIGHT_BOLD)
|
|
set_font_size(ctx, fontpointsize)
|
|
set_source(ctx, bkcolor)
|
|
rectangle(ctx, 0, 0, mapwidth, mapheight)
|
|
fill(ctx)
|
|
set_source(ctx, rcolor)
|
|
for i in 1:size(basebuffer)[1], j in 1:size(basebuffer)[2]
|
|
move_to(ctx, j * fontpointsize * 0.9, i * fontpointsize)
|
|
c = basebuffer[i, j]
|
|
if c == '~'
|
|
set_source(ctx, xcolor)
|
|
show_text(ctx, String([rand(caps)]))
|
|
set_source(ctx, rcolor)
|
|
else
|
|
show_text(ctx, String([c]))
|
|
end
|
|
end
|
|
end
|
|
|
|
while true
|
|
for col in 1:windowmaxx
|
|
c = popfirst!(columngenerators[col])
|
|
if c != '\0'
|
|
basebuffer[2:end, col] .= basebuffer[1:end-1, col]
|
|
basebuffer[1, col] = c
|
|
end
|
|
end
|
|
draw(can)
|
|
Gtk.showall(win)
|
|
sleep(0.05)
|
|
end
|
|
end
|
|
|
|
digitalrain()
|