Public
Edited
Jan 24, 2022
1 fork
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const frame = regl.frame(function(context) {
regl.clear({
color: [0.0, 0.0, 0.0, 1],
depth: 1
});

// Each loop, update the data
updateData(points);

// And draw it!
drawDots({
pointWidth: 1,
points: points
});
});
invalidation.then(() => frame.cancel());
}
Insert cell
drawDots = regl({
frag: `
precision mediump float;
uniform vec4 color;
void main () {
float r = 0.0, delta = 0.0, alpha = 1.0;
vec2 cxy = 2.0 * gl_PointCoord - 1.0;
r = dot(cxy, cxy);
if (r > 1.0) {
discard;
}
gl_FragColor = color * alpha;
}`,

vert: `
precision mediump float;
attribute vec2 position;
attribute float pointWidth;
uniform float stageWidth;
uniform float stageHeight;
// helper function to transform from pixel space to normalized
// device coordinates (NDC). In NDC (0,0) is the middle,
// (-1, 1) is the top left and (1, -1) is the bottom right.
// Stolen from Peter Beshai's great blog post:
// http://peterbeshai.com/beautifully-animate-points-with-webgl-and-regl.html
vec2 normalizeCoords(vec2 position) {
// read in the positions into x and y vars
float x = position[0];
float y = position[1];
return vec2(
2.0 * ((x / stageWidth) - 0.5),
// invert y to treat [0,0] as bottom left in pixel space
-(2.0 * ((y / stageHeight) - 0.5)));
}
void main () {
gl_PointSize = pointWidth;
gl_Position = vec4(normalizeCoords(position), 0, 1);
}`,

attributes: {
position: function(context, props) {
return props.points.map(function(point) {
return [point.x, point.y];
});
},
pointWidth: function(context, props) {
return props.points.map(function(point) {
return point.size;
});
}
},

uniforms: {
color: function(context, props) {
// just to be a bit strange, oscillate the color a bit.
return [Math.cos(context.tick / 100), 0.704, 1.0, 1.0];
},
stageWidth: regl.context("drawingBufferWidth"),
stageHeight: regl.context("drawingBufferHeight")
},

count: function(context, props) {
// set the count based on the number of points we have
return props.points.length;
},
primitive: "points"
});
Insert cell
updateData = (data) => {
data.forEach(function(datum) {
datum.x += datum.speed;
// reset x if its gone past max width
datum.x = datum.x > width ? 0 : datum.x;
});
}
Insert cell
points = createData(numberOfStars);
Insert cell
createData = (dataCount) => {
restart;
var data = [];
for (var i = 0; i < dataCount; i++) {
var datum = {
id: i,
speed: randomFromInterval(1, 1.2),
y: randomIntFromInterval(1, width / 1.6),
x: randomIntFromInterval(1, width),
size: randomIntFromInterval(1.5, 3.1)
};

data.push(datum);
}
return data;
}
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more