SOURCE

function project3D(x, y, z, vars) {

  var p, d;
  x -= vars.camX;
  y -= vars.camY;
  z -= vars.camZ;
  p = Math.atan2(x, z);
  d = Math.sqrt(x * x + z * z);
  x = Math.sin(p - vars.yaw) * d;
  z = Math.cos(p - vars.yaw) * d;
  p = Math.atan2(y, z);
  d = Math.sqrt(y * y + z * z);
  y = Math.sin(p - vars.pitch) * d;
  z = Math.cos(p - vars.pitch) * d;
  var rx1 = -9;
  var ry1 = 1;
  var rx2 = 9;
  var ry2 = 1;
  var rx3 = 0;
  var ry3 = 0;
  var rx4 = x;
  var ry4 = z;
  var uc = (ry4 - ry3) * (rx2 - rx1) - (rx4 - rx3) * (ry2 - ry1);
  var ua = ((rx4 - rx3) * (ry1 - ry3) - (ry4 - ry3) * (rx1 - rx3)) / uc;
  var ub = ((rx2 - rx1) * (ry1 - ry3) - (ry2 - ry1) * (rx1 - rx3)) / uc;
  if (!z) z = 0.000000001;
  if (ua > 0 && ua < 1 && ub > 0 && ub < 1) {
    return {
      x: vars.cx + (rx1 + ua * (rx2 - rx1)) * vars.scale,
      y: vars.cy + y / z * vars.scale,
      d: Math.sqrt(x * x + y * y + z * z)
    };
  } else {
    return {
      d: -1
    };
  }
}

function Vert(x, y, z) {
  this.x = x;
  this.y = y;
  this.z = z;
}

function Poly(verts) {
  this.verts = verts;
}

function elevation(x, y, z) {

  var dist = Math.sqrt(x * x + y * y + z * z);
  if (dist && z / dist >= -1 && z / dist <= 1) return Math.acos(z / dist);
  return 0.00000001;
}

function rgb(col) {

  col += 0.000001;
  var r = parseInt((0.5 + Math.sin(col) * 0.5) * 256);
  var g = parseInt((0.5 + Math.cos(col) * 0.5) * 256);
  var b = parseInt((0.5 - Math.sin(col) * 0.5) * 256);
  return "#" + ("0" + r.toString(16)).slice( - 2) + ("0" + g.toString(16)).slice( - 2) + ("0" + b.toString(16)).slice( - 2);
}

function process(vars) {

  var p, d, t;
  p = Math.atan2(vars.camX, vars.camZ);
  d = Math.sqrt(vars.camX * vars.camX + vars.camZ * vars.camZ);
  d -= Math.sin(vars.frameNo / 80) / 20;
  t = Math.sin(vars.frameNo / 200) / 105;
  vars.camX = Math.sin(p + t) * d;
  vars.camZ = Math.cos(p + t) * d;
  vars.camY = -Math.sin(vars.frameNo / 100) * 20;
  vars.yaw = Math.PI + p + t;
  vars.pitch = elevation(vars.camX, vars.camZ, vars.camY) - Math.PI / 2;

  for (var i = 1; i < vars.shapes.length; ++i) {
    rotateShape(vars.shapes[i], 0, 0, 0, 0, .02 * (i % 2 ? -1 : 1), 0);
  }
}

function sortFunction(a, b) {
  return b.dist - a.dist;
}

