JS: 3D Cube

http://jsdo.it/cue/mxgb http://greggman.com/downloads/examples/3d-in-canvas-vs-webgl/3d-in-canvas.html

by Yannick Albert

HTML

<canvas id="world" />

CSS

html, body {
  height: 100%;
}

body {
  margin: 0;
}

canvas {
  display: block;
  height: 100%;
  width: 100%;
}

/*
// http://jsdo.it/cue/mxgb
// http://jsdo.it/theheyoa/As0c
// http://www.sitepoint.com/building-3d-engine-javascript/
// http://codentronix.com/2011/05/10/html5-experiment-a-rotating-solid-cube/
var RAD2DEG = 180 / Math.PI
var DEG2RAD = Math.PI / 180

function Vector3D(x, y, z) {
  this.x = x || 0
  this.y = y || 0
  this.z = z || 0
}

Vector3D.prototype.add = function (v) {
	return new Vector(this.x + v.x, this.y + v.y, this.z + v.z)
}

Vector3D.prototype.sub = function (v) {
	return new Vector(this.x - v.x, this.y - v.y, this.z - v.z)
}

function Vertex3D(x, y, z, rx, ry, rz) {
  Vector3D.apply(this, [x, y, z])
  
  this.tx = this.x
  this.ty = this.y
  this.tz = this.z

  this.rx = rx || 0
  this.ry = ry || 0
  this.rz = rz || 0
    
  this.screenX = 0
  this.screenY = 0
}
Vertex3D.prototype = new Vector3D

function Camera(x, y, z, angle) {
  Vertex3D.apply(this, [x, y, z]);
  this._angle = 0;
  this.fov = 0;
  this.angle = function(value) {
    if(value) {
      this._angle = value;
      this.fov = 1 / Math.tan(this._angle * 0.5 * Math.PI / 180) * canvas.width * 0.5;
    }
    else {
      return this._angle;
    }
  };
  this.angle(angle || 60);
}
Camera.prototype = new Vertex3D;

function Material3D(fillColor, fillAlpha, lineColor, lineAlpha, lineThickness) {
  this.fillColor = fillColor || [0, 0, 0]
  this.fillAlpha = fillAlpha || 0
  this.lineColor = lineColor || null
  this.lineAlpha = lineAlpha || 0
  this.lineThickness = lineThickness || 1
  this.doubleSide = false
}

Material3D.prototype.fillShader = function(factor) {
  return "rgba(" + parseInt(this.fillColor[0] * factor, 10) + ", " + parseInt(this.fillColor[1] * factor, 10) + ", " + parseInt(this.fillColor[2] * factor, 10) + ", " + this.fillAlpha + ")";
}

Material3D.prototype.lineShader = function(factor) {
  return "rgba(" + parseInt(this.lineColor[0] * factor, 10) + ", " +...

JavaScript

// https://projects.mariusgundersen.net/OnGameStart/#68
// http://garybeene.com/3d/3d-purejs.htm

var RAD2DEG = 180 / Math.PI
var DEG2RAD = Math.PI / 180

// http://codepen.io/ImagineProgramming/pen/NqRrmM
// http://codentronix.com/2011/05/10/html5-experiment-a-rotating-solid-cube/
function Point3D(x, y, z) {
  this.x = x;
  this.y = y;
  this.z = z;

  this.tx = 0
  this.ty = 0
  this.tz = 0

  this.rotateX = function(angle) {
    var rad, cosa, sina, y, z
    rad = angle * Math.PI / 180
    cosa = Math.cos(rad)
    sina = Math.sin(rad)
    y = this.y * cosa - this.z * sina
    z = this.y * sina + this.z * cosa
    return new Point3D(this.x, y, z)
  }

  this.rotateY = function(angle) {
    var rad, cosa, sina, x, z
    rad = angle * Math.PI / 180
    cosa = Math.cos(rad)
    sina = Math.sin(rad)
    z = this.z * cosa - this.x * sina
    x = this.z * sina + this.x * cosa
    return new Point3D(x, this.y, z)
  }

  this.rotateZ = function(angle) {
    var rad, cosa, sina, x, y
    rad = angle * Math.PI / 180
    cosa = Math.cos(rad)
    sina = Math.sin(rad)
    x = this.x * cosa - this.y * sina
    y = this.x * sina + this.y * cosa
    return new Point3D(x, y, this.z)
  }

  this.project = function(cx, cy, fov, viewDistance) {
    var factor, x, y
    factor = fov / (viewDistance + this.tz)
    x = this.tx * factor + cx
    y = this.ty * factor + cy
    return new Point3D(x, y, this.tz)
  }
}

function Camera(fov, zoom) {
	this.x = 0
  this.y = 0
  this.z = 0
	this.cx = 0
  this.cy = 0
  this.cz = 0
  this.rx = 0
  this.ry = 0
  this.rz = 0
  this.fov = fov || 400
  this.zoom = zoom || 4
}

function Shape(vertices, faces, colors) {
	this.vertices = vertices
  this.faces = faces
  this.colors = colors
  this.rx = 0
  this.ry = 0
  this.rz = 0
}

Shape.prototype.rotate = function (camera) {
  var cosX = Math.cos(this.rx - camera.rx)
  var sinX = Math.sin(this.rx - camera.rx)
  var cosY = Math.cos(this.ry - camera.ry)
  var sinY = Math.sin(this.ry - camera.ry)
  var...