当前位置: 首页 > Web前端 > HTML5

【画布流浪(10)】文字烟花

时间:2023-04-05 22:48:47 HTML5

示例代码托管于:http://www.github.com/dashnowords/blogs博客园地址:《大史住在大前端》原博文目录华为云社区地址:[你打怪的前端升级指南】[TOC]1.TextFireworkTextFirework小控件是下面这个效果,你可能在很多个人博客上都看到过:本节我们将介绍其实现方法这个小动画。2.动画原理首先,动画的主帧还是我们反复使用的逐帧动画帧。烟花生成后的部分不难理解。我们之前模拟过物理碰撞,这里其实是模拟初速度。自由落体。所以这个小动画唯一的难点就是如何根据文字生成烟花。只要做好这一步,其他部分就比较容易实现了。2.1像素操作这里需要用到画布像素操作的API——context.getImageData(),它可以以像素的形式返回画布上指定的矩形区域,像素数据挂载在返回的data属性上目的。是一个一维的Uint8ClampedArray构造数组,每个值只能取0-255之间的整数,如果赋值超过这个范围,会自动修改为[0,255]不报错。这个一维数组就是将矩形区域的像素数据逐行拼接在一起。每4个点代表一个像素的RGBA颜色数据,最后一个通道是透明度数据。例如,红色像素的数据是[。...,255,0,0,0....]。比如截取一个长200像素,高10像素的矩形区域的数据点,会得到一个200*10*4=8000个数据点的数组。这是canvas的一个非常重要的API。它的应用场景很多,比如结合WebRTC输入的流数据做视频弹幕,或者用算法处理像素数据实现各种图片滤镜等。使用离屏canvas提高性能,具体应用留给你去探索。2.2烟花生成算法得到像素数据后,我们就可以进行分析了。分析算法如下:将获得像素的部分划分为大小适中的网格。如果网格太小,渲染压力会很大。好的。遍历每一个格子,取出小方块区域的所有像素点,或者一次性读取整个区域的像素点按小区域使用,然后统计其中的脏像素点个数(判断是否对应colorvalue都是255,如果不是,则判断为dirty),如果该区域的dirtypoints比例超过一定阈值(例子中为60%),则判定该区域需要替换为fireworks点。在需要生成烟花的区域生成一个大小颜色随机的小球,根据其位置指定水平初速度方向,小球受垂直向下的重力影响。更新帧动画中球的状态。2.3定时器最后,我们还需要一个新的定时器对象。我们之前接触到的精灵动画大多是连续的,每一帧都需要更新。但是这一段时间文本的更新是离散的,一秒只更新一次,烟花由于动画过程不适合每秒生成一次。所以我们需要在timer中实现一个内部定时器,每1秒更新一次渲染的文本,每2秒触发一次。如果时间精度要求高,可以记录时间戳进行对比。如果精度不高,可以直接在update方法中自增更新周期取模。Timer类的定义如下://Timer类Timer{constructor(){this.lastTime=Date.now();//初始化时记录一次时间this.label=newDate(this.lastTime).Format('hh:mm:ss');//Format为自定义格式化方法this.step=0;//标记是否为刷新时间文本this.shouldAnim=0;//标记是否生成新的烟花}update(){this.step=(this.step+1)%60;//每60帧刷新一次时间文本this.shouldAnim=(this.shouldAnim+1)%120;//每120帧产生一次烟花if(!this.step){this.lastTime=Date.now();this.label=newDate(this.lastTime).Format('hh:mm:ss');}}paint(ctx){context.fillStyle="#353535";ctx.fillText(this.label,200,100);}}主框架部分的代码已经多次提到,本文不再赘述。