function rotateShape(shape, ox, oy, oz, pitch, yaw) {

  var p, d, x, y, z;
  x = shape.x - ox;
  y = shape.y - oy;
  z = shape.z - oz;
  d = Math.sqrt(y * y + z * z);
  p = Math.atan2(y, z);
  y = Math.sin(p + pitch) * d;
  z = Math.cos(p + pitch) * d;
  d = Math.sqrt(x * x + z * z);
  p = Math.atan2(x, z);
  x = Math.sin(p + yaw) * d;
  z = Math.cos(p + yaw) * d;
  shape.x = x + ox;
  shape.y = y + oy;
  shape.z = z + oz;

  for (var i = 0; i < shape.polys.length; ++i) {
    for (var j = 0; j < shape.polys[i].verts.length; ++j) {
      x = shape.polys[i].verts[j].x;
      y = shape.polys[i].verts[j].y;
      z = shape.polys[i].verts[j].z;
      d = Math.sqrt(y * y + z * z);
      p = Math.atan2(y, z);
      y = Math.sin(p + pitch) * d;
      z = Math.cos(p + pitch) * d;
      d = Math.sqrt(x * x + z * z);
      p = Math.atan2(x, z);
      x = Math.sin(p + yaw) * d;
      z = Math.cos(p + yaw) * d;
      shape.polys[i].verts[j].x = x;
      shape.polys[i].verts[j].y = y;
      shape.polys[i].verts[j].z = z;
    }
  }
}

function draw(vars) {

  vars.ctx.globalAlpha = .25;
  vars.ctx.fillStyle = "#000";
  vars.ctx.fillRect(0, 0, vars.canvas.width, vars.canvas.height);

  var pt, x, y, z, polys = [];

  for (var i = 0; i < vars.shapes.length; ++i) {
    for (var j = 0; j < vars.shapes[i].polys.length; ++j) {
      x = vars.shapes[i].x + vars.shapes[i].polys[j].verts[0].x;
      y = vars.shapes[i].y + vars.shapes[i].polys[j].verts[0].y;
      z = vars.shapes[i].z + vars.shapes[i].polys[j].verts[0].z;
      pt = project3D(x, y, z, vars);
      if (pt.d != -1) {
        poly = {};
        poly.verts = Array(vars.shapes[i].polys[j].verts.length);
        poly.dist = pt.d;
        poly.color = Math.PI * 2 / vars.shapes.length * i;
        poly.verts[0] = {};
        poly.verts[0].x = pt.x;
        poly.verts[0].y = pt.y;
        for (var k = 1; k < poly.verts.length; ++k) {
          x = vars.shapes[i].x + vars.shapes[i].polys[j].verts[k].x;
          y = vars.shapes[i].y + vars.shapes[i].polys[j].verts[k].y;
          z = vars.shapes[i].z + vars.shapes[i].polys[j].verts[k].z;
          pt = project3D(x, y, z, vars);
          poly.dist += pt.d;
          poly.verts[k] = {};
          poly.verts[k].x = pt.x;
          poly.verts[k].y = pt.y;
        }
        polys.push(poly);
      }
    }
  }
  polys.sort(sortFunction);
  for (var i = 0; i < polys.length; ++i) {
    x = polys[i].verts[0].x;
    y = polys[i].verts[0].y;
    vars.ctx.lineWidth = 100 / (1 + polys[i].dist);
    vars.ctx.beginPath();
    vars.ctx.moveTo(x, y);
    for (var j = 1; j < polys[i].verts.length; ++j) {
      x = polys[i].verts[j].x;
      y = polys[i].verts[j].y;
      vars.ctx.lineTo(x, y);
    }
    vars.ctx.fillStyle = rgb(vars.frameNo / 20 + polys[i].color);
    vars.ctx.globalAlpha = .75;
    vars.ctx.fill();
    vars.ctx.strokeStyle = "#fff";
    vars.ctx.globalAlpha = .8;
    vars.ctx.stroke();
  }
}

