feat: change to fullscreen and progressive rendering

This commit is contained in:
sigmasternchen 2024-12-12 23:57:57 +01:00
parent 4211fc3074
commit 68f7c53c64
3 changed files with 122 additions and 26 deletions

9
dist/index.html vendored
View file

@ -2,6 +2,15 @@
<html>
<head>
<title>Queer Mandelbrot</title>
<style>
#mandelbrot {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
</style>
</head>
<body>
<canvas id="mandelbrot" width="600" height="400"></canvas>

View file

@ -2,7 +2,36 @@
export const getContext = (id) =>
document.getElementById(id).getContext("2d");
export const getInnerWidth = () =>
window.innerWidth;
export const getInnerHeight = () =>
window.innerHeight;
export const onResize = (callback) =>
window.addEventListener("resize", callback);
export const setPixel = (ctx, x, y, color) => {
ctx.fillStyle = color;
ctx.fillRect(x, y, 1, 1);
};
export const clear = (ctx) => {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
};
export const setSize = (ctx, width, height) => {
ctx.canvas.width = width;
ctx.canvas.height = height;
};
export const requestAnimationFrame = (callback) => {
let eventListener = () => {
callback();
window.removeEventListener("message", eventListener);
}
window.addEventListener("message", eventListener)
window.postMessage(null);
};
//window.requestAnimationFrame;

View file

@ -70,41 +70,81 @@ fn value_to_color(colorscheme: ColorScheme, value: Int) -> String {
}
}
pub fn main() {
fn animate_for_each(
list: List(a),
still_valid: fn() -> Bool,
callback: fn(a) -> Nil,
) -> Nil {
case list, still_valid() {
_, False -> Nil
[], True -> Nil
[head, ..rest], True -> {
callback(head)
request_animation_frame(fn() {
animate_for_each(rest, still_valid, callback)
})
}
}
}
fn redraw(ctx: Context2D, canvas_width: Int, canvas_height: Int) {
let colorscheme = Lesbian
let ctx = get_context("mandelbrot")
set_size(ctx, canvas_width, canvas_height)
clear(ctx)
let canvas_width = 600
let canvas_height = 400
let min_x = -2.0
let max_x = 1.0
let min_y = -1.0
let max_y = 1.0
list.range(0, canvas_width - 1)
|> list.each(fn(x) {
list.range(0, canvas_height - 1)
|> list.each(fn(y) {
let location =
Complex(
real: int.to_float(x)
/. int.to_float(canvas_width)
*. { max_x -. min_x }
+. min_x,
imaginary: int.to_float(y)
/. int.to_float(canvas_height)
*. { max_y -. min_y }
+. min_y,
)
let value = get_mandelbrot_value(location, 1000.0, Complex(0.0, 0.0), 0)
case value {
Converges -> set_pixel(ctx, x, y, "#000")
Diverges(value) ->
set_pixel(ctx, x, y, value_to_color(colorscheme, value))
}
})
})
|> list.sized_chunk(1)
|> animate_for_each(
fn() {
get_inner_width() == canvas_width && get_inner_height() == canvas_height
},
list.each(_, fn(x) {
io.debug(x)
list.range(0, canvas_height - 1)
|> list.each(fn(y) {
let pad_horizontal =
{ max_x -. min_x } /. { max_y -. min_y }
<. int.to_float(canvas_width) /. int.to_float(canvas_height)
let #(sizing_factor, x_offset, y_offset) = case pad_horizontal {
True -> #(canvas_height, min_x, min_y)
False -> #(canvas_width, min_x, min_y)
}
let location =
Complex(
real: int.to_float(x)
/. int.to_float(sizing_factor)
*. { max_x -. min_x }
+. x_offset,
imaginary: int.to_float(y)
/. int.to_float(sizing_factor)
*. { max_y -. min_y }
+. y_offset,
)
let value = get_mandelbrot_value(location, 1000.0, Complex(0.0, 0.0), 0)
case value {
Converges -> set_pixel(ctx, x, y, "#000")
Diverges(value) ->
set_pixel(ctx, x, y, value_to_color(colorscheme, value))
}
})
}),
)
}
pub fn main() {
let ctx = get_context("mandelbrot")
redraw(ctx, get_inner_width(), get_inner_height())
on_resize(fn() { redraw(ctx, get_inner_width(), get_inner_height()) })
}
type Context2D
@ -112,5 +152,23 @@ type Context2D
@external(javascript, "./canvas.mjs", "getContext")
fn get_context(id: String) -> Context2D
@external(javascript, "./canvas.mjs", "getInnerWidth")
fn get_inner_width() -> Int
@external(javascript, "./canvas.mjs", "getInnerHeight")
fn get_inner_height() -> Int
@external(javascript, "./canvas.mjs", "onResize")
fn on_resize(callback: fn() -> Nil) -> Nil
@external(javascript, "./canvas.mjs", "setPixel")
fn set_pixel(ctx: Context2D, x: Int, y: Int, color: String) -> Nil
@external(javascript, "./canvas.mjs", "clear")
fn clear(ctx: Context2D) -> Nil
@external(javascript, "./canvas.mjs", "setSize")
fn set_size(ctx: Context2D, width: Int, height: Int) -> Nil
@external(javascript, "./canvas.mjs", "requestAnimationFrame")
fn request_animation_frame(callback: fn() -> Nil) -> Nil