您的位置:首页 > Web前端 > JavaScript

一个很不错的JS3D效果。收藏一下

2011-01-13 14:37 639 查看
JSCube可以创建一个立方体,将6个HTML元素贴在其面上,并支持旋转和缩放。

当前最新版本1.6.0。支持IE,FireFox,Opear,Chrome,Safari浏览器。

脚本引用地址:http://www.etherdream.com/FunnyScript/WitCube/Cube.js

Cube.js导出一个类:Cube。

共4个方法:
setLocate(cx, cy)
页面中定位立方体。
(cx, cy)为立方体中心点坐标

setFace(id, elem)
立方体贴面。
id: 立方体面编号
elem: 页面中的HTML元素

setRadius(r)
设置立方体中心点到顶点的距离。

rotate(angleX, angleY, angleZ)
旋转立方体。
angleX: 绕X轴旋转1角度
...

6个静态属性:
Cube.FACE_FRONT = 0
Cube.FACE_RIGHT = 1
Cube.FACE_BACK = 2
Cube.FACE_LEFT = 3
Cube.FACE_TOP = 4
Cube.FACE_BOTTOM = 5
顾名思义,立方体前后左右上下面的ID编号。
用于setFace的第一个参数。

一个简单的Demo: http://www.etherdream.com/FunnyScript/WitCube/GCube.html

发挥你想象,可以做出很多有趣的东西。
原贴地址:http://topic.csdn.net/u/20110112/21/252dab4e-eace-494c-8129-cf81a3db271c.html?35253
源码如下:
/****************************************
* HTML立方体插件 v1.6.0
*   By EtherDream (c) 2006-2010
* 最后更新: 2010.12.25
**/
var Cube;

