# HTML5 3D Cube Slideshow

554人阅读 评论(0)

HTML5 3D Cube Slideshow

Our new tutorial tells us about creation of animated 3D Cube slideshow (pictures are located within the walls of the cube). The cube itself rotates continuously.

### Step 1. HTML

This is markup of our result slideshow page. Here it is.

#### index.html

<!DOCTYPE html>
<html lang="en" >
<meta charset="utf-8" />
<title>HTML5 3D Cube Slideshow | Script Tutorials</title>
<script src="js/script.js"></script>
<body>
<h2>HTML5 3D Cube Slideshow</h2>
<a href="http://www.script-tutorials.com/html5-3d-cube-slideshow/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
<canvas id="slideshow" width="1280" height="800"></canvas>
</body>
</html>


### Step 2. CSS

#### css/main.css

That file available in package (because it just contains styles of page layout)

### Step 3. JS

#### js/script.js

var canvas, ctx;
var aImages = [];
var points = [];
var triangles = [];
var textureWidth, textureHeight;
var lev = 3;
var angle = 0;

// scene vertices
var vertices = [
new Point3D(-2,-1,2),
new Point3D(2,-1,2),
new Point3D(2,1,2),
new Point3D(-2,1,2),
new Point3D(-2,-1,-2),
new Point3D(2,-1,-2),
new Point3D(2,1,-2),
new Point3D(-2,1,-2)
];

// scene faces (6 faces)
var faces  = [[0,1,2,3],[1,5,6,2],[5,4,7,6],[4,0,3,7],[0,4,5,1],[3,2,6,7]];

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

this.rotateX = function(angle) {
var rad, cosa, sina, y, z
rad = angle * Math.PI / 180
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
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
x = this.x * cosa - this.y * sina
y = this.x * sina + this.y * cosa
return new Point3D(x, y, this.z)
}
this.projection = function(viewWidth, viewHeight, fov, viewDistance) {
var factor, x, y
factor = fov / (viewDistance + this.z)
x = this.x * factor + viewWidth / 2
y = this.y * factor + viewHeight / 2
return new Point3D(x, y, this.z)
}
}

// array of photos
var aImgs = [
'images/pic1.jpg',
'images/pic2.jpg',
'images/pic3.jpg',
'images/pic4.jpg'
];
for (var i = 0; i < aImgs.length; i++) {
var oImg = new Image();
oImg.src = aImgs[i];
aImages.push(oImg);

textureWidth = oImg.width;
textureHeight = oImg.height;
}
}

// creating canvas objects
canvas = document.getElementById('slideshow');
ctx = canvas.getContext('2d');

// prepare points
for (var i = 0; i <= lev; i++) {
for (var j = 0; j <= lev; j++) {
var tx = (i * (textureWidth / lev));
var ty = (j * (textureHeight / lev));
points.push({
tx: tx,
ty: ty,
nx: tx / textureWidth,
ny: ty / textureHeight,
ox: i,
oy: j
});
}
}

// prepare triangles ----
var levT = lev + 1;
for (var i = 0; i < lev; i++) {
for (var j = 0; j < lev; j++) {
triangles.push({
p0: points[j + i * levT],
p1: points[j + i * levT + 1],
p2: points[j + (i + 1) * levT],
up: true
});
triangles.push({
p0: points[j + (i + 1) * levT + 1],
p1: points[j + (i + 1) * levT],
p2: points[j + i * levT + 1],
up: false
});
}
}

drawScene();
};

