HTMLのcanvasタグとJavaScriptを使って3Dっぽいことをするサンプルです。WebGLを使わずに3Dっぽいことをしています。サンプルは下の方に表示されます。
class Vertex{ constructor(x, y, z){ this.x = x; this.y = y; this.z = z; } rotate(sin, cos){ this._screenX = this.x * cos * cos - this.y * sin + this.z * cos * sin + 200; this._screenY = this.x * sin * cos + this.y * cos + this.z * sin * sin + 200; this._screenZ = -this.x * sin + this.z * cos; } get screenX(){ return this._screenX; } get screenY(){ return this._screenY; } get screenZ(){ return this._screenZ; } } class Face{ constructor(indices, color){ this._indices = indices; this._color = color; } calcZ(vertices){ return (vertices[this._indices[0]].screenZ + vertices[this._indices[1]].screenZ + vertices[this.indices[2]].screenZ) / 3.0; } get indices(){ return this._indices; } get color(){ return this._color; } } const vertices = [ new Vertex(-100, -100, -100), new Vertex(-100, 100, 100), new Vertex(100, -100, 100), new Vertex(100, 100, -100) ]; const faces = [ new Face([0, 3, 2], "#FF0000"), new Face([0, 2, 1], "#00FF00"), new Face([0, 1, 3], "#0000FF"), new Face([1, 2, 3], "#00FFFF") ]; let context = null; let time = 0; window.addEventListener("load", () => { const canvas = document.getElementById("ese"); context = canvas.getContext('2d'); setInterval(draw, 33); }, false); const draw = () => { context.clearRect(0, 0, 400, 400); updateVertices(vertices, time); zsort(faces, vertices); for(const face of faces){ drawTriangle(context, vertices, face); } time += 0.01; }; const updateVertices = (vertices, time) => { for(const vertex of vertices){ vertex.rotate(Math.sin(time), Math.cos(time)); } }; const zsort = (faces, vertices) => { faces.sort((face1, face2) => { return face1.calcZ(vertices) - face2.calcZ(vertices); }); }; const drawTriangle = (context, vertices, face) => { const vertex1 = vertices[face.indices[0]]; const vertex2 = vertices[face.indices[1]]; const vertex3 = vertices[face.indices[2]]; context.fillStyle = face.color; context.beginPath(); context.moveTo(vertex1.screenX, vertex1.screenY); context.lineTo(vertex2.screenX, vertex2.screenY); context.lineTo(vertex3.screenX, vertex3.screenY); context.lineTo(vertex1.screenX, vertex1.screenY); context.closePath(); context.fill(); context.stroke(); };