Published
Edited
Aug 18, 2021
2 forks
9 stars
Insert cell
Insert cell
draw(options)
Insert cell
viewof options = view`<div>
${['month', Inputs.range([0, 11], {step: 1, value: 0, label: 'Month'})]}
${['rotation', Inputs.range([-.5, .5], {step: .01, value: .1, label: 'Rotation'})]}
${['latitude', Inputs.range([-.5, .5], {step: .01, value: .2, label: 'Latitude'})]}
${['size', Inputs.range([100, 800], {step: 10, value: 400, label: 'Size'})]}
`
Insert cell
options
Insert cell
Insert cell
Insert cell
{
const size = 300;
const canvas = DOM.canvas(size, size);
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#fff';
// Our per-frame draw callback.
const drawFrame = t => {
// Paint a white background.
ctx.fillRect(0, 0, canvas.width, canvas.height);
return draw({
canvas, size,
rotation: t,
month: Math.floor(t * 12) % 12,
latitude: .3 + .1 * Math.cos((t + .4) * Math.PI * 2),
});
};
return renderGif(invalidation, drawFrame, 5000, {
preview: drawFrame(0),
// gif.js options
converterOptions: {
// Sample interval (lower is better)
quality: 2,
// Small file size reduction, longer compile time.
// globalPalette: true,
dither: 'FalseFloydSteinberg',
}
})
}
Insert cell
Insert cell
Insert cell
draw = {
init(viewof options.value.size);
vertexBuffer;
const _canvas = DOM.canvas(gl.canvas.width, gl.canvas.height);
return (options = {}) => {
const {
month = 0,
latitude = .5,
rotation = 0,
size = 400,
canvas = _canvas
} = options;

if(gl.canvas.width != size || gl.canvas.height != size) {
init(size);
}
const rotate = [rotation * 2 * Math.PI, latitude * Math.PI];
gl.uniform2fv(u_rotate, rotate);
gl.bindTexture(gl.TEXTURE_2D, textures[month]);
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);

if(canvas.width != size || canvas.height != size) {
canvas.width = canvas.height = size;
}
canvas.getContext('2d').drawImage(gl.canvas, 0, 0);
return canvas;
}
}
Insert cell
init = size => {
gl.canvas.width = gl.canvas.height = size;
gl.useProgram(program);
gl.enableVertexAttribArray(a_vertex);
gl.vertexAttribPointer(a_vertex, 2, gl.FLOAT, false, 0, 0);
gl.uniform2f(u_translate, size / 2, size / 2);
gl.uniform1f(u_scale, size / 2 - 1);
gl.viewport(0, 0, size, size);
}
Insert cell
// Overrides width of the imported notebook, so that changes to width
// don't invalidate cells.
dummy_width = 1
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more