function drawScene() {
// clear context
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

// rotate scene
var t = new Array();
for (var iv = 0; iv < vertices.length; iv++) {
var v = vertices[iv];
var r = v.rotateY(angle);
//var r = v.rotateX(angle).rotateY(angle);
var prj = r.projection(ctx.canvas.width, ctx.canvas.height, 1000, 3);
t.push(prj)
}

var avg_z = new Array();
for (var i = 0; i < faces.length; i++) {
var f = faces[i];
avg_z[i] = {"ind":i, "z":(t[f[0]].z + t[f[1]].z + t[f[2]].z + t[f[3]].z) / 4.0};
}

// get around through all faces
for (var i = 0; i < faces.length; i++) {
var f = faces[avg_z[i].ind];

if (t[f[3]].z+t[f[2]].z+t[f[1]].z+t[f[0]].z > -3) {
ctx.save();

// draw surfaces
ctx.fillStyle = "rgb(160,180,160)";
ctx.beginPath();
ctx.moveTo(t[f[0]].x,t[f[0]].y);
ctx.lineTo(t[f[1]].x,t[f[1]].y);
ctx.lineTo(t[f[2]].x,t[f[2]].y);
ctx.lineTo(t[f[3]].x,t[f[3]].y);
ctx.closePath();
ctx.fill();

// draw stretched images
if (i < 4) {
var ip = points.length;
while (--ip > -1) {
var p = points[ip];
var mx = t[f[0]].x + p.ny * (t[f[3]].x - t[f[0]].x);
var my = t[f[0]].y + p.ny * (t[f[3]].y - t[f[0]].y);
p.px = (mx + p.nx * (t[f[1]].x + p.ny * (t[f[2]].x - t[f[1]].x) - mx)) + p.ox;
p.py = (my + p.nx * (t[f[1]].y + p.ny * (t[f[2]].y - t[f[1]].y) - my)) + p.oy;
}

var n = triangles.length;
while (--n > -1) {
var tri = triangles[n];
var p0 = tri.p0;
var p1 = tri.p1;
var p2 = tri.p2;

var xc = (p0.px + p1.px + p2.px) / 3;
var yc = (p0.py + p1.py + p2.py) / 3;

ctx.save();
ctx.beginPath();
ctx.moveTo((1.05 * p0.px - xc * 0.05), (1.05 * p0.py - yc * 0.05));
ctx.lineTo((1.05 * p1.px - xc * 0.05), (1.05 * p1.py - yc * 0.05));
ctx.lineTo((1.05 * p2.px - xc * 0.05), (1.05 * p2.py - yc * 0.05));
ctx.closePath();
ctx.clip();

// transformation
var d = p0.tx * (p2.ty - p1.ty) - p1.tx * p2.ty + p2.tx * p1.ty + (p1.tx - p2.tx) * p0.ty;
ctx.transform(
-(p0.ty * (p2.px - p1.px) -  p1.ty * p2.px  + p2.ty *  p1.px + (p1.ty - p2.ty) * p0.px) / d, // m11
(p1.ty *  p2.py + p0.ty  * (p1.py - p2.py) - p2.ty *  p1.py + (p2.ty - p1.ty) * p0.py) / d, // m12
(p0.tx * (p2.px - p1.px) -  p1.tx * p2.px  + p2.tx *  p1.px + (p1.tx - p2.tx) * p0.px) / d, // m21
-(p1.tx *  p2.py + p0.tx  * (p1.py - p2.py) - p2.tx *  p1.py + (p2.tx - p1.tx) * p0.py) / d, // m22
(p0.tx * (p2.ty * p1.px  -  p1.ty * p2.px) + p0.ty * (p1.tx *  p2.px - p2.tx  * p1.px) + (p2.tx * p1.ty - p1.tx * p2.ty) * p0.px) / d, // dx
(p0.tx * (p2.ty * p1.py  -  p1.ty * p2.py) + p0.ty * (p1.tx *  p2.py - p2.tx  * p1.py) + (p2.tx * p1.ty - p1.tx * p2.ty) * p0.py) / d  // dy
);
ctx.drawImage(aImages[i], 0, 0);
ctx.restore();
}
}
}
}

// shift angle and redraw scene
angle += 0.3;
setTimeout(drawScene, 40);
}


At the first, I have defined all vertices and faces (walls) of our virtual cube. Then I have defined rules of rotating. After – the most difficult thing – transformation of images with using ‘clip’ and ‘transform’.

### Conclusion

I hope that today’s 3D html5 cube lesson has been interesting for you. We have done another one nice html5 example. I will be glad to see your thanks and comments. Good luck!

### HTML5 Canvas Slideshow

0
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：901030次
• 积分：10578
• 等级：
• 排名：第1530名
• 原创：92篇
• 转载：1171篇
• 译文：11篇
• 评论：28条
评论排行
最新评论