OffscreenCanvas rAF+commit loop fetch image
by Gregg Tavares
July 02, 2018
HTML
<canvas></canvas>
<div id="no-offscreencanvas" style="display: none;">
<div>Sorry but your browser doesn't appear to support OffscreenCanvas</div>
</div>
CSS
body { margin: 0; }
canvas { width: 100vw; height: 100vh; }
#no-webgl, #no-offscreencanvas {
position: absolute;
left: 0;
top: 0;
background: red;
color: white;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
JavaScript
const wsrc = `
const appInfo = {
clientWidth: 300,
clientHeight: 150,
};
function main(gl) {
const vs = \`
void main(){
gl_Position = vec4(0, 0, 0, 1);
gl_PointSize = 200.0;
}
\`;
const fs = \`
precision mediump float;
uniform sampler2D tex;
void main() {
gl_FragColor = texture2D(tex, gl_PointCoord.xy);
}
\`;
const p = createProgram(gl, [vs, fs]);
gl.useProgram(p);
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255]));
fetch('https://i.imgur.com/ZKMnXce.png', {mode:'cors'}).then(function(response) {
if (!response.ok) {
console.error(response);
}
return response.blob();
}).then(function(blob) {
return createImageBitmap(blob, {
premultiplyAlpha: 'none',
colorSpaceConversion: 'none',
});
}).then(function(bitmap) {
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
gl.generateMipmap(gl.TEXTURE_2D);
}).catch(function(e) {
console.error(e);
});
function render(time) {
time *= 0.001;
const clientWidth = appInfo.clientWidth;
const clientHeight = appInfo.clientHeight;
// Make the canvas match its display size
if (gl.canvas.width !== clientWidth || gl.canvas.height !== clientHeight) {
gl.canvas.width = clientWidth;
gl.canvas.height = clientHeight;
}
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, time % 1, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);
gl.commit();
requestAnimationFrame(render);
}
requestAnimationFrame(render);
function createShader(gl, type, src) {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) {
throw new Error(gl.getShaderInfoLog(s));
}
return s;
}
...