每周一点canvas动画代码文件
在上一节《每周一点canvas动画》——3D物理效果中,咱们介绍了3维环境下的速度与加速度效果。这一节,咱们继续介绍另外两个物理效果:重力和屏幕环绕。html
三维系统中实现重力效果的方式与二维的状况同样,设定一个重力值,好比g=0.2
。而后,在动画循环中将它做用于物体竖直方向的速度上。虽然原理上没有什么大的变化,可是多了一个维度实现出来的效果确实至关具备视觉冲击力的。ok,一图胜千言,与其在这听我嘚吧嘚吧嘚,还不如直接上个效果图。git
在动画中,咱们为小球的下落设置了一个边界——至关于地面,并与反弹的效果结合在一块儿,当小球触碰到地面发生反弹。与二维系统中的效果一模一样。下面是核心代码,具体代码请看gravity.html
:github
。。。 function move(ball){ ball.vy += gravity; //重力加速度 ball.xpos += ball.vx; ball.ypos += ball.vy; ball.zpos += ball.vz; if (ball.ypos > floor) { //触地反弹 ball.ypos = floor; ball.vy *= bounce; } if(ball.zpos > -fl){ //3维场景设置 var scale = fl/(fl + ball.zpos); ball.scaleX = ball.scaleY = scale; ball.x = vpX + ball.xpos * scale; ball.y = vpY + ball.ypos * scale; ball.visible = true; }else{ ball.visible = false; } } 。。。
屏幕环绕是咱们今天的重头戏,与二维环境中的概念同样。所谓屏幕环绕就是从屏幕的这端消失,相应的从屏幕的另外一边出来。对应到三维的环境中,咱们就多了一个纬度的选择。下面咱们介绍第一个效果——森林canvas
绘制森林前咱们要作的第一个准备工做是绘制森林的基本组成单元——tree。在这里我提供了3个树的类文件。segmentfault
与球类文件的引入和使用方式同样,下面咱们展现一下三种文件的绘制效果。bash
简单树的绘制效果如图所示,若是你想要让它的枝条更多,再多加两条树枝就能够了。类文件tree.js
,没有什么特别的,只是用到简单的lineTo
,moveTo
等API。动画
二叉树的类文件名为binaryTree.js
。与简单树的原理不同,二叉树的原理是采用递归的方法实现树枝与树干的绘制。绘制效果如图:this
具体代码以下:spa
/* gen: 树枝的节点代数,默认是6个节点*/ /* angle: 每次在节点树枝的旋转角度*/ /* branchLength: 树枝的长度*/ function Tree(color, angle, genNum, branchLength){ this.x = 0; this.y = 0; this.xpos = 0; this.ypos = 0; this.zpos = 0 this.scaleX = 0.85; this.scaleY = 0.85; this.gen = 0; this.alpha = 1; this.color = utils.parseColor(color); this.angle = (angle === undefined) ? 0.3 : angle; this.genNum = (genNum === undefined) ? 6 : genNum; this.branchLength = (branchLength === undefined) ? 40 : branchLength; } Tree.prototype.draw = function(ctx){ ctx.save() ctx.translate(this.x, this.y); this.branch(ctx, 0); //初始角度为0, 绘制树干 ctx.restore(); } Tree.prototype.branch= function(ctx, initAngle){ this.gen++; ctx.save(); ctx.strokeStyle = this.color; ctx.rotate(initAngle); ctx.scale(this.scaleX, this.scaleY); ctx.beginPath(); ctx.moveTo(0, 0); ctx.translate(0, -this.branchLength); ctx.lineTo(0, 0); ctx.stroke(); if(this.gen <= this.genNum){ //判断当前的节点代数是否大于设置的节点数 this.branch(ctx, this.angle); //画右边树枝 this.branch(ctx, -this.angle); //画左侧树枝 } ctx.restore(); this.gen--; }
二叉树的造型已经与咱们现实中的树木结构有类似之处了。下一步咱们就经过这种绘制二叉树的方法来实现天然树。prototype
天然树的原理与二叉树的原理彻底同样,不一样之处在于对树枝的分叉设置了更多的随机性。也就是说,不会像咱们上面看到的同样,树枝的分叉那么有对称性。而且,在树枝的末端绘制树叶。ok,下面展现一下用canvas绘制的艺术品。
怎么样,帅气吧!是否是跟真的树如出一辙。代码有点长,我在这就不列出来了,具体代码请查看binaryTree.js
。若是你想体验不一样的绘制效果请查看natureTree.html
。在这个文件中,你能够对一些主要的参数进行控制来实现不一样的绘制效果。
无限森林的效果,就是使用屏幕环绕的原理。当物体的z
轴坐标超过设定的位置就回到初始位置。下面咱们看看效果图。为了让动画的效果更流畅,咱们采用第一种简单树来作,请各位看官原谅个人渣电脑实在是太老旧了。
若是你的电脑配置不错,能够换成其余两种树试试。效果必定更好哦!核心代码以下:
... function move (tree) { tree.xpos += vx; tree.ypos += vy; tree.zpos += vz; if(tree.ypos < floor){ //让树的Y轴坐标落在设置好的地面上 tree.ypos = floor; } if (tree.zpos < -fl) { //若是z坐标超出了屏幕回到一个老远的位置 tree.zpos += 10000; } if (tree.zpos > 10000 - fl) { //若是z轴的坐标超过了咱们设置的距离, 让它回到一个近的位置 tree.zpos -= 10000; } //3维环境设置 var scale = fl / (fl + tree.zpos); tree.scaleX = tree.scaleY = scale; tree.x = vpX + tree.xpos * scale; tree.y = vpY + tree.ypos * scale; tree.alpha = scale; } ...
森林的运动经过键盘的方向键来控制。具体代码请查看tree-2.html
。
星海使用的仍是咱们的球类文件,不一样之处在于球体的着色上使用的是canvas
的放射渐变来造成光晕效果。具体代码请看ball3d-s.js
... var gradient = context.createRadialGradient(0, 0, 0, 0, 0, this.radius ); gradient.addColorStop(0,"rgba(255,255,255,1)"); gradient.addColorStop(0.2,"rgba(0,255,255,1)"); gradient.addColorStop(0.3,"rgba(0,0,100,1)"); gradient.addColorStop(1,"rgba(0,0,0,0.1)"); context.fillStyle = gradient; ...
效果图以下:
默认状况下,小球是有一个竖直向上的速度,经过方向键来控制做用于球体上的加速度,以此来达到物体运动的效果。代码基本上没有变化,在这我就不列举了。详细代码请查看star.html
本节的内容到这就结束了,下一节,咱们介绍3维环境下的旋转与碰撞。