Mandelbrot set
Julia set
- numpy - paths: - /palettes.py - /fractals.py from pyodide import to_js import numpy as np from palettes import Magma256 from fractals import mandelbrot, julia from js import ( console, document, devicePixelRatio, ImageData, Uint8ClampedArray, CanvasRenderingContext2D as Context2d, ) def create_canvas(width: int, height: int, target: str) -> Context2d: pixel_ratio = devicePixelRatio canvas = document.createElement("canvas") ctx = canvas.getContext("2d") canvas.style.width = f"{width}px" canvas.style.height = f"{height}px" canvas.width = width*pixel_ratio canvas.height = height*pixel_ratio ctx.scale(pixel_ratio, pixel_ratio) ctx.translate(0.5, 0.5) ctx.clearRect(0, 0, width, height) el = document.querySelector(target) el.replaceChildren(canvas) return ctx def color_map(array: np.array, palette: np.array) -> np.array: size, _ = palette.shape index = (array/array.max()*(size - 1)).round().astype("uint8") width, height = array.shape image = np.full((width, height, 4), 0xff, dtype=np.uint8) image[:, :, :3] = palette[index] return image def draw_image(ctx: Context2d, image: np.array) -> None: data = Uint8ClampedArray.new(to_js(image.tobytes())) width, height, _ = image.shape image_data = ImageData.new(data, width, height) ctx.putImageData(image_data, 0, 0) def draw_mandelbrot(width: int, height: int) -> None: ctx = create_canvas(width, height, "#mandelbrot") console.log("Computing Mandelbrot set ...") console.time("mandelbrot") array = mandelbrot(width, height) console.timeEnd("mandelbrot") image = color_map(array, Magma256) draw_image(ctx, image) def draw_julia(width: int, height: int) -> None: ctx = create_canvas(width, height, "#julia") console.log("Computing Julia set ...") console.time("julia") array = julia(width, height) console.timeEnd("julia") image = color_map(array, Magma256) draw_image(ctx, image) draw_mandelbrot(600, 600) draw_julia(600, 600)