toy = function (shader, options = {}) {
let { width = 512, height = 512, render = "onmouse" } = options;
let canvas = DOM.canvas(width, height);
let regl = createRegl({
canvas
});
let uniforms = {
u_resolution: [width, height],
u_frame: 0,
u_mouse: [0, 0]
};
let draw = regl({
frag:
`
precision mediump float;
uniform vec2 u_resolution;
uniform int u_frame;
uniform vec2 u_mouse;
` + shader,
vert: `
attribute vec2 position;
void main () {
gl_Position = vec4(position, 0, 1);
}`,
attributes: {
position: [
[-1, -1],
[1, -1],
[1, 1],
[1, 1],
[-1, 1],
[-1, -1]
]
},
uniforms: {
u_resolution: regl.prop("u_resolution"),
u_frame: regl.prop("u_frame"),
u_mouse: regl.prop("u_mouse")
},
count: 6
});
let requestId = null;
function renderFrame() {
uniforms.u_frame++;
draw(uniforms);
}
canvas.onmousedown = (e) => {
uniforms.u_mouse = [e.offsetX, height - e.offsetY];
if (render != "single") renderFrame();
};
canvas.onmousemove = (e) => {
uniforms.u_mouse = [e.offsetX, height - e.offsetY];
if (render != "single" && e.buttons != 0) renderFrame();
};
invalidation.then(() => {
if (requestId) cancelAnimationFrame(requestId);
});
canvas.value = shader;
if (render == "continuous") {
function animationRender() {
renderFrame();
requestId = requestAnimationFrame(animationRender);
}
animationRender();
} else {
renderFrame();
}
return canvas;
}