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

第十讲:html5中canvas实现正方体的动态旋转

2014-06-11 20:48 323 查看
在html5的画布上,画出三维图形,并且实现它动态的围着一条轴进行旋转。

实现步骤:

1、定义一个对象Vector3,用于存储三维的坐标

2、定义一个观察点坐标和显示屏,初始化观察点的显示屏的距离(主要通过他们计算出各个点在二维平面的坐标值)

3、定义八个点(为了方便计算,我将会是画布和坐标进行i平移和旋转)

4、通过一定的公式,计算出八个点显示在平面的坐标(x,y)

5、使用moveTo和lineTo连接所有的直线

6、定义进行旋转的方法(难点,主要使用三维立体计算出各个点的推导公式)

7、最后进行旋转

<html>
<head>
<title>3D图形(3D旋转)</title>
<script src="../js/jscex.jscexRequire.min.js" type="text/javascript"></script>
<style type="text/css">
body{margin: 0 0 0 0;padding: 0 0 0 0;}
</style>
</head>

<body>
<canvas id="mc" width="600px" height="600px" style="background-color: #111;">
</canvas>
<script type="text/javascript">
//定义一个三维矢量类
Vector3 = function(x,y,z){
this.x = x;
this.y = y;
this.z = z;
}
//////////////////////////////////////////////////
var canvas = document.getElementById('mc');
var cxt = canvas.getContext('2d');
//定义一些常量,用于以后使用
var currentAngle = 0;
var translateX = 300;
var translateY = 300;
var points = [];
var distance = 500;//定义摄像机和摄像机距离显示屏的距离
var eyePosition = new Vector3(0,0,700);//定义眼睛所在的位置
cxt.translate(translateX,translateY);
cxt.scale(1,-1);//是的y的方向相反
//初始化八个顶点
function init_eight_points(){
//z轴上面的四个点
points[0] = new Vector3(100,100,100);
points[1] = new Vector3(100,-100,100);
points[2] = new Vector3(-100,-100,100);
points[3] = new Vector3(-100,100,100);
//下面四个点
points[4] = new Vector3(100,100,-100);
points[5] = new Vector3(100,-100,-100);
points[6] = new Vector3(-100,-100,-100);
points[7] = new Vector3(-100,100,-100);
}
//8个顶点、摄像机、摄像机到显示屏的距离都已经有了。就可以开始计算八个顶点到显示屏上面的x、y坐标了
//projection 投射、发射、推测
function chang_projection(){
for(var i = 0 ;i < points.length ; i++){
points[i].x = points[i].x * distance / Math.abs(eyePosition.z - points[i].z);
points[i].y = points[i].y * distance / Math.abs(eyePosition.z - points[i].z);
}
}
//已经计算出来了所有点的坐标,接下来就是把所有的点的坐标连接起来就行
function drawCube(){
//画出下面的八条虚线
cxt.strokeStyle = "#0FF595";
cxt.lineWidth = 2;
cxt.beginPath();
cxt.moveTo(points[4].x,points[4].y);
cxt.lineTo(points[5].x,points[5].y);
cxt.lineTo(points[6].x,points[6].y);
cxt.lineTo(points[7].x,points[7].y);
cxt.lineTo(points[4].x,points[4].y);
cxt.lineTo(points[0].x,points[0].y);
cxt.moveTo(points[5].x,points[5].y);
cxt.lineTo(points[1].x,points[1].y);
cxt.moveTo(points[6].x,points[6].y);
cxt.lineTo(points[2].x,points[2].y);
cxt.moveTo(points[7].x,points[7].y);
cxt.lineTo(points[3].x,points[3].y);
cxt.moveTo(points[0].x,points[0].y);
cxt.lineTo(points[1].x,points[1].y);
cxt.lineTo(points[2].x,points[2].y);
cxt.lineTo(points[3].x,points[3].y);
cxt.lineTo(points[0].x,points[0].y);
cxt.stroke();
}
//旋转计算坐标的方法 (沿着x轴旋转)

function rotate(angle){
//沿着x轴进行旋转
for (i = 0; i < points.length; i++) {
var tempY = points[i].y;
points[i].y = points[i].y * Math.cos(angle) - points[i].z * Math.sin(angle);
points[i].z = tempY * Math.sin(angle) + points[i].z * Math.cos(angle);
}
//沿着y轴进行旋转
for (var i = 0; i < points.length; i++) {
var tempX = points[i].x;
points[i].x = points[i].x * Math.cos(angle) - points[i].z * Math.sin(angle);
points[i].z = points[i].z * Math.cos(angle) + tempX * Math.sin(angle);
}
//沿着z轴进行旋转
for(var i = 0 ; i < points.length ; i++){
var tempX = points[i].x;
var tempY = points[i].y;
points[i].x = tempX * Math.cos(angle) - tempY * Math.sin(angle);
points[i].y = tempX * Math.sin(angle) + tempY * Math.cos(angle);
}
}
//计算角度的方法
function degToRad(a){
return a * Math.PI / 180;
}
//移动显示屏改变其三维投影的图形
var somethingAsync = eval(Jscex.compile("async", function () {
while (true) {
cxt.clearRect(-translateX,-translateY,canvas.width,canvas.height);//清除画布
init_eight_points();//初始化所有的点
rotate(degToRad(currentAngle));//旋转角度之后,计算所有的点坐标
currentAngle += 10;//每次以10°的频率旋转
chang_projection();//计算所有点在二维平面的上的坐标
drawCube();//画出所有的图形
$await(Jscex.Async.sleep(100));
}
}));
somethingAsync().start();
</script>
<br>

</body>
</html>


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