{
const mandelbrot = `
float distance(vec2 c) {
float c2 = dot(c, c);
if (256.0 * c2 * c2 - 96.0 * c2 + 32.0 * c.x - 3.0 < 0.0 ) return 0.0;
if (16.0 *(c2 + 2.0 * c.x + 1.0) - 1.0 < 0.0 ) return 0.0;
vec2 z = vec2(0.0);
vec2 dz = vec2(0.0);
float m2 = 0.0;
for (int i = 0; i < 300; i++) {
dz = 2.0 * vec2(z.x * dz.x - z.y * dz.y, z.x * dz.y + z.y * dz.x) + vec2(1.0, 0.0);
z = vec2(z.x * z.x - z.y * z.y, 2.0 * z.x * z.y) + c;
if (dot(z, z) > 1024.0) return 0.5 * sqrt(dot(z, z) / dot(dz, dz)) * log(dot(z, z));
}
return 0.0;
}
void main() {
vec2 translate_norm = translate / cm_Resolution;
translate_norm.y = 1.0 - translate_norm.y;
vec2 coord = (gl_FragCoord.xy / cm_Resolution - translate_norm) / scale;
vec2 c = vec2(-2.18 + 3.0 * coord.x, -1.30 - 2.60 * coord.y);
float b = clamp(pow(4.0 * distance(c) * scale, 0.2), 0.0, 1.0);
gl_FragColor = vec4(vec3(b), 1.0);
}
`;
const uniforms = cm.state({ scale: 1, translate: [0, 0] });
const width = 800;
const app = cm.app({
width,
height: width * 0.86,
use: { zoom: cm.zoom },
styleCursor: "grab",
draw: () => [
cm.rasterGL({
fill: mandelbrot,
uniforms,
zoom: {
scaleExtent: [1, Infinity],
onZoom: ({ transform }) => {
const { x, y, k } = transform;
const dpr = window.devicePixelRatio ?? 1;
uniforms.scale = k;
uniforms.translate = [x * dpr, y * dpr];
}
}
})
]
});
invalidation.then(() => app.dispose());
const node = app.render();
yield node;
fullscreen(node, { center: true });
}