mirror of
https://github.com/sigmasternchen/queermandelbrot
synced 2025-03-14 23:48:54 +00:00
first commit
This commit is contained in:
commit
4211fc3074
12 changed files with 267 additions and 0 deletions
23
.github/workflows/test.yml
vendored
Normal file
23
.github/workflows/test.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
name: test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: erlef/setup-beam@v1
|
||||
with:
|
||||
otp-version: "26.0.2"
|
||||
gleam-version: "1.5.1"
|
||||
rebar3-version: "3"
|
||||
# elixir-version: "1.15.4"
|
||||
- run: gleam deps download
|
||||
- run: gleam test
|
||||
- run: gleam format --check src test
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
*.beam
|
||||
*.ez
|
||||
/build
|
||||
erl_crash.dump
|
26
README.md
Normal file
26
README.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# queermandelbrot
|
||||
|
||||
[](https://hex.pm/packages/queermandelbrot)
|
||||
[](https://hexdocs.pm/queermandelbrot/)
|
||||
|
||||
```sh
|
||||
gleam add queermandelbrot@1
|
||||
```
|
||||
```gleam
|
||||
import queermandelbrot
|
||||
|
||||
pub fn main() {
|
||||
// TODO: An example of the project in use
|
||||
}
|
||||
```
|
||||
|
||||
Further documentation can be found at <https://hexdocs.pm/queermandelbrot>.
|
||||
|
||||
## Development
|
||||
|
||||
```sh
|
||||
gleam run -m esgleam/install # Install esbuild dependency
|
||||
gleam build # Build the project to JS
|
||||
gleam run -m build # Create bundle in /dist
|
||||
gleam run -m serve # Start dev webserver on part 8000
|
||||
```
|
1
dist/.gitignore
vendored
Normal file
1
dist/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
queermandelbrot.js
|
10
dist/index.html
vendored
Normal file
10
dist/index.html
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Queer Mandelbrot</title>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="mandelbrot" width="600" height="400"></canvas>
|
||||
<script src="./queermandelbrot.js"></script>
|
||||
</body>
|
||||
</html>
|
21
gleam.toml
Normal file
21
gleam.toml
Normal file
|
@ -0,0 +1,21 @@
|
|||
name = "queermandelbrot"
|
||||
version = "1.0.0"
|
||||
target = "js"
|
||||
|
||||
# Fill out these fields if you intend to generate HTML documentation or publish
|
||||
# your project to the Hex package manager.
|
||||
#
|
||||
# description = ""
|
||||
# licences = ["Apache-2.0"]
|
||||
# repository = { type = "github", user = "", repo = "" }
|
||||
# links = [{ title = "Website", href = "" }]
|
||||
#
|
||||
# For a full reference of all the available options, you can have a look at
|
||||
# https://gleam.run/writing-gleam/gleam-toml/.
|
||||
|
||||
[dependencies]
|
||||
gleam_stdlib = ">= 0.34.0 and < 2.0.0"
|
||||
esgleam = ">= 0.7.0 and < 1.0.0"
|
||||
|
||||
[dev-dependencies]
|
||||
gleeunit = ">= 1.0.0 and < 2.0.0"
|
15
manifest.toml
Normal file
15
manifest.toml
Normal file
|
@ -0,0 +1,15 @@
|
|||
# This file was generated by Gleam
|
||||
# You typically do not need to edit this file
|
||||
|
||||
packages = [
|
||||
{ name = "esgleam", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "simplifile"], otp_app = "esgleam", source = "hex", outer_checksum = "8EBF4DB26902950919B046B2283B0E45B5A49B986AAB6AFB06A729EF254321E6" },
|
||||
{ name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" },
|
||||
{ name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" },
|
||||
{ name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" },
|
||||
{ name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" },
|
||||
]
|
||||
|
||||
[requirements]
|
||||
esgleam = { version = ">= 0.7.0 and < 1.0.0" }
|
||||
gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" }
|
||||
gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
|
10
src/build.gleam
Normal file
10
src/build.gleam
Normal file
|
@ -0,0 +1,10 @@
|
|||
import esgleam
|
||||
|
||||
pub fn main() {
|
||||
esgleam.new("./dist/")
|
||||
|> esgleam.entry("queermandelbrot.gleam")
|
||||
|> esgleam.kind(esgleam.Script)
|
||||
|> esgleam.format(esgleam.Iife)
|
||||
|> esgleam.raw("--outfile=./dist/queermandelbrot.js")
|
||||
|> esgleam.bundle
|
||||
}
|
8
src/canvas.mjs
Normal file
8
src/canvas.mjs
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
export const getContext = (id) =>
|
||||
document.getElementById(id).getContext("2d");
|
||||
|
||||
export const setPixel = (ctx, x, y, color) => {
|
||||
ctx.fillStyle = color;
|
||||
ctx.fillRect(x, y, 1, 1);
|
||||
};
|
22
src/complex.gleam
Normal file
22
src/complex.gleam
Normal file
|
@ -0,0 +1,22 @@
|
|||
import gleam/float
|
||||
|
||||
pub type Complex {
|
||||
Complex(real: Float, imaginary: Float)
|
||||
}
|
||||
|
||||
pub fn add(x: Complex, y: Complex) -> Complex {
|
||||
Complex(real: x.real +. y.real, imaginary: x.imaginary +. y.imaginary)
|
||||
}
|
||||
|
||||
pub fn multiply(x: Complex, y: Complex) -> Complex {
|
||||
Complex(
|
||||
real: x.real *. y.real -. x.imaginary *. y.imaginary,
|
||||
imaginary: x.imaginary *. y.real +. x.real *. y.imaginary,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn absolute(x: Complex) -> Float {
|
||||
let assert Ok(result) =
|
||||
float.square_root(x.real *. x.real +. x.imaginary *. x.imaginary)
|
||||
result
|
||||
}
|
116
src/queermandelbrot.gleam
Normal file
116
src/queermandelbrot.gleam
Normal file
|
@ -0,0 +1,116 @@
|
|||
import gleam/int
|
||||
import gleam/io
|
||||
import gleam/list
|
||||
|
||||
import complex.{type Complex, Complex, absolute, add, multiply}
|
||||
|
||||
type MandelbrotValue {
|
||||
Converges
|
||||
Diverges(Int)
|
||||
}
|
||||
|
||||
fn square(x: Complex) -> Complex {
|
||||
multiply(x, x)
|
||||
}
|
||||
|
||||
fn get_mandelbrot_value(
|
||||
location: Complex,
|
||||
threshold: Float,
|
||||
current: Complex,
|
||||
iteration: Int,
|
||||
) -> MandelbrotValue {
|
||||
case iteration > 100 {
|
||||
True -> Converges
|
||||
False -> {
|
||||
let next = square(current) |> add(location)
|
||||
|
||||
case absolute(next) >. threshold {
|
||||
True -> Diverges(iteration)
|
||||
False -> get_mandelbrot_value(location, threshold, next, iteration + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ColorScheme {
|
||||
Rainbow
|
||||
Trans
|
||||
Lesbian
|
||||
}
|
||||
|
||||
fn value_to_color(colorscheme: ColorScheme, value: Int) -> String {
|
||||
case colorscheme {
|
||||
Rainbow ->
|
||||
case value {
|
||||
n if n < 5 -> "#732982"
|
||||
n if n < 6 -> "#004CFF"
|
||||
n if n < 7 -> "#008026"
|
||||
n if n < 9 -> "#FFED00"
|
||||
n if n < 13 -> "#FF8C00"
|
||||
_ -> "#E40303"
|
||||
}
|
||||
Trans ->
|
||||
case value {
|
||||
n if n < 6 -> "#5BCFFB"
|
||||
n if n < 7 -> "#F5ABB9"
|
||||
n if n < 9 -> "#FFFFFF"
|
||||
n if n < 13 -> "#F5ABB9"
|
||||
_ -> "#5BCFFB"
|
||||
}
|
||||
Lesbian ->
|
||||
case value {
|
||||
n if n < 5 -> "#D52D00"
|
||||
n if n < 6 -> "#EF7627"
|
||||
n if n < 7 -> "#FF9A56"
|
||||
n if n < 8 -> "#FFFFFF"
|
||||
n if n < 9 -> "#D162A4"
|
||||
n if n < 13 -> "#B55690"
|
||||
_ -> "#A30262"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let colorscheme = Lesbian
|
||||
|
||||
let ctx = get_context("mandelbrot")
|
||||
|
||||
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))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
type Context2D
|
||||
|
||||
@external(javascript, "./canvas.mjs", "getContext")
|
||||
fn get_context(id: String) -> Context2D
|
||||
|
||||
@external(javascript, "./canvas.mjs", "setPixel")
|
||||
fn set_pixel(ctx: Context2D, x: Int, y: Int, color: String) -> Nil
|
11
src/serve.gleam
Normal file
11
src/serve.gleam
Normal file
|
@ -0,0 +1,11 @@
|
|||
import esgleam
|
||||
|
||||
pub fn main() {
|
||||
esgleam.new("./dist/")
|
||||
|> esgleam.entry("queermandelbrot.gleam")
|
||||
|> esgleam.kind(esgleam.Script)
|
||||
|> esgleam.format(esgleam.Iife)
|
||||
|> esgleam.raw("--outfile=./dist/queermandelbrot.js")
|
||||
|> esgleam.serve("./dist/")
|
||||
|> esgleam.bundle
|
||||
}
|
Loading…
Reference in a new issue