显然低成本高收益

canvas图形绘制之星空、噪点与气团雾效果

2016/06/07 · HTML5 · 1
评论 ·
Canvas

原著出处:
张鑫旭(@张鑫旭)   

一、三合一

四个成效合成一篇小说。

有四个小友人问笔者,为什么不开个公众号,未来都是运动时期,你博客文章写好后,公众号再复制一份,花不了多久,同不常间传播方便快速,打赏方便快速,鲜明低开销高受益。

以前方来看,就像真正如此。

不过,就自己个人来讲,行为和处置法规总是服从内心的直觉和大方向的指点。说不上实际的道理,便是感觉,文章的输出源如若持续两个,久远来看,带来的未知损耗一定要高于短时间的已知收益。

取巧的作业多慎思而克己,就好比本文内容,实际上,三个不等的canvas效果,直接分3篇来写,凑个小说数,扩大点浏览量其实也是没有可过分责问的。然,想了想,有一点点不像本身的style,内心真实的和煦并不期望本身如此做,于是,就3个效果与利益合体为一篇小说。

闭门羹小片段的吸引,让本人过得更自在。

澳门太陽城集团登录网址,正文的3个作用都以源自己近年来做的多少个实在的门类,是canvas领域基本入门的一些功力。代码我都极其重新梳理了下,须求注释也都足够去了,方便大家的读书。然后,倘使你有不懂的地点,请不要来问我,没错,是不要澳门太阳集团城网址,,我并不接待你找我来调换,自身一点一点去弄掌握。因为,假若连这么基本的canvas效果都不知情,小编实在也帮不了你什么。倒不是说腾不出时间,而是腾不出精力,每一天今日头条私信还恐怕有邮箱找笔者的人还挺多,实在迎接不暇。

二、canvas图形效果之旋转星空

澳门太阳集团城网址 1

图是死的,效果是活的,IE9+浏览器下,您能够狠狠地点击这里:canvas达成的团团转星空效果demo

会看出地球上方会有成百上千轻易在日趋地绕着地球转啊转,星星在闪啊闪。

像那类密集型canvas效果,一般离不开上面那多少个首要字:实例,随机,变化与重绘,requestAnimationFrame。

规律就是:

  1. 先画贰个地点发光度随机的静态的轻松实例对象;
  2. 有三个能够更动轻巧地点和反射率的draw方法;
  3. 显然低成本高收益。电磁打点计时器跑起来,画布不停地铲除与绘图,动画效果达成!

规律非常粗大略。

本例子完毕的2个难题在于:

  1. 月明星稀
    点滴垂直方向实际上是个伪随机,越相近地球,星星越密集,而越往上,越荒芜。其算法如下:
JavaScript

var getMinRandom = function() { var rand = Math.random(); //
step的大小决定了星星靠近地球的聚拢程度, // step = Math.ceil(2 /
(1 - rand))就聚拢很明显 var step = Math.ceil(1 / (1 - rand)); var
arr = \[\]; for (var i=0; i<step; i++) { arr.push(Math.random());
} return Math.min.apply(null, arr); };

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-5">
5
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-6">
6
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-7">
7
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-8">
8
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-9">
9
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-10">
10
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b2b195965046-11">
11
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b2b195965046-12">
12
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4a6436b2b195965046-1" class="crayon-line">
var getMinRandom = function() {
</div>
<div id="crayon-5b8f4a6436b2b195965046-2" class="crayon-line crayon-striped-line">
    var rand = Math.random();
</div>
<div id="crayon-5b8f4a6436b2b195965046-3" class="crayon-line">
    // step的大小决定了星星靠近地球的聚拢程度,
</div>
<div id="crayon-5b8f4a6436b2b195965046-4" class="crayon-line crayon-striped-line">
    // step = Math.ceil(2 / (1 - rand))就聚拢很明显
</div>
<div id="crayon-5b8f4a6436b2b195965046-5" class="crayon-line">
    var step = Math.ceil(1 / (1 - rand));
</div>
<div id="crayon-5b8f4a6436b2b195965046-6" class="crayon-line crayon-striped-line">
    var arr = [];
</div>
<div id="crayon-5b8f4a6436b2b195965046-7" class="crayon-line">
    for (var i=0; i&lt;step; i++) {
</div>
<div id="crayon-5b8f4a6436b2b195965046-8" class="crayon-line crayon-striped-line">
        arr.push(Math.random());
</div>
<div id="crayon-5b8f4a6436b2b195965046-9" class="crayon-line">
    }
</div>
<div id="crayon-5b8f4a6436b2b195965046-10" class="crayon-line crayon-striped-line">
 
</div>
<div id="crayon-5b8f4a6436b2b195965046-11" class="crayon-line">
    return Math.min.apply(null, arr);       
</div>
<div id="crayon-5b8f4a6436b2b195965046-12" class="crayon-line crayon-striped-line">
};
</div>
</div></td>
</tr>
</tbody>
</table>

很大概率会返回一个数值偏小的值,于是,就可以有“月明星稀”的分布效果了。
  1. 圆弧轨迹
    显然低成本高收益。显然低成本高收益。实际不会细小略,大家套用高级中学时候学的圆方程式就能够了,如下注释截图所述:
    澳门太阳集团城网址 2显然低成本高收益。那下标题就归纳了,已知a,b,
    求y相对于x的函数表明式……

三、canvas图形效果之雪花噪点效果

澳门太阳集团城网址 3

图是死的,效果这里也是死的,但并不要紧碍大家零距离围观,您能够狠狠地点击这里:canvas达成的噪点效果demo

