3D cube - Fl-Matrix + Gl-Matrix - JSFiddle
Demo
by David Komer
HTML
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary-type-identifiers/master/index.js"></script>
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary-type-classes/master/index.js"></script>
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary-def/master/index.js"></script>
<script src="https://cdn.rawgit.com/sanctuary-js/sanctuary/master/index.js"></script>
<script src="https://unpkg.com/fl-matrix/dist/fl-matrix.browser-production.js"></script>
<script src="https://unpkg.com/gl-matrix/dist/gl-matrix.js"></script>
<canvas id="canvas"></canvas>
CSS
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#canvas {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
}
JavaScript
//Globals
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
updateCanvasSize();
gl.clearColor(0.4, 0.4, 0.4, 1);
gl.enable(gl.DEPTH_TEST);
//Config
const BOX_SIZE = 200;
const HALF_BOX_SIZE = BOX_SIZE/2;
const ROTATION_SPEED = Math.PI/2;
const S = window.sanctuary.create({
checkTypes: false,
env: window.sanctuary.env
});
//Axis changes (to give it variety)
let ROTATION_AXIS = [1,1,1];
const changeAxis = () => {
console.log("changing axis");
ROTATION_AXIS =
[Math.random(), Math.random(), Math.random()]
.map(n => n *= (Math.random() < .5) ? -1 : 1);
}
//Functional helpers for creating common transformations
const createPerspective = fov => aspect => near => far =>
FlMatrix.emptyMatrix (4) (4)
.map(es =>
mat4.perspective(es, fov, aspect, near, far)
);
const createEye = origin => dest => up =>
FlMatrix.emptyMatrix (4) (4)
.map(es =>
mat4.lookAt(es, origin, dest, up)
);
const rotateMatrix = m => amount => axis =>
m.map(es =>
mat4.rotate(es, es, amount, axis)
);
const scaleMatrix = m => scale =>
m.map(es =>
mat4.scale(es, es, scale)
);
const translateMatrix = m => translate =>
m.map(es =>
mat4.translate(es, es, [.5,.5,.5])
);
//Setup our camera matrix - any model composed with it will be rendered with this view
const cameraMatrix =
S.compose
(createPerspective (Math.PI/2) (canvas.clientWidth/canvas.clientHeight) (1) (3000))
(createEye ([0,0,-1000]) ([0,0,1]) ([0,1,0]));
//accepts any modelMatrix :D
const getTransformMatrix = S.compose(cameraMatrix); //alternatively, cameraMatrix.compose;
//helper for object updates
const updateRotation = (m) => (deltaTime) =>
rotateMatrix (m) (deltaTime * ROTATION_SPEED) (ROTATION_AXIS);
//helper to create buffer
const makeSimpleBuffer = program => aName => nComponents => {
gl.useProgram(program);
const buffer = gl.createBuffer();
const location =...