(function(){
/*******************
*     |+y
*     |
*     0----- +x
*    /
*   /+z
******************/
function Point(x, y, z)
{
var _x = x;
var _y = y;
var _z = z;

this.update = function()
{
this.rx = _x;
this.ry = _y;
this.deepth = _z;	//无限远
};

this.rotate = function(radX, radY, radZ)
{
var x,y,z;
var sin, cos;

if(radX)
{
sin = Math.sin(radX);
cos = Math.cos(radX);
y = cos * _y - sin * _z;
z = cos * _z + sin * _y;
_y = y;
_z = z;
}

if(radY)
{
sin = Math.sin(radY);
cos = Math.cos(radY);
x = cos * _x - sin * _z;
z = cos * _z + sin * _x;
_x = x;
_z = z;
}

if(radZ)
{
sin = Math.sin(radZ);
cos = Math.cos(radZ);
x = cos * _x - sin * _y;
y = cos * _y + sin * _x;
_x = x;
_y = y;
}

this.update();
};

this.update();
}

/*****************************
*   p1--------p2
*   |          |
*   p3--------p4
*****************************/
function Face(p1, p2, p3, p4)
{
var P1 = p1;
var P2 = p2;
var P3 = p3;
var P4 = p4;

/***************************************************
*    P(x,y) + [a,b,c,d,tx,ty]
* => P(ax+by+tx, cx+dy+ty)
***************************************************/
this.getMatrix = function()
{
var tx = P1.rx;
var ty = P1.ry;

var a = (P2.rx - tx) / 2;
var b = (ty - P2.ry) / 2;

var c = (P3.rx - tx) / 2;
var d = (ty - P3.ry) / 2;

return [a, b, c, d, tx, ty];
};

this.getDeepth = function()
{
return P1.deepth + P4.deepth;
};

this.getBlockX = function()
{
return Math.min(P1.rx, P2.rx, P3.rx, P4.rx);
};

this.getBlockY = function()
{
return Math.max(P1.ry, P2.ry, P3.ry, P4.ry);
};
}

Cube = function()
{
/*******************
*    4-------5
*   /|      /|
*  0-------1 |
*  | |     | |
*  | 7- - -|-6
*  |/      |/
*  3-------2
*******************/
var R = 35;
var P =
[
new Point(-1, +1, +1),
new Point(+1, +1, +1),
new Point(+1, -1, +1),
new Point(-1, -1, +1),

new Point(-1, +1, -1),
new Point(+1, +1, -1),
new Point(+1, -1, -1),
new Point(-1, -1, -1)
];
var F =
[
new Face(P[0], P[1], P[3], P[2]), //前
new Face(P[1], P[5], P[2], P[6]), //右
new Face(P[5], P[4], P[6], P[7]), //后
new Face(P[4], P[0], P[7], P[3]), //左
new Face(P[4], P[5], P[0], P[1]), //上
new Face(P[3], P[2], P[7], P[6])  //下
];

var _cx, _cy;
var arrSty = [];
var arrFlt = [];
var keyName;

var ver = navigator.userAgent;
var isIE = /MSIE/.test(ver);
var isFF = /Firefox/.test(ver);
var RAD = Math.PI / 180;

function apply(id, visible)
{
var sty = arrSty[id];
if(!sty)
return;

if(visible)
sty.display = "block";
else
{
sty.display = "none";
return;
}

var face = F[id];
var m = face.getMatrix(R);

//0.123456
for(var i=0; i<6; i++)
m[i] = ((m[i] * 1e6) >> 0) / 1e6;

if(isIE)
{
//IE Matrix滤镜
var objFlt = arrFlt[id];

objFlt.M11 = m[0];
objFlt.M21 = m[1];
objFlt.M12 = m[2];
objFlt.M22 = m[3];
//objFlt.Dx = m[4];	//设置了没有效果
//objFlt.Dy = m[5];

sty.pixelLeft = _cx + R * face.getBlockX();
sty.pixelTop = _cy - R * face.getBlockY();
}
else
{
//CSS3
m[4] = _cx + R * m[4];
m[5] = _cy - R * m[5];

if(isFF)
{
m[4] += "px";
m[5] += "px";
}
sty[keyName] = "matrix(" + m.join(",") + ")";
}
}

function draw()
{
var deepth = [];
var i;

/*
* 深度排序
*/
for(i=0; i<6; i++)
deepth[i] = {id:i, val:F[i].getDeepth()};

deepth.sort(function(a,b){return (a.val>b.val)?-1:1});

/*
* 0-2: visible
* 3-5: hidden
*/
for(i=0; i<6; i++)
apply(deepth[i].id, i<3);
}

function updateSize(sty)
{
var D = R+R;
if(!isIE)	//解决边框分离
D-=2;

sty.width = Math.round(D) + "px";
sty.height = Math.round(D) + "px";
}

/**
* setLocate:
*   页面中定位立方体。
*   (cx, cy)为立方体中心点坐标
*/
this.setLocate = function(cx, cy)
{
_cx = cx;
_cy = cy;
draw();
};

/**
* setFace:
*   立方体贴面。
*   id: 立方体面编号
*   elem: 页面中的HTML元素
*/
this.setFace = function(id, elem)
{
if(arrSty[id])
arrSty[id].display = "none";

var sty = elem.style;
arrSty[id] = sty;

sty.position = "absolute";
sty.left = "0";
sty.top = "0";
sty.margin = "0";
sty.border = "#000 1px solid";

if(isIE)
{
//IE Filter
var s = "DXImageTransform.Microsoft.Matrix";
sty.filter = "progid:" + s + "(sizingMethod='auto expand')";
arrFlt[id] = elem.filters[s];
}
else
{
//CSS3 transform
if(!keyName)
{
if(sty.MozTransform != null)			//FireFox
keyName = "MozTransform";
else if(sty.WebkitTransform != null)	//Chrome,Safari
keyName = "WebkitTransform";
else if(sty.OTransform != null)			//Opera
keyName = "OTransform";
else
throw new Error("浏览器不支持");
}
//调整参照点
sty[keyName + "Origin"]	= "0% 0%";
}

updateSize(sty);
draw();
};

/**
* setRadius:
*   设置立方体中心点到顶点的距离。
*/
this.setRadius = function(r)
{
R = r;
for(var i=0,sty; i<8; i++)
if(sty = arrSty[i])
updateSize(sty);
draw();
};

/**
* rotate:
*   旋转立方体。
*   angleX: 绕X轴旋转1角度
*   ...
*/
this.rotate = function(angleX, angleY, angleZ)
{
for(var i=0; i<8; i++)
P[i].rotate(RAD*angleX, RAD*angleY, RAD*angleZ);
draw();
};
};

Cube.FACE_FRONT = 0;
Cube.FACE_RIGHT = 1;
Cube.FACE_BACK = 2;
Cube.FACE_LEFT = 3;
Cube.FACE_TOP = 4;
Cube.FACE_BOTTOM = 5;

})()	//End Module
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: