24、《每周一点canvas动画》——森林与星海

21人阅读 评论(0) 收藏 举报
分类:

在上一节《每周一点canvas动画》——3D物理效果中,我们介绍了3维环境下的速度与加速度效果。这一节,我们继续介绍另外两个物理效果:重力和屏幕环绕。

一、重力

三维系统中实现重力效果的方式与二维的情况一样,设定一个重力值,比如 g=0.2 。然后,在动画循环中将它作用于物体竖直方向的速度上。虽然原理上没有什么大的变化,但是多了一个维度实现出来的效果确实相当具有视觉冲击力的。ok,一图胜千言,与其在这听我嘚吧嘚吧嘚,还不如直接上个效果图。

在动画中,我们为小球的下落设置了一个边界——相当于地面,并与反弹的效果结合在一起,当小球触碰到地面发生反弹。与二维系统中的效果如出一辙。下面是核心代码,具体代码请看 gravity.html

    。。。
    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;
         }
 }
 。。。

二、屏幕环绕

屏幕环绕是我们今天的重头戏,与二维环境中的概念一样。所谓屏幕环绕就是从屏幕的这端消失,相应的从屏幕的另一边出来。对应到三维的环境中,我们就多了一个纬度的选择。下面我们介绍第一个效果——森林

1. hello!树先生

绘制森林前我们要做的第一个准备工作是绘制森林的基本组成单元——tree。在这里我提供了3个树的类文件。

  1. tree.js ——简单树
  2. binaryTree.js ——二叉树
  3. natureTree.js ——自然树

与球类文件的引入和使用方式一样,下面我们展示一下三种文件的绘制效果。

1.简单树

简单树的绘制效果如图所示,如果你想要让它的枝条更多,再多加两条树枝就可以了。类文件tree.js,没有什么特别的,只是用到简单的 lineTo,moveTo 等API。

2.二叉树

二叉树的类文件名为 binaryTree.js 。与简单树的原理不一样,二叉树的原理是采用递归的方法实现树枝与树干的绘制。绘制效果如图:

具体代码如下:

/* 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--;
}

二叉树的造型已经与我们现实中的树木结构有相似之处了。下一步我们就通过这种绘制二叉树的方法来实现自然树。

3.自然树

自然树的原理与二叉树的原理完全一样,不同之处在于对树枝的分叉设置了更多的随机性。也就是说,不会像我们上面看到的一样,树枝的分叉那么有对称性。并且,在树枝的末端绘制树叶。ok,下面展示一下用 canvas 绘制的艺术品。

怎么样,帅气吧!是不是跟真的树一模一样。代码有点长,我在这就不列出来了,具体代码请查看 binaryTree.js 。如果你想体验不同的绘制效果请查看natureTree.html。在这个文件中,你可以对一些主要的参数进行控制来实现不同的绘制效果。

2.无限森林

无限森林的效果,就是使用屏幕环绕的原理。当物体的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

3.星海

星海使用的还是我们的球类文件,不同之处在于球体的着色上使用的是 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维环境下的旋转与碰撞。

查看评论

11、《每周一点canvas动画》 —— 弹性动画

本系列文章代码文件 在上一章我们介绍了缓动动画,并且对弹性动画的概念做了简单的介绍。弹性动画(spring)与缓动动画都是基于距离的百分比动画,两者的不同之处在于,一个作用于速度(ease), ...
  • qq_39759115
  • qq_39759115
  • 2018-01-15 17:20:02
  • 97

8、《每周一点canvas动画》——边界检测与摩擦力(2)

到目前为止,我们最常见的两种情形: 物体按照一定的速度做任意运动直到碰上边界 物体自身,或者通过外部的作用力,运用加速度来改变物体的速度 不管怎样,除非我们...
  • qq_39759115
  • qq_39759115
  • 2018-01-03 09:56:51
  • 89

7、《每周一点canvas动画》——边界检测与摩擦力(1)

本章已经是《Canvas 动画系列》动画的第七篇了,我保证这一章不会再有难的数学公式和物理概念。鉴于有的同学并不是从第一章开始看这个系列,我将会把本文所用到的一些 类...
  • qq_39759115
  • qq_39759115
  • 2018-01-02 11:49:18
  • 113

14、《每周一点canvas动画》——碰撞检测(1)

每周一点canvas动画代码文件 在前面的几章中我介绍了一些动画效果,这些动画效果都相对基础。但是通过这些基础的动画形式和概念,你可以设计出更复杂的动画。本章将介绍在动画中相对来说比较难的物理概...
  • qq_39759115
  • qq_39759115
  • 2018-01-15 17:22:53
  • 112

《每周一点canvas动画》——圆周运动

效果源码 终于到年底了,再过两天我也要回家过年了,想想就激动呢!今天给大家带来一个基于移动端的canvas价格选择效果。 主要功能就是拖动标尺变动价格。而且支付宝和京东金融的里也有这样的效果(...
  • qq_39759115
  • qq_39759115
  • 2018-04-17 15:40:18
  • 4

11、《每周一点canvas动画》——缓动动画

本系列文章代码文件 前面的章节我们介绍了许多基本的动画,在本节我们将使用这些基本的动画来创建一些高级动画。今天我们介绍的第一个高级动画叫做缓动动画(ease),也许在写css动画的时候已经接触过...
  • qq_39759115
  • qq_39759115
  • 2018-01-15 17:19:07
  • 48

24、《每周一点canvas动画》——3D物理效果

在上一节《每周一点canvas动画》——3维环境搭建中,我们详细的介绍了要想在2D的画布上实现立体效果,需要做哪些事情。也就是我们所说的,怎样给画布中的物体搭建一个可以做三维运动的环境。这之后的所有知...
  • qq_39759115
  • qq_39759115
  • 2018-04-17 12:00:25
  • 10

16、《每周一点canvas动画》——坐标旋转

每周一点canvas动画代码文件 在上一节中我们介绍了一些碰撞检测的方法。这一节本来打算讲解一个基于距离碰撞检测的小游戏。但是,因为最近比较忙,一直没来的及把游戏的整个过程完整的写出来。所以,这...
  • qq_39759115
  • qq_39759115
  • 2018-01-15 17:25:06
  • 48

4.每周一点canvas动画--波形运动

在上一节我们介绍了canvas动画中有关三角函数的内容,以及一个跟随鼠标旋转的箭头动画。这一节主要介绍三角函数的波形运动。包括: 平滑运动 线性运动 脉冲运动 1.Sin函数的波形sin函数的波形想必...
  • qq_39759115
  • qq_39759115
  • 2018-01-02 11:40:30
  • 63
    个人资料
    持之以恒
    等级:
    访问量: 1万+
    积分: 759
    排名: 6万+
    最新评论