canvas 让你呼风唤雨,下雨下雪效果

转载自:http://blog.csdn.net/xllily_11/article/details/51444311

前端如何呼风唤雨

Canvas 等于什么?  

 = html5 =js = 取代flash =  你可以即见即所得向别人装逼!没错 进入 canvas 的权力游戏吧!

起初我创造了canvas 。

我说,要有雨,就有了雨;

我说,要有雪,就有了雪。

而对于前端来说,canvas即是天地

在canvas这个天地上,前端可以呼风唤雨,无所不能。

------------------------------------华丽的分割线-------------------------------------------------

文章起因

其实就是最近在做一个需求,需要有下雨下雪的动画特效, 故在这里做了一个drop的组件,来展现这种canvas常见的下落物体的效果。那么,=。= ,就让我们先看看效果吧。

[github地址] 之后贴出来哈。。。。

效果展示

调用代码

<code class="hljs html" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;"><span class="hljs-doctype" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><!DOCTYPE html></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">html</span> <span class="hljs-attribute" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">lang</span>=<span class="hljs-value" style="color: rgb(166, 226, 46); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"en"</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">head</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">meta</span> <span class="hljs-attribute" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">charset</span>=<span class="hljs-value" style="color: rgb(166, 226, 46); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"UTF-8"</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">title</span>></span>Document<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">title</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">style</span>></span><span class="css" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">
        <span class="hljs-id" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">#canvas</span><span class="hljs-rules" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">{
            <span class="hljs-rule" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(102, 217, 239);">width</span>:<span class="hljs-value" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">100%</span></span></span>;
            <span class="hljs-rule" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><span class="hljs-attribute" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(102, 217, 239);">height</span>:<span class="hljs-value" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"> <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">100%</span></span></span>;
        }</span>
    </span><span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">style</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">head</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">body</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">canvas</span> <span class="hljs-attribute" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">id</span>=<span class="hljs-value" style="color: rgb(166, 226, 46); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"canvas"</span>></span><span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">canvas</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">script</span> <span class="hljs-attribute" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">src</span>=<span class="hljs-value" style="color: rgb(166, 226, 46); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"canvasDrop.js"</span>></span><span class="undefined" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span><span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">script</span>></span>
    <span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"><<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">script</span>></span><span class="actionscript" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">
        canvasDrop.init({
            type: <span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"rain"</span>,  <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">// drop类型,有rain or snow</span>
            speed : [<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.4</span>,<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">2.5</span>], <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//速度范围</span>
            size_range: [<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.5</span>,<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1.5</span>],<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//大小半径范围</span>
            hasBounce: <span class="hljs-literal" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">true</span>, <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//是否有反弹效果or false,</span>
            wind_direction: -<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">105</span> <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//角度</span>
            hasGravity: <span class="hljs-literal" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">true</span> <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//是否有重力考虑</span>
        });
    </span><span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">script</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">body</span>></span>
<span class="hljs-tag" style="color: rgb(0, 102, 102); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></<span class="hljs-title" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">html</span>></span>
</code>

下雨 下雪

 

看起来效果还是不错的,相对于使用创建dom元素来制作多物体位移动画, 使用canvas会更加容易快捷,以及性能会更好

源码讲解

好了,接下来讲解一下简单的实现原理 首先,先定义一些我们会用到的全局变量,如风向角度,几率,对象数据等

定义全局变量

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;">
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//定义两个对象数据</span>
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//分别是drops下落物体对象</span>
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//和反弹物体bounces对象</span>
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> drops = [], bounces = [];
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//这里设定重力加速度为0.2/一帧</span>
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> gravity = <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.2</span>;


<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> speed_x_x, <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//横向加速度</span>
      speed_x_y, <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//纵向加速度</span>
      wind_anger;  <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//风向</span>
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//画布的像素宽高</span>
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> canvasWidth,
    canvasHeight;
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//创建drop的几率</span>
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> drop_chance;
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//配置对象</span>
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> OPTS;
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//判断是否有requestAnimationFrame方法,如果有则使用,没有则大约一秒30帧</span>
<span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.requestAnimFrame =
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.requestAnimationFrame ||
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.webkitRequestAnimationFrame ||
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.mozRequestAnimationFrame ||
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.oRequestAnimationFrame ||
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.msRequestAnimationFrame ||
    <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">callback</span>) </span>{
        <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.setTimeout(callback, <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1000</span> / <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">30</span>);
    };
</code>

定义核心对象

接下来我们需要定义几个重要的对象 该组织所需定义的对象也比较少,总共才三个 在整个drop组件中共定义了`三个核心对象,分别是如下:

  •  Vector 速度对象,带有横向x,和纵向y的速度大小 单位为:V = 位移像素/帧

对于Vector对象的理解也十分简单粗暴,就是记录下落对象drop的速度/V

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;">
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> Vector = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">x, y</span>) </span>{
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//私有属性  横向速度x ,纵向速度y</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.x = x || <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>;
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.y = y || <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>;
};
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//公有方法- add : 速度改变函数,根据参数对速度进行增加</span>
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//由于业务需求,考虑的都是下落加速的情况,故没有减速的,后期可拓展</span>
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">/*
* @param v  object || string  
*/</span>
Vector.prototype.add = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">v</span>) </span>{
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span> (v.x != <span class="hljs-literal" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">null</span> && v.y != <span class="hljs-literal" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">null</span>) {
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.x += v.x;
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.y += v.y;
    } <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">else</span> {
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.x += v;
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.y += v;
    }
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">return</span> <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>;
};
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//公有方法- copy : 复制一个vector,来用作保存之前速度节点的记录</span>
Vector.prototype.copy = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//返回一个同等速度属性的Vector实例</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">return</span> <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Vector(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.y);
};
</code>
  • Drop 下落物体对象, 即上面效果中的雨滴和雪, 在后面你也可自己拓展为陨石或者炮弹

对于Drop对象其基本定义如下

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;"><span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//构造函数</span>
<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> Drop = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">/* .... */</span>
};
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//公有方法-update </span>
Drop.prototype.update = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">/* .... */</span>
};
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//公有方法-draw</span>
Drop.prototype.draw = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">/* .... */</span>
};
</code>

看了上面的三个方法,是否都猜到他们的作用呢,接下来让我们了解这三个方法做了些什么

构造函数

构造函数主要负责定义drop对象的初始信息,如速度,初始坐标,大小,加速度等

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;"><span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//构造函数 Drop</span>

<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> Drop = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//随机设置drop的初始坐标 </span>
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//首先随机选择下落对象是从从哪一边</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> randomEdge = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random()*<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">2</span>;
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span>(randomEdge > <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1</span>){
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Vector(<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">50</span> + <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * canvas.width, -<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">80</span>);
    }<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">else</span>{
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Vector(canvas.width, <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * canvas.height);
    }

    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//设置下落元素的大小</span>
     <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//通过调用的OPTS函数的半径范围进行随机取值</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.radius = (OPTS.size_range[<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>] + <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * OPTS.size_range[<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1</span>]) *DPR;

    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//获得drop初始速度</span>
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//通过调用的OPTS函数的速度范围进行随机取值</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.speed = (OPTS.speed[<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>] + <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * OPTS.speed[<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1</span>]) *DPR;

    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.prev = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos;
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//将角度乘以 0.017453293 (2PI/360)即可转换为弧度。</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> eachAnger =  <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.017453293</span>; 
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//获得风向的角度</span>
    wind_anger = OPTS.wind_direction * eachAnger;
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//获得横向加速度 </span>
    speed_x =  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.speed * <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.cos(wind_anger);
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//获得纵向加速度</span>
    speed_y = - <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.speed * <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.sin(wind_anger);

    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//绑定一个速度实例</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Vector(wind_x, wind_y);

};
</code>
Drop对象的update方法

update方法负责,每一帧drop实例的属性的改变 如位移的改变

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;">Drop.prototype.update = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{

      <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.prev = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.copy();
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//如果是有重力的情况,则纵向速度进行增加</span>
      <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span> (OPTS.hasGravity) {
          <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel.y += gravity;
      }
  <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//</span>
   <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.add(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel);
};
</code>
Drop对象的draw方法

draw方法负责,每一帧drop实例的绘画

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;">Drop.prototype.draw = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{

  ctx.beginPath();
  ctx.moveTo(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.y);
<span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//目前只分为两种情况,一种是rain  即贝塞尔曲线</span>
  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span>(OPTS.type ==<span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"rain"</span>){
       ctx.moveTo(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.prev.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.prev.y);
       <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> ax = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.abs(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.radius * <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.cos(wind_anger));
       <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> ay = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.abs(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.radius * <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.sin(wind_anger));
       ctx.bezierCurveTo(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.x + ax, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.y + ay, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.prev.x + ax , <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.prev.y + ay, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.y);
       ctx.stroke();

  <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//另一种是snow--即圆形     </span>
  }<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">else</span>{
         ctx.moveTo(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.y);
         ctx.arc(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.y, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.radius, <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>, <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.PI*<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">2</span>);
         ctx.fill();
  }
};
</code>
  • bounce 下落落地反弹对象, 即上面雨水反弹的水滴, 你也可后期拓展为反弹的碎石片或者烟尘

定义的十分简单,这里就不做详细说明

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;"><span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> Bounce = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">x, y</span>) </span>{

  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> dist = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">7</span>;
  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> angle = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.PI + <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.PI;

  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Vector(x, y);
  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.radius =  <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.2</span>+ <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random()*<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.8</span>;
  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Vector(
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.cos(angle) * dist,
    <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.sin(angle) * dist
    );
};

Bounce.prototype.update = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{

  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel.y += gravity;

  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel.x *= <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.95</span>;
  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel.y *= <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.95</span>;

  <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.add(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.vel);
};

Bounce.prototype.draw = <span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{

  ctx.beginPath();
  ctx.arc(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.x, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.pos.y, <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">this</span>.radius*DPR, <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>, <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.PI * <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">2</span>);
  ctx.fill();

};
</code>

对外接口

update

即相当于整个canvas动画的开始函数

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;"><span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(166, 226, 46);">update</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>) </span>{

    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> d = <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Date</span>;
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//清理画图</span>
    ctx.clearRect(<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>, <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>, canvas.width, canvas.height);

    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> i = drops.length;
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">while</span> (i--) {

        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> drop = drops[i];

        drop.update();
        <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//如果drop实例下降到底部,则需要在drops数组中清楚该实例对象</span>
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span> (drop.pos.y >= canvas.height) {
            <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//如果需要回弹,则在bouncess数组中加入bounce实例</span>
            <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span>(OPTS.hasBounce){
                <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> n = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.round(<span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">4</span> + <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() * <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">4</span>);
                <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">while</span> (n--)
                bounces.push(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Bounce(drop.pos.x, canvas.height));
            }
           <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//如果drop实例下降到底部,则需要在drops数组中清楚该实例对象</span>
            drops.splice(i, <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1</span>);
        }

        drop.draw();
    }
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//如果需要回弹</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span>(OPTS.hasBounce){
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> i = bounces.length;
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">while</span> (i--) {
            <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> bounce = bounces[i];
            bounce.update();
            bounce.draw();
            <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span> (bounce.pos.y > canvas.height) bounces.splice(i, <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1</span>);
        }
    }
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//每次产生的数量</span>
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span>(drops.length < OPTS.maxNum){
        <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span> (<span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">Math</span>.random() < drop_chance) {
            <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">var</span> i = <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0</span>,
                  len = OPTS.numLevel;
            <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">for</span>(; i<len; i++){
                drops.push(<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">new</span> Drop());
            }
        }

    }
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//不断循环update</span>
    requestAnimFrame(update);
}
</code>

init

init接口,初始化整个canvas画布的一切基础属性 如获得屏幕的像素比,和设置画布的像素大小,和样式的设置

<code class="hljs javascript" style="display: block; padding: 0px; color: rgb(248, 248, 242); margin: 0px; border: 0px; vertical-align: baseline; overflow-x: auto; font-size: 12px; font-family: 'Source Code Pro', Consolas, Monaco, Menlo, Consolas, monospace; background: 0px 50%;"><span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(166, 226, 46);">init</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">opts</span>) </span>{
    OPTS = opts;

    canvas = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">document</span>.getElementById(opts.id);
    ctx = canvas.getContext(<span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"2d"</span>);

    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">兼容高清屏幕,canvas画布像素也要相应改变</span>
    DPR = <span class="hljs-built_in" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">window</span>.devicePixelRatio;

    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//canvas画板像素大小, 需兼容高清屏幕,故画板canvas长宽应该乘于DPR</span>
    canvasWidth = canvas.clientWidth * DPR;
    canvasHeight =canvas.clientHeight * DPR;

    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//设置画板宽高</span>
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    drop_chance = <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">0.4</span>;
    <span class="hljs-comment" style="color: rgb(117, 113, 94); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">//设置样式</span>
    setStyle();
}

<span class="hljs-function" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(249, 38, 114);"><span class="hljs-keyword" style="color: rgb(102, 217, 239); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">function</span> <span class="hljs-title" style="margin: 0px; padding: 0px; border: 0px; vertical-align: baseline; color: rgb(166, 226, 46);">setStyle</span>(<span class="hljs-params" style="color: rgb(248, 248, 242); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;"></span>)</span>{
    <span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">if</span>(OPTS.type ==<span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">"rain"</span>){
        ctx.lineWidth = <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">1</span> * DPR;
        ctx.strokeStyle = <span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">'rgba(223,223,223,0.6)'</span>;
        ctx.fillStyle = <span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">'rgba(223,223,223,0.6)'</span>;

    }<span class="hljs-keyword" style="color: rgb(249, 38, 114); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">else</span>{
        ctx.lineWidth = <span class="hljs-number" style="color: rgb(174, 129, 255); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">2</span> * DPR;
        ctx.strokeStyle = <span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">'rgba(254,254,254,0.8)'</span>;
        ctx.fillStyle = <span class="hljs-string" style="color: rgb(230, 219, 116); margin: 0px; padding: 0px; border: 0px; vertical-align: baseline;">'rgba(254,254,254,0.8)'</span>;
    }
}
</code>

结束语

好了,一个简单的drop组件已经完成了,当然其存在着许多地方不够完善,经过本次drop组件的编写,对于canvas的动画实现,我相信在H5的场景中拥有着许多可发掘的地方。

最后说下不足的地方和后期的工作哈:

  • 0、该组件目前对外接口不够多,可调节的范围并不是很多,抽象不是很彻底
  • 1、 setStyle 设置 基本样式
  • 2、 Drop 和Bounce 对象的 update 和 draw 方法的自定义,让用户可以设立更多下落的 速度和大小改变的形式和样式效果
  • 3、 应增加对动画的pause,加速和减速等操作的接口
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值