rotate 3D [初识篇]

rotate 3D [初识篇]随着前端技术发展 尤其是 html5 中 canvas 和 svg 的应用 开始让 web 也可以轻易的渲染出各种绚丽的效果

大家好,欢迎来到IT知识分享网。

随着前端技术发展,尤其是html5中canvas和svg的应用,开始让web也可以轻易的渲染出各种绚丽的效果。

本篇讨论的是基于rotate(旋转)的3d效果的初识。在canvas的getContext(‘2d’)下利用一些变换来模拟。webGL是后话,本篇暂不讨论。

最直观的感觉就是可以想象一张拍很长走廊的照片,照片里的走廊一定是近处宽,随着距离的拉远,走廊宽度一定是渐窄,看起来就像是两条斜线向远处延伸。

// 创建一个小球 
var ball = createBall(ballR);
//添加到舞台
stage.addChild(ball);
//取得画布中心位置
vpx = canvas.width/2;
vpy = canvas.height/2;

// 取得当前鼠标相对中心偏移距离 xpos, ypos
stage.addEventListener('mousemove', function (x, y) {
xpos
= x - vpx;
ypos
= y - vpy;
});

// 用键盘上下键改变z坐标的位置
document.addEventListener('keydown', function (e) {
if (e.keyCode == 38) zpos += 5;
if (e.keyCode == 40) zpos -=5;
},
false)


// 每帧刷新时的改变
stage.onRefresh = function () {
// 将z坐标扁平化
var scale = focalLength/(focalLength + zpos);
// 将扁平後z坐标对x,y的影响给小球坐标
ball.x = vpx + xpos*scale;
ball.y
= vpy + ypos*scale;
// 对小球大小的影响
ball.width = ballR*2*scale;

document.getElementById(

'scale').innerHTML = scale;
}

stage.start();


<!DOCTYPE html><html><style> html {overflow:hidden} body {position: absolute; margin:0; padding:0;width:100%; height:100%} canvas {display:block;border:2px solid #ccc; margin:10px auto;} p {text-align: center; font-size:12px;color:#454545;} </style><script src=”http://hongru.github.com/js/JCanvas.js”></script> <canvas id=”canvas” width=”600″ height=”400″></canvas><p>键盘上下键改变z方向深度。 当前scale:<span id=”scale”></span></p><script> var canvas = document.getElementById(‘canvas’); var stage = new Stage(canvas); var createBall = function (radius) { radius = (radius === undefined) ? 20 : radius; return new Sprite(stage.ctx, { x: 0, y: 0, width: radius*2, draw: function () { this.ctx.beginPath(); this.ctx.arc(0, 0, this.width/2, 0, Math.PI*2, true); this.ctx.closePath(); this.ctx.fillStyle = ‘rgba(0,0,0,’+ Math.min(1, this.width/(2*radius)) +’)’; this.ctx.fill(); } }); }; var initialize = function () { var xpos = 0, ypos = 0, zpos = 0, focalLength = 250, ballR = 20, vpx, vpy; var ball = createBall(ballR); stage.addChild(ball); vpx = canvas.width/2; vpy = canvas.height/2; stage.addEventListener(‘mousemove’, function (x, y) { xpos = x – vpx; ypos = y – vpy; }); document.addEventListener(‘keydown’, function (e) { if (e.keyCode == 38) zpos += 5; if (e.keyCode == 40) zpos -=5; }, false) stage.onRefresh = function () { var scale = focalLength/(focalLength + zpos); ball.x = vpx + xpos*scale; ball.y = vpy + ypos*scale; ball.width = ballR*2*scale; document.getElementById(‘scale’).innerHTML = scale; } stage.start(); }; initialize(); </script></html>

 

// 获取画布中心 
vpx = canvas.width/2;
vpy = canvas.height/2;

// 根据鼠标位置计算选装角度(速度)
stage.addEventListener('mousemove', function (x, y) {
angleY
= (x - vpx) * .001;
});



// 主旋转函数
function rotateY(ball, angleY) {
// 把角度三角函数化,以便看起来是绕圆旋转
var cosy = Math.cos(angleY),
siny
= Math.sin(angleY),
// 把 z方向影响算进来
x1 = ball.xpos * cosy - ball.zpos * siny,
z1
= ball.zpos * cosy + ball.xpos * siny;
ball.xpos
= x1;
ball.zpos
= z1;


// z坐标扁平化,并赋给小球影响
var scale = focalLength / (focalLength + ball.zpos);
ball.x
= vpx + ball.xpos * scale;
ball.y
= vpy + ball.ypos * scale;
ball.width
= ballR*2*scale;
}

<!DOCTYPE html><html><style> html {overflow:hidden} body {position: absolute; margin:0; padding:0;width:100%; height:100%} canvas {display:block;border:2px solid #ccc; margin:10px auto;} p {text-align: center; font-size:12px;color:#454545;} </style><script src=”http://hongru.github.com/js/JCanvas.js” ></script> <canvas id=”canvas” width=”600″ height=”400″></canvas><p></p><script > var canvas = document.getElementById(‘canvas’); var stage = new Stage(canvas); var createBall = function (radius) { radius = (radius === undefined) ? 20 : radius; return new Sprite(stage.ctx, { x: 0, y: 0, width: radius*2, draw: function () { this.ctx.beginPath(); this.ctx.arc(0, 0, this.width/2, 0, Math.PI*2, true); this.ctx.closePath(); this.ctx.fillStyle = ‘rgba(0,0,0,’+ Math.min(1, this.width/(2*radius)) +’)’; this.ctx.fill(); } }); }; var initialize = function () { var focalLength = 250, ballR = 20, ballN = 20, balls = [], vpx = 0, vpy = 0, angleY = 0; for (var i=0; i<ballN; i++) { var ball = createBall(ballR); stage.addChild(ball); ball.xpos = Math.random() * 200 – 100; ball.ypos = Math.random() * 200 – 100; ball.zpos = Math.random() * 200 – 100; balls.push(ball); } vpx = canvas.width/2; vpy = canvas.height/2; stage.addEventListener(‘mousemove’, function (x, y) { angleY = (x – vpx) * .001; }); 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; var scale = focalLength / (focalLength + ball.zpos); ball.x = vpx + ball.xpos * scale; ball.y = vpy + ball.ypos * scale; ball.width = ballR*2*scale; } stage.onRefresh = function () { for (var i=0,ball; ball=balls[i]; i++) { rotateY(ball, angleY) } } stage.start(); }; onload = initialize; </script></html>

 

恩,本来这篇还想多写点的,但是肚子饿了,木办法,先去填肚子了,明天还要上班….

今天中秋,虽然迟了点,还是祝各位园友佳节快乐吧。

下篇继续…

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/128879.html

(0)
上一篇 2025-08-28 16:15
下一篇 2025-08-28 16:20

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信