canvas教程

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

字号+ 作者:H5之家 来源:H5之家 2016-06-08 14:00 我要评论( )

这篇文章发布于 2016年06月2日,星期四,00:34,归类于canvas相关。 阅读 154 次, 今日 149 次 byzhangxin

这篇文章发布于 2016年06月2日,星期四,00:34,归类于canvas相关。 阅读 154 次, 今日 149 次

byzhangxinxu from http://www.zhangxinxu.com

本文地址: wordpress/?p=5404

一、三合一

三个效果合成一篇文章。

有多个小伙伴问我,为何不开个公众号,现在都是移动时代,你博客文章写好后,公众号再复制一份,花不了多长时间,同时传播方便迅速,打赏方便快捷,显然低成本高收益。

从眼前来看,似乎确实如此。

但是,就我个人而言,行为和处事准则总是遵循内心的直觉和大方向的指引。说不上具体的道理,就是觉得,作品的输出源如果不止一个,久远来看,带来的未知损耗一定要大于短期的已知收益。

取巧的事情多慎思而克己,就好比本文内容,实际上,三个不同的canvas效果,直接分3篇来写,凑个文章数,增加点浏览量其实也是无可厚非的。然,想了想,有点不像自己的style,内心真实的自己并不希望自己这么做,于是,就3个效果合体为一篇文章。

拒绝小部分的诱惑,让自己过得更轻松。

本文的3个效果都是源自我最近做的几个真实的项目,是canvas领域基本入门的一些效果。代码我都专门重新梳理了下,必要注释也都加上去了,方便大家的学习。然后,如果你有不懂的地方,请 不要 来问我,没错,是 不要 ,我并不欢迎你找我来交流,自己一点一点去弄明白。因为,如果连这么基本的canvas效果都不理解,我真的也帮不了你什么。倒不是说腾不出时间,而是腾不出精力,每天微博私信还有邮箱找我的人还挺多,实在应接不暇。

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

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

图是死的,效果是活的,IE9+浏览器下,您可以狠狠地点击这里: canvas实现的旋转星空效果demo

会看到地球上方会有很多星星在慢慢地绕着地球转啊转,星星在闪啊闪。

像这类密集型canvas效果,一般离不开下面这几个关键字:实例,随机,变化与重绘, requestAnimationFrame 。

原理就是:

原理很简单。

本例子实现的2个难点在于:

  • 月明星稀

    星星垂直方向实际上是个伪随机,越靠近地球,星星越密集,而越往上,越稀疏。其算法如下:

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

    很大概率会返回一个数值偏小的值,于是,就可以有“月明星稀”的分布效果了。

  • 圆弧轨迹
    其实很简单,我们套用高中时候学的圆方程式就可以了,如下注释截图所述:

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

    这下题目就简单了,已知a,b, 求y相对于x的函数表达式……

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

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

    图是死的,效果这里也是死的,但并不妨碍我们零距离围观,您可以狠狠地点击这里: canvas实现的噪点效果demo

    由于这里是静态的,所以但从这一点来看,似乎比上面星空简单。但是,如果仅仅看绘制一帧,那这里的噪点要比上面的星空要困难些,最大的难点在于对性能的把控。

    这么说吧,上面的星空,总共最多就400个点(白色的星星),但是,这里的噪点,例如,demo中画布大小(那我的机子举例)是1920*500,其中,噪点大小是1像素*1像素,总共就有960000个绘制点,显然跟400个点完全不是一个数量级的,如果我们真的一个一个绘制下来,肯定,就连Chrome这么牛步的浏览器也会感觉到明显的卡顿,如何优化如何绘制呢?

    这就是本例子实现的难点:

  • 数量与性能

    我这里是这么处理的,虽然最终的噪点大小是1920*500,但是,我们实际上是由N块300*150的小的像瓷砖一样的小方块拼起来的。话句话说,我实际只绘制了45000个点,比960000显然要小了20倍还不止。

    这样,既满足了效果,又保证了性能。

  • 具体实现原理为:

  • 创建一个canvas,绘制一个300*150随机噪点图形;
  • 把这里具有噪点的canvas以画布形式在绘制到页面上的大canvas上;
  • 说得canvas绘图,不得不提一下非常常用的一个 drawImage() 方法,语法如下:

    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图形效果之烟雾缭绕效果

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

    图是死的,效果是活的,IE9+浏览器下,您可以狠狠地点击这里: canvas实现的烟雾缭绕效果demo

    本例子,效果看上去要更酷一些,实际上,从技术层面讲,跟上面的星空旋转效果几乎如出一辙,可能还要比星空更简单一些,因为其运动轨迹直来直往,不需要转圈圈。

    那为何看上去更酷呢,主要在于感觉烟雾很难去模拟。

    没错,烟雾确实很难用代码直接绘制出来,实际上,这里的烟雾,是一个png图片,是使用画笔在PS里绘制导出来的。

    旋转星空的例子,我们是使用canvas的 fillRect 方法绘制了星星,而本例子,则是使用上面提到的 drawImage() 方法把烟雾图片绘制进来了。

    其他的位移啊,透明度变化什么的,原理都是类似。

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • Canvas与ValueAnimator

      Canvas与ValueAnimator

      2017-04-28 18:00

    • Android Bitmap和Canvas学习笔记(转)

      Android Bitmap和Canvas学习笔记(转)

      2017-04-28 17:00

    • 21天学习android开发教程之SurfaceView与多线程的混搭

      21天学习android开发教程之SurfaceView与多线程的混搭

      2017-04-27 12:00

    • Android画图学习免费下载

      Android画图学习免费下载

      2017-04-27 11:01

    网友点评