<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 Canvas飞行在六边形蜂巢建筑中</title>
<style>
html,
body {
margin: 0px;
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
}
canvas {
position: absolute;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script>
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 (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 rgb(col) {
col += 0.000001;
var r = 0; //parseInt((0.5+Math.sin(col)*0.5)*256);
var g = parseInt((0.5 + Math.cos(col) * 0.5) * 256);
var b = parseInt((0.2 + Math.cos(col) * 0.2) * 256);
return "#" + ("0" + r.toString(16)).slice(-2) + ("0" + g.toString(16)).slice(-2) + ("0" + b.toString(16)).slice(-2);
}
function rgb2(col) {
col += 0.000001;
var r = parseInt((0.15 + Math.cos(col) * 0.15) * 256);
var g = 1; //parseInt((0.5+Math.sin(col)*0.5)*256);
var b = parseInt((0.5 + Math.cos(col) * 0.5) * 256);
return "#" + ("0" + r.toString(16)).slice(-2) + ("0" + g.toString(16)).slice(-2) + ("0" + b.toString(16)).slice(-2);
}
function Vert(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
}
function Seg(x1, y1, z1, x2, y2, z2) {
this.a = new Vert(x1, y1, z1);
this.b = new Vert(x2, y2, z2);
this.dist = 0;
}
function Polygon() {
this.verts = [];
this.dist = 0;
}
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 transformShape(shape, scaleX, scaleY, scaleZ) {
for (var i = 0; i < shape.polys.length; ++i) {
for (var j = 0; j < shape.polys[i].segs.length; ++j) {
shape.polys[i].segs[j].a.x *= scaleX;
shape.polys[i].segs[j].a.y *= scaleY;
shape.polys[i].segs[j].a.z *= scaleZ;
shape.polys[i].segs[j].b.x *= scaleX;
shape.polys[i].segs[j].b.y *= scaleY;
shape.polys[i].segs[j].b.z *= scaleZ;
}
}
}
function process(vars) {
var x1, y1, z1, x2, y2, z2, x = y = z = 0,
d1, d2, v = 180;
x1 = vars.camX;
y1 = vars.camY;
z1 = vars.camZ;
d1 = Math.sqrt(vars.camX * vars.camX + vars.camY * vars.camY + vars.camZ * vars.camZ);
var p = vars.frameNo / 120;
x = Math.sin(p) * v;
y = -400;
z = -Math.sin(p * 2) * v / 2;
vars.camX = x;
vars.camY = y;
vars.camZ = z;
d2 = Math.sqrt(vars.camX * vars.camX + vars.camY * vars.camY + vars.camZ * vars.camZ);
vars.camX = vars.camX / d2 * d1;
vars.camY = vars.camY / d2 * d1;
vars.camZ = vars.camZ / d2 * d1;
vars.yaw = Math.atan2(vars.camX - x1, vars.camZ - z1);
vars.pitch = -elevation(vars.camX - x1, vars.camZ - z1, vars.camY - y1) + Math.PI / 2 + .3 + .1 * Math.cos(vars.frameNo / 30);
}
function sortFunction(a, b) {
return b.dist - a.dist;
}
function rand(seed) {
return parseFloat('0.' + Math.sin(seed).toString().substr(6));
}
function draw(vars) {
vars.ctx.globalAlpha = 1;
vars.ctx.fillStyle = "#000";
vars.ctx.fillRect(0, 0, vars.canvas.width, vars.canvas.height);
var t, x, y, z, x1, y1, z1, x2, y2, z2, point, visible;
var polys = [];
for (var i = 0; i < vars.shapes.length; ++i) {
for (var j = 0; j < vars.shapes[i].polys.length; ++j) {
vars.shapes[i].polys[j].dist = 0;
visible = 1;
vars.shapes[i].polys[j].shape = i;
vars.shapes[i].polys[j].index = j;
for (var k = 0; k < vars.shapes[i].polys[j].segs.length; ++k) {
x = vars.shapes[i].x + vars.shapes[i].polys[j].segs[k].a.x;
y = vars.shapes[i].y + vars.shapes[i].polys[j].segs[k].a.y;
z = vars.shapes[i].z + vars.shapes[i].polys[j].segs[k].a.z;
point = project3D(x, y, z, vars);
if ((point.d != -1) && (i || point.d < 160)) {
vars.shapes[i].polys[j].segs[k].rx = point.x;
vars.shapes[i].polys[j].segs[k].ry = point.y;
vars.shapes[i].polys[j].segs[k].dist = point.d;
vars.shapes[i].polys[j].dist += point.d;
} else {
visible = 0;
}
}
if (visible) polys.push(vars.shapes[i].polys[j]);
}
}
polys.sort(sortFunction);
var a;
for (var i = 0; i < polys.length; ++i) {
a = polys[i].shape ? 1 : 1 - Math.pow(polys[i].dist / polys[i].segs.length / 150, 10);
if (a > 0 && a <= 1) {
vars.ctx.fillStyle = polys[i].shape ? rgb2(polys[i].index / 8 - vars.frameNo / 12) : rgb(polys[i].index / 8 - vars.frameNo / 12);
vars.ctx.globalAlpha = a;
vars.ctx.beginPath();
x1 = polys[i].segs[0].rx;
y1 = polys[i].segs[0].ry;
vars.ctx.moveTo(x1, y1);
for (var k = 1; k < polys[i].segs.length; ++k) {
x2 = polys[i].segs[k].rx;
y2 = polys[i].segs[k].ry;
vars.ctx.lineTo(x2, y2);
}
vars.ctx.fill();
}
for (var k = 0; k < polys[i].segs.length; ++k) {
a = polys[i].shape ? 1 : 1 - Math.pow(polys[i].segs[k].dist / 150, 10) * 1;
if (a > 0 && a <= 1) {
vars.ctx.strokeStyle = polys[i].shape ? "#fff" : "#fff";
vars.ctx.globalAlpha = a * polys[i].shape ? .1 : .1;
x1 = polys[i].segs[k].rx;
y1 = polys[i].segs[k].ry;
t = (k + 1) % polys[i].segs.length;
x2 = polys[i].segs[t].rx;
y2 = polys[i].segs[t].ry;
vars.ctx.beginPath();
vars.ctx.moveTo(x1, y1);
vars.ctx.lineTo(x2, y2);
vars.ctx.lineWidth = 1 + (600 + polys[i].shape * 20000) / (1 + polys[i].dist);
vars.ctx.stroke();
}
}
}
}
function pushVert(p1, p2, dist, poly) {
x = Math.sin(p1) * Math.sin(p2) * dist;
z = Math.cos(p1) * Math.sin(p2) * dist;
y = Math.cos(p2) * dist;
poly.verts.push(new Vert(x, y, z));
}
function expandShape(shape, convexity) {
for (j = 0; j < shape.polys.length; ++j) {
for (k = 0; k < shape.polys[j].verts.length; ++k) {
x = shape.polys[j].verts[k].x;
y = shape.polys[j].verts[k].y;
z = shape.polys[j].verts[k].z;
d = Math.sqrt(x * x + y * y + z * z);
p1 = Math.atan2(x, y);
p2 = elevation(x, y, z);
d2 = d + (1 - d) * convexity;
shape.polys[j].verts[k].x = Math.sin(p1) * Math.sin(