function Torus(x, y, z, radius1, radius2, stacks, slices, pitch, yaw) {
  var shape = {},
  x, y, z, p, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, p1, p2, d;
  shape.x = x;
  shape.y = y;
  shape.z = z;
  shape.polys = [];
  for (var j = 0; j < slices; ++j) {
    for (var i = 0; i < stacks; ++i) {
      p1 = Math.PI * 2 / stacks * i;
      x1 = radius2 + Math.sin(p1) * radius1;
      y1 = Math.cos(p1) * radius1;
      z1 = 0;
      d = Math.sqrt(x1 * x1);
      p2 = Math.PI * 2 / slices * j;
      p1 = Math.atan2(x1, z1) + p2;
      x1 = Math.sin(p1) * d;
      z1 = Math.cos(p1) * d;

      p1 = Math.PI * 2 / stacks * (i + 1);
      x2 = radius2 + Math.sin(p1) * radius1;
      y2 = Math.cos(p1) * radius1;
      z2 = 0;
      d = Math.sqrt(x2 * x2);
      p2 = Math.PI * 2 / slices * j;
      p1 = Math.atan2(x2, z2) + p2;
      x2 = Math.sin(p1) * d;
      z2 = Math.cos(p1) * d;

      p1 = Math.PI * 2 / stacks * (i + 1);
      x3 = radius2 + Math.sin(p1) * radius1;
      y3 = Math.cos(p1) * radius1;
      z3 = 0;
      d = Math.sqrt(x3 * x3);
      p2 = Math.PI * 2 / slices * (j + 1);
      p1 = Math.atan2(x3, z3) + p2;
      x3 = Math.sin(p1) * d;
      z3 = Math.cos(p1) * d;

      p1 = Math.PI * 2 / stacks * i;
      x4 = radius2 + Math.sin(p1) * radius1;
      y4 = Math.cos(p1) * radius1;
      z4 = 0;
      d = Math.sqrt(x4 * x4);
      p2 = Math.PI * 2 / slices * (j + 1);
      p1 = Math.atan2(x4, z4) + p2;
      x4 = Math.sin(p1) * d;
      z4 = Math.cos(p1) * d;

      shape.polys.push(new Poly([new Vert(x1, y1, z1), new Vert(x2, y2, z2), new Vert(x3, y3, z3), new Vert(x4, y4, z4)]));
    }
  }
  for (var i = 0; i < shape.polys.length; ++i) {
    for (var j = 0; j < shape.polys[i].verts.length; ++j) {
      x = shape.polys[i].verts[j].x;
      y = shape.polys[i].verts[j].y;
      z = shape.polys[i].verts[j].z;
      d = Math.sqrt(y * y + z * z);
      p = Math.atan2(y, z);
      y = Math.sin(p + pitch) * d;
      z = Math.cos(p + pitch) * d;
      d = Math.sqrt(x * x + z * z);
      p = Math.atan2(x, z);
      x = Math.sin(p + yaw) * d;
      z = Math.cos(p + yaw) * d;
      shape.polys[i].verts[j].x = x;
      shape.polys[i].verts[j].y = y;
      shape.polys[i].verts[j].z = z;
    }
  }
  return shape;
}

function loadScene(vars) {

  vars.shapes = [];
  var x = 0;
  var y = 0;
  var z = 0;
  var rad1 = 2;
  var rad2 = 10;
  var stacks = 8;
  var slices = 20;
  var pitch = 0;
  var yaw = 0;
  vars.shapes.push(Torus(x, y, z, rad1, rad2, stacks, slices, pitch, yaw));

  var sd = 3,
  p;
  for (var i = 0; i < sd; ++i) {
    p = Math.PI * 2 / sd * i;
    x = Math.sin(p) * rad2;
    z = Math.cos(p) * rad2;
    pitch = Math.PI / 2;
    yaw = p + Math.PI / 2;
    rad1b = 1;
    rad2b = 3.5 * (i + 1);
    stacks = 6;
    slices = 8 * (i + 1);
    vars.shapes.push(Torus(x, y, z, rad1b, rad2b, stacks, slices, pitch, yaw));
  }
}

