function makeRegl(glsl, funcs='', height=400, w=null) {
let isFullWidth = false;
if (w === null) {
w = width;
isFullWidth = true;
}
const threshold = 0.5;
const dpi = window.devicePixelRatio;
const pxWidth = isFullWidth ? Math.round(w * dpi) : w;
const pxHeight = isFullWidth ? Math.round(height * dpi) : height;
const canvas = DOM.canvas(pxWidth, pxHeight);
const displayWidth = Math.round(width * dpi);
const displayHeight = Math.round(width * dpi / pxWidth * pxHeight);
const useSecondCanvas = false;
canvas.style.width = width + 'px';
const secondCanvas = useSecondCanvas ? DOM.canvas(displayWidth, displayHeight) : null;
const ctx = canvas.getContext('webgl', {
preserveDrawingBuffer: useSecondCanvas,
});
const regl = reglConstructor(ctx);
const pixels = regl.texture();
const drawFeedback = regl({
frag: `
precision mediump float;
uniform sampler2D texture;
uniform float t;
uniform vec2 iResolution;
varying vec2 uv;
${funcs}
void main () {
${glsl}
}`,
vert: `
precision mediump float;
attribute vec2 position;
varying vec2 uv;
void main () {
uv = position;
gl_Position = vec4(2.0 * position - 1.0, 0, 1);
}`,
attributes: {
position: [
-2, 0,
0, -2,
2, 2]
},
uniforms: {
texture: pixels,
t: ({tick}) => 0.01 * (tick - 1),
iResolution: [pxWidth, pxHeight],
},
count: 3
})
let cancel = null;
let running = false;
const start = () => {
if (running) {
console.log('already running');
return;
}
running = true;
const doCancel = regl.frame(function () {
regl.clear({
color: [0, 0, 0, 1]
})
drawFeedback()
pixels({
copy: true
});
if (useSecondCanvas) {
const secondCtx = secondCanvas.getContext('2d');
secondCtx.drawImage(canvas, 0, 0, displayWidth, displayHeight);
}
}).cancel;
cancel = () => {
if (!running) {
console.log('not cancelling because not running');
} else {
running = false;
doCancel();
}
}
}
const observer = new IntersectionObserver(onIntersection, {threshold});
function onIntersection(entries, opts){
if (entries[0].intersectionRatio > threshold || threshold === 0 && entries[0].isIntersecting) {
console.log('start');
start();
} else {
if (cancel) {
console.log('cancel');
cancel();
} else {
console.log('no cancel');
}
}
}
setTimeout(() => {
observer.observe(useSecondCanvas ? secondCanvas : canvas);
}, 100);
return useSecondCanvas ? secondCanvas : canvas;
}