function rotationZ(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c, s, 0, 0,
-s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1,
];
}
// Using TWGL (twgljs.org) to keep the code small
var gl = document.getElementById("c").getContext("webgl");
// compiles shader, links and looks up locations
var programInfo = twgl.createProgramInfo(gl, ["vs", "fs"]);
// make some curve points
points = [];
for (var i = 0; i < 100; ++i) {
var a = i / 100 * Math.PI * 2;
var r = 0.5;
points.push(
Math.sin(Math.sin(a * 2.)) * r ,
Math.cos(a) * r);
}
var arrays = {
position: { numComponents: 2, data: points, },
};
// calls gl.createBuffer, gl.bindBuffer, gl.bufferData for each array
var bufferInfo = twgl.createBufferInfoFromArrays(gl, arrays);
function render(time) {
var uniforms = {
u_matrix: rotationZ(time * 0.001),
};
gl.useProgram(programInfo.program);
// calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
// calls gl.uniformXXX, gl.activeTexture, gl.bindTexture
twgl.setUniforms(programInfo, uniforms);
// calls gl.drawArray or gl.drawElements
twgl.drawBufferInfo(gl, bufferInfo, gl.LINE_LOOP);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
canvas { border: 1px solid blue; }
<!--
note! I'm using a square canvas so I don't have to deal with aspect
which would complicate the example
See the articles linked in the answer for details about aspect
-->
<canvas id="c" width="150" height="150"></canvas>
<script src="https://twgljs.org/dist/3.x/twgl-full.min.js"></script>
<script id="vs" type="notjs">
attribute vec4 position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * position;
}
</script>
<script id="fs" type="notjs">
precision mediump float;
void main() {
gl_FragColor = vec4(0,0,0,1);
}
</script>