function loadFloor(vars) {

  var p1, p2, d = 100;
  vars.floorTiles = [];
  for (var i = 0; i < 3500; ++i) {
    vert = {};
    vert.p1 = Math.PI * 2 * Math.random();
    vert.p2 = Math.PI * Math.random();
    vert.x = Math.sin(vert.p1) * Math.sin(vert.p2) * d;
    vert.z = Math.cos(vert.p1) * Math.sin(vert.p2) * d;
    vert.y = Math.cos(vert.p2) * d;
    vars.floorTiles.push(vert);
  }
}

function frame(vars) {

  if (vars === undefined) {
    var vars = {};
    vars.canvas = document.createElement("canvas");
    document.body.appendChild(vars.canvas);
    vars.ctx = vars.canvas.getContext("2d");
    vars.canvas.width = document.body.clientWidth;
    vars.canvas.height = document.body.clientHeight;
    window.addEventListener("resize", function() {
      vars.canvas.width = document.body.clientWidth;
      vars.canvas.height = document.body.clientHeight;
      vars.cx = vars.canvas.width / 2;
      vars.cy = vars.canvas.height / 2;
    },
    true);
    vars.canvas.oncontextmenu = function(e) {
      e.preventDefault();
    };
    vars.canvas.addEventListener("mousemove", function(e) {
      var rect = vars.canvas.getBoundingClientRect();
      vars.mx = Math.round((e.clientX - rect.left) / (rect.right - rect.left) * vars.canvas.width);
      vars.my = Math.round((e.clientY - rect.top) / (rect.bottom - rect.top) * vars.canvas.height);
    },
    true);
    vars.canvas.addEventListener("mousedown", function(e) {
      switch (e.which) {
      case 1:
        vars.leftButton = 1;
        break;
      case 3:
        vars.rightButton = 1;
        break;
      }
    },
    true);
    vars.canvas.addEventListener("mouseup", function(e) {
      switch (e.which) {
      case 1:
        vars.leftButton = 0;
        break;
      case 3:
        vars.rightButton = 0;
        break;
      }
    },
    true);
    vars.canvas.addEventListener("mousewheel", function(e) {
      var e = window.event || e; // old IE support
      vars.wheelDelta = Math.max( - 1, Math.min(1, (e.wheelDelta / 120 || -e.detail)));
    },
    true);
    vars.canvas.addEventListener("touchstart", function(e) {
      vars.leftButton = 1;
      e.preventDefault();
      var rect = vars.canvas.getBoundingClientRect();
      vars.omx = vars.mx;
      vars.omy = vars.my;
      vars.mx = Math.round((e.changedTouches[0].pageX - rect.left) / (rect.right - rect.left) * vars.canvas.width);
      vars.my = Math.round((e.changedTouches[0].pageY - rect.top) / (rect.bottom - rect.top) * vars.canvas.height);
    },
    true);
    vars.canvas.addEventListener("touchend", function(e) {
      vars.leftButton = 0;
    },
    true);
    vars.canvas.addEventListener("touchmove", function(e) {
      e.preventDefault();
      var rect = vars.canvas.getBoundingClientRect();
      vars.mx = Math.round((e.changedTouches[0].pageX - rect.left) / (rect.right - rect.left) * vars.canvas.width);
      vars.my = Math.round((e.changedTouches[0].pageY - rect.top) / (rect.bottom - rect.top) * vars.canvas.height);
    },
    true);
    vars.frameNo = 0;

    vars.camX = 0;
    vars.camY = 0;
    vars.camZ = -30;
    vars.pitch = 0;
    vars.yaw = 0;
    vars.cx = vars.canvas.width / 2;
    vars.cy = vars.canvas.height / 2;
    vars.scale = 700;
    vars.seed = 0;
    loadScene(vars);
    loadFloor(vars);
  }

  vars.frameNo++;
  requestAnimationFrame(function() {
    frame(vars);
  });

  process(vars);
  draw(vars);
}
frame();
html,
body {
  margin: 0px;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

#canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}
console 命令行工具 X clear

                    
>
console