经验大分享:rotate3D篇二

简介: 经验大分享:rotate3D篇二

接上一篇,基于rotate的方式模拟三维空间。

一开始定一个旋转原点,让物体随着这个原点旋转。(一般定为画布中心)

vpx = canvas.Width</span>/2;

vpy = canvas.Height</span>/2;

然后为了让旋转效果和用户有交互,让旋转速度和角度和鼠标位置挂上关系

stage.addEventListener('mousemove', function (x, y) {

angleY = (x - vpx) .001;

angleX = (y - vpy) .001;

});

接下来,如果我们有个三维空间里的小球ball,它有三向坐标(xpos, ypos, zpos)。下面就要计算出经过一个角度变化后的三个坐标

// 绕y轴变化,得出新的x,z坐标

function rotateY(ball, angleY) {

var cosy = Math.cos(angleY),

siny = Math.sin(angleY),

x1 = ball.xpos cosy - ball.zpos siny,

z1 = ball.zpos cosy + ball.xpos siny;

ball.xpos = x1;

ball.zpos = z1;

}

上面是绕y轴的,同理,可以得出绕x轴的

function rotateX(ball, angleX) {

var cosx = Math.cos(angleX),

sinx = Math.sin(angleX),

y1 = ball.ypos cosx - ball.zpos sinx,

z1 = ball.zpos cosx + ball.ypos sinx;

// 新位置

ball.ypos = y1;

ball.zpos = z1;

}

经过变换得到新的(xpos, ypos, zpos)后,接下来要做的事情就是把这个三维坐标的zpos去掉,也就是变换到二维空间来。

根据上文说的,在普通的模型中,z坐标对x,y的影响在二维体系里一般表现在对x,y造成偏移量,对大小,透明度这几个属性的影响。所以,把三维空间降到二维中来

function render (ball) {

// focalLength 表示当前焦距,一般可设为一个常量

if (ball.zpos

// 把z方向扁平化

var scale = focalLength / (focalLength + ball.zpos);

ball.x = vpx + ball.xpos scale;

ball.y = vpy + ball.ypos scale;

ball.width = ballR2scale;

}//代码效果参考:http://www.ezhiqi.com/bx/art_4983.html

}//代码效果参考:http://www.ezhiqi.com/bx/art_4395.html

到此,基本上绕一个固定点的旋转模型就可以了。但是由于canvas绘制矢量图是根据代码执行顺序画上去的。而通常我们都是直接用一个数组作为collection来搜集管理各个点(比如小球)。而这个数组并没有按照我们需要的根据z方向的大小来排序,所以直接一个for循环进去按个绘制小球的时候会发现:

z方向对于x,y的偏移,小球大小,透明度等都是正确渲染的,但是有个问题就是会出现距离近的球反而被挡在距离远的球后面(不透的球在半透球后面)。造成这个现象的原因就是上面所说。

所以为了解决这个问题,有个办法就是每次变换后对我们collection里面的元素按z的大小顺序重排一下就ok

function sortZ () {

balls.sort(function (a, b) { return b.zpos-a.zpos })

stage.children.sort(function (a, b) { return b.zpos-a.zpos })

}

至此,一个【多点绕固定点旋转】3d模型表现如下:

html {overflow:hidden}

body {position: absolute; margin:0; padding:0;width:100%; height:100%}

canvas {display:block;border:2px solid #ccc; margin:10px auto;}//代码效果参考:http://www.ezhiqi.com/zx/art_2774.html

p {text-align: center; font-size:12px;color:#454545;}

相关文章
|
3月前
|
前端开发 JavaScript Serverless
揭秘CSS布局神器:vw/vh、rem、%与px大PK,掌握它们,让你的网页设计秒变高大上,面试难题迎刃而解!
【8月更文挑战第4天】在Web开发中,合理选择CSS单位对响应式布局至关重要。本文探索viewport单位(vw/vh)、rem、百分比(%)及像素(px)的基础知识与应用场景。通过代码示例,展示如何运用这些单位实现全屏布局、尺寸比例调整、灵活的元素大小及固定尺寸。最后,模拟面试题,介绍如何仅用CSS实现一个元素的高度为其宽度两倍且响应视口变化的方法。
248 8
|
5月前
|
移动开发 前端开发 HTML5
技术经验解读:关于前端的margin
技术经验解读:关于前端的margin
44 0
|
5月前
|
XML JavaScript 前端开发
技术经验分享:fadeIn()与fadeOut()方法
技术经验分享:fadeIn()与fadeOut()方法
36 0
|
5月前
|
XML JSON 监控
技术经验分享:Axis2实践
技术经验分享:Axis2实践
70 0
|
5月前
|
前端开发
技术经验分享:DIV居中的经典方法
技术经验分享:DIV居中的经典方法
21 0
|
前端开发
Canvas知识点梳理2
Canvas知识点梳理2
72 1
|
前端开发
今天来讲讲 scale、translate 和 rotate 这三个属性,你不会以为我是要讲的是 transform 吧?
总所周知,transform 是 CSS3 中最强大的属性之一,它有这么三个函数属性值:scale、translate 和 rotate,它们分别是缩放、位移和旋转,但是你有没有想过有这么一天它们三个
268 0
今天来讲讲 scale、translate 和 rotate 这三个属性,你不会以为我是要讲的是 transform 吧?
|
移动开发 前端开发 JavaScript
Canvas知识点梳理1
Canvas知识点梳理1
62 0
|
C++
【PAT甲级 - C++题解】1033 To Fill or Not to Fill
【PAT甲级 - C++题解】1033 To Fill or Not to Fill
64 0
CF76.E. Points (贡献 思维)
CF76.E. Points (贡献 思维)
75 0