JSFiddle - React, Tailwind, and code Playground
by jacomyal
HTML
<script src="https://rawgithub.com/html5rocks/www.html5rocks.com/bd6830fd1ec987ef8f614eed4255a3c57737a3c4/content/tutorials/webgl/webgl_fundamentals/static/webgl/resources/webgl-utils.js"></script>
<body>
<canvas id="white"></canvas>
<canvas id="black"></canvas>
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;
attribute vec2 a_customAttributes;
uniform vec2 u_resolution;
varying vec4 color;
void main() {
// Scale from [[-1 1] [-1 1]] to the container:
gl_Position = vec4((a_position / u_resolution * 2.0 - 1.0) * vec2(1, -1), 0, 1);
gl_PointSize = a_customAttributes[0] * 2.0;
float c = a_customAttributes[1];
// Extract the color:
color.b = mod(c, 256.0); c = floor(c / 256.0);
color.g = mod(c, 256.0); c = floor(c / 256.0);
color.r = mod(c, 256.0); c = floor(c / 256.0);
color /= 255.0;
color.a = 1.0;
}
</script>
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
varying vec4 color;
void main(void) {
float border = 0.03;
float radius = 0.5;
vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);
vec2 m = gl_PointCoord - vec2(0.5, 0.5);
float dist = radius - sqrt(m.x * m.x + m.y * m.y);
float t = 0.0;
if (dist > border)
t = 1.0;
else if (dist > 0.0)
t = dist / border;
gl_FragColor = mix(color0, color, t);
}
</script>
</body>
CSS
body {
background: #ccc;
}
#white {
background: #fff;
}
#black {
background: #000;
}
JavaScript
// Get A WebGL context
function draw(canvas) {
var gl = canvas.getContext('experimental-webgl'),
buffer,
matrix;
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.enable(gl.BLEND);
// Setup a GLSL program
var vertexShader = createShaderFromScriptElement(gl, '2d-vertex-shader'),
fragmentShader = createShaderFromScriptElement(gl, '2d-fragment-shader'),
program = createProgram(gl, [vertexShader, fragmentShader]);
gl.useProgram(program);
// Look up where the vertex data needs to go
var positionLocation = gl.getAttribLocation(program, 'a_position'),
customAttributesLocation = gl.getAttribLocation(program, 'a_customAttributes'),
resolutionLocation = gl.getUniformLocation(program, 'u_resolution');
gl.enableVertexAttribArray(positionLocation);
gl.enableVertexAttribArray(customAttributesLocation);
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
matrix = [
40, 40, 25, 0x333333,
75, 40, 25, 0xcccccc,
40, 110, 25, 0xcccccc,
75, 110, 25, 0x333333,
150, 40, 25, 0xcccccc,
185, 40, 25, 0xcccccc,
150, 110, 25, 0x333333,
185, 110, 25, 0x333333
];
buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(matrix),
gl.DYNAMIC_DRAW);
gl.vertexAttribPointer(
positionLocation,
2,
gl.FLOAT,
false,
4 * Float32Array.BYTES_PER_ELEMENT,
0
);
gl.vertexAttribPointer(
customAttributesLocation,
2,
gl.FLOAT,
false,
4 * Float32Array.BYTES_PER_ELEMENT,
8
);
// Draw
gl.drawArrays(gl.POINTS, 0, matrix.length / 4);
}
draw(document.getElementById('white'));
draw(document.getElementById('black'));