出于这里是静态的,所以但从那一点来看,就像是比地方星空轻巧。不过,要是单独看绘制一帧,那这里的噪点要比地点的星空要艰苦些,最大的难处在于对品质的把控。

如此说啊,上边的星空,总共最多就400个点(青蓝的星星点点),不过,这里的噪点,比方,demo中画布大小(那作者的对讲机例如)是1919*500,个中,噪点大小是1像素*1像素,总共就有9陆仟0个绘制点,显著跟400个点完全不是贰个数码级的,要是大家真的二个叁个绘制下来,肯定,就连Chrome这么牛步的浏览器也会感到到到鲜明的卡顿,怎样优化怎么样绘制呢?

那正是本例子完毕的困难:

  1. 多少与特性
    自个儿这里是那样管理的,即使最终的噪点大小是1917*500,可是,大家实在是由N块300*150的小的像瓷砖同样的小方块拼起来的。话句话说,我实际只绘制了4四千个点,比940000引人瞩目要小了20倍还不唯有。那样,既满意了作用,又保险了质量。

显然低成本高收益。具体达成原理为:

  1. 创设多少个canvas,绘制叁个300*150即兴噪点图形;
  2. 把这里全部噪点的canvas以画布情势在绘制到页面上的大canvas上;

说得canvas绘图,不得不提一下可怜常用的二个drawImage()格局,语法如下:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

1
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

次第参数暗暗提示为(网络的汇报都是直译,很别扭,作者那边再次汇报了下):

参数 描述
img 用来被绘制的图像、画布或视频。
sx 可选。img被绘制区域的起始左上x坐标。
sy 可选。img被绘制区域的起始左上y坐标。
swidth 可选。img被绘制区域的宽度。
sheight 可选。img被绘制区域的高度。
x 画布上放置img的起始x坐标。
y 画布上放置img的起始y坐标。
width 可选。画布上放置img提供的宽度。(伸展或缩小图像)
height 可选。画布上放置img提供的高度。(伸展或缩小图像)

本例的小的噪点区块正是通过drawImage()主意被平铺到大的canvas成分上的。

四、canvas图形效果之云遮云涌效果

澳门太阳集团城网址 4

图是死的,效果是活的,IE9+浏览器下,您能够狠狠地方击这里:canvas完成的云烟缭绕效果demo

本例子,效果看上去要更酷一些,实际上,从本领层面讲,跟上边包车型的士星空旋转效果大约千篇一律,恐怕还要比星空更简单一些,因为其移动轨迹直来直往,无需转圈圈。

那为什么看起来更酷呢,首要在于以为谷雾很难去模拟。

无庸置疑,蒸发雾确实很难用代码直接绘制出来,实际上,这里的冰雾,是多少个png图片,是运用画笔在PS里绘制导出来的。

旋转星空的例证,我们是应用canvas的fillRect情势绘制了少于,而本例子,则是运用方面提到的drawImage()主意把谷雾图片绘制进来了。

其余的移动啊,发光度变化什么的,原理都以周边。

本例子的难关首要在于模拟是或不是丰富真实:

  1. 高处不胜寒
    越往上,气团雾越淡,实际上便是越走近上方,光滑度越低;
// 越靠近边缘,透明度越低 // 纵向透明度变化要比横向的明显 this.alpha
= (1 - Math.abs(canvasWidth\*0.5 - this.x) / canvasWidth) \* (0.7 -
Math.abs(canvasHeight\*0.5 - this.y) / canvasHeight);

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f4a6436b3d419634939-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f4a6436b3d419634939-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f4a6436b3d419634939-3">
3
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f4a6436b3d419634939-1" class="crayon-line">
// 越靠近边缘,透明度越低
</div>
<div id="crayon-5b8f4a6436b3d419634939-2" class="crayon-line crayon-striped-line">
// 纵向透明度变化要比横向的明显
</div>
<div id="crayon-5b8f4a6436b3d419634939-3" class="crayon-line">
this.alpha = (1 - Math.abs(canvasWidth*0.5 - this.x) / canvasWidth) * (0.7 - Math.abs(canvasHeight*0.5 - this.y) / canvasHeight);
</div>
</div></td>
</tr>
</tbody>
</table>
  1. 缭绕
    所谓“缭绕”,正是运动看似不拥有规律性。要驾驭,凡事有轨道有套路的运动都以有规律性地,你说那蒸发雾上上下下,左左右右运动太过火规律,效果就能够减小,可是,真的未有规律又倒霉通过代码调节移动轨迹。因此,为了搞到三个临近缭绕效果的运动函数,还真是烧了过多头脑细胞。

五、canvas动作效果与结语

正文两个例证都以canvas 2D效果,是入门学习十三分好的例子。

canvas特别适合完毕密集型图形和卡通片,能够把质量优势给发挥出来,因为便是一块画布渲染;其余一些正是省流量,举个例子说第1个例证的噪点效果,假如是一致服从一九二零*500的png图片,科科,作者特别保存了下,286K,1K的代码PK
286K的图纸,鲜明是完爆啊!

canvas还支持3D效果,也就是webGL, 亦称3D Canvas graphics,
IE11+支持,目前Android
4.*私行版本都还不帮忙,行业内部资深的相关库就是threejs了。

只是,作者没商讨过,也没兴趣,不是本身的主旋律。

好了,就那一个,多谢阅读。

1 赞 7 收藏 1
评论

澳门太阳集团城网址 5

You may also like...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图