大家好,我是小丞同学,一名前端爱好者

欢迎访问博主的个人网站:一口奶盖

在人间贩卖声音 等凑够满天星辰 放烟花给你看

上次的烟花有些许平淡,这次来放大招了,让你的名字在天空绽放!

喜欢的话可以私信源码去晒狗粮噢~

全程高能,无尿点,有部分内容在上期的文章中噢~

实现效果

你以为仅此而已吗,后面还有大招噢

实现过程

1. 在画布上绘制文字

通过ctx.font设定字体的大小以及字体,再填充颜色,最后通过ctx.fillText绘制到画布当中,这里有几个需要注意的地方:

注意

  1. ctx.font至少需要两个参数,一个字体大小,一个字体
  2. 这里的颜色之所以设为#000001原因是背景是黑色的,这样这个字不会被看到,但是它是真实存在的,不然每次点击时都会有一个字体生成在左上角,影响视觉,当然也可以新建在一个画布,这里就简单处理了
  3. ctx.measureText(text):返回一个对象,该对象包含以像素计的指定字体宽度
// 填充字体样式
let font = 120
ctx.font = font + "px '微软雅黑'"
ctx.fillStyle = "#000001"
// 内容
let text = '小丞同学'
// 获取字体的宽度
let textWidth = ctx.measureText(text).width
// 在左上角填充字体
ctx.fillText(text,0 , font)

2. 获取像素点

通过ctx.getImageData可以获取一个区域内的像素数据,返回的是一个imageData对象

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

  • R - 红色 (0-255)
  • G - 绿色 (0-255)
  • B - 蓝色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

在前面的代码中我们在 (0,0) 的位置绘制了字体,我们通过getImageData将这块区域的像素信息取出来。

let imgData = ctx.getImageData(0, 0, textWidth, font * 1.2)

我们先看看imgData,可以看到里面的数据十分庞大,里面存储的是像素信息

这样我们可以通过判断这些像素点来实现粒子的效果

3. 实现文字粒子化

在上面一步中我们已经将文字的像素信息得到了,也就相当于我们复制了一个文字,我们可以遍历整个imgData.data数组就能绘制出原先的文字,那我们要实现粒子化的效果,就需要隔几个像素格再绘制,这样绘制处理的图形就会是一个粒子化的效果,原因就是部分位置的像素,没有进行渲染

for (let h = 0; h < font * 1.2; h += 6) {
for (let w = 0; w < textWidth; w += 6) {
let position = (textWidth * h + w) * 4;
// 返回的数组是rgba的方式存储
let r = imgData.data[position],
g = imgData.data[position + 1],
b = imgData.data[position + 2],
a = imgData.data[position + 3];
if (r + g + b == 0) {
continue
}
//烟花代码
}
}

在上面的代码块中,遍历了从左到右,从上到下,遍历了整个图形区域的全部像素信息,r,g,b,a对应一个某个像素点的颜色,当颜色不为黑色时,我们不对它进行操作,跳过此轮循环,当颜色不为黑色时,利用该点的信息生成一个烟花粒子

let firework = {};
firework.x = x;
firework.y = y;
firework.fx = x + w - textWidth / 2;
firework.fy = y + h - font / 2;
firework.size = Math.floor(Math.random() * 2) + 1;
firework.speed = 1;
setColors(firework);
fireworks.push(firework);

烟花粒子对象存入烟花数组中

4. 设置粒子动画

现在我们已经得到了一整个即将绽放的烟花数组,我们只需要给他们加上动画,通过每次渲染时改变当前粒子的坐标,降低透明度实现烟花殆尽的效果,直至烟花粒子透明度降为0

关键代码

firework.x += (firework.fx - firework.x) / 10;
firework.y += (firework.fy - firework.y) / 10 - (firework.alpha - 1) * firework.speed;
firework.alpha -= 0.01;
// 如果透明度小于0就删除这个粒子
if (firework.alpha <= 0) {
fireworks.splice(i, 1);
// 跳过这次循环,不进行绘制
continue;
}

5. 设置拖尾并渲染更新画布

拖尾实现的思路是不断的添加一个半透明的蒙层来实现,使用 requestAnimationFrame于定时器的区别在上篇文章有讲过噢

function tick() {
// // 设置拖影
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = 'rgba(0,0,0,' + 10 / 100 + ')';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'lighter';
// 更新画布
drawFires();
requestAnimationFrame(tick);
}

总结

今天的烟花就到这里反映结束了,不过瘾的话,可以让我们一起期待下一篇图片烟花效果噢~摩尔庄园的烟花也很好看噢!

还在用canvas画格子吗?文字烟花效果更不错噢的更多相关文章

  1. 樱花的季节,教大家用canvas画出飞舞的樱花树

    又到了樱花的季节,教大家使用canvas画出飞舞的樱花树效果. 废话少说,先看效果. 演示效果地址:http://suohb.com/work/tree4.htm 查看演示效果 第一步,我们先画出一棵 ...

  2. Android利用canvas画各种图形

    Android利用canvas画各种图形(点.直线.弧.圆.椭圆.文字.矩形.多边形.曲线.圆角矩形) 本文链接:https://blog.csdn.net/rhljiayou/article/det ...

  3. 使用javascript和canvas画月半弯

    使用javascript和canvas画月半弯,月半弯好浪漫!浏览器须支持html5 查看效果:http://keleyi.com/a/bjad/8xqdm0r2.htm 以下是代码: <!do ...

  4. canvas画随机闪烁的星星

    canvas画一颗星星: 规则的星星有内切圆和外切圆,每两个点之间的角度是固定的,因此可得到星星的每个点的坐标,画出星星. function drawStars(x,y,radius1,radius2 ...

  5. 深夜,用canvas画一个时钟

    深夜,用canvas画一个时钟 查看demo 这几天准备阿里巴巴的笔试,可以说已经是心力交瘁,自从阿里和蘑菇街的内推被刷掉之后,开始越来越怀疑起自己的能力来,虽然这点打击应该是微不足道的.毕竟校招在刚 ...

  6. [JavaScript] canvas 合成图片和文字

    Canvas Canvas 是 HTML5 新增的组件,就像一个画板,用 js 这杆笔,在上面乱涂乱画 创建一个 canvas <canvas id="stockGraph" ...

  7. canvas转图片中的文字自动换行

    概述 最近项目用到了canvas转图片,但是由于canvas对文字排版的支持非常弱,一般我们在canvas上画不同排版的文字(比如竖排文字)都是利用js计算横纵坐标,然后一个字一个字地画出来,今天无意 ...

  8. 10分钟,利用canvas画一个小的loading界面

    首先利用定义下canvas得样式 <canvas width="1024" height="720" id="canvas" styl ...

  9. 【带着canvas去流浪(10)】文字烟花

    目录 一. 文字烟花 二. 动画原理 2.1 像素操作 2.2 烟花生成算法 2.3 计时器 示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址 ...

随机推荐

  1. mysql事务干货详解

    说明: mysql是现在行业中流行的关系型数据库,它的核心是存储引擎.mysql的存储引擎有很多种我们可以通过命令查看如下 SHOW ENGINES 不同版本得到的数据不一样,我们今天说的事务是在 M ...

  2. win10连接mysql提示:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

    win10中cmd连接mysql提示:ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YE ...

  3. ci框架驱动器

    1.驱动器什么是 驱动器是一种特殊类型的类库,它有一个父类和任意多个子类.子类可以访问父类, 但不能访问兄弟类.在你的控制器中,驱动器为你的类库提供了 一种优雅的语法,从而不用将它们拆成很多离散的类. ...

  4. windows2012安装django

    第一步:下载python3.6.8或者到(https://www.python.org/downloads/release/python-368/)官网下载(Windows x86-64 execut ...

  5. Elasticsearch、XXLJob以及最近的学习记录

    Elasticsearch.XXLJob以及最近的学习记录 前言 在这九月的最后一周,来总结一下最近的学习记录,主要是对于Elasticsearch.XXLjob的初步学习,想着还是多记录点,以便后面 ...

  6. P5074-Eat the Trees【插头dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P5074 题目大意 给出一个\(n\times m\)的网格,有的必须铺线有的不能,铺成若干条闭合回路,求方案数. ...

  7. Java-对象克隆

    1. 为什么要克隆 在java中,我们通过直接=等号赋值的方法来拷贝,如果是基本数据类型是没有问题的,例如 int i = 1; int j = 0; j = i; // 直接=等号赋值,这样是没有问 ...

  8. 提问式复习:图文回顾 redo log 相关知识

    原文链接:提问式复习:图文回顾 redo log 相关知识 1.如何提升 redo日志 的写性能? 为了保证 redo日志 不丢失,会在磁盘中开辟一块空间将日志保存起来.但是这样会有一个问题,磁盘的读 ...

  9. .Net Core 实现 自定义Http的Range输出实现断点续传或者分段下载

    一.Http的Range请求头,结合相应头Accept-Ranges.Content-Range 可以实现如下功能: 1.断点续传.用于下载文件被中断后,继续下载. 2.大文件指定区块下载,如视频.音 ...

  10. vue+element UI 使用select元素动态的从后台获取到

    VUE select元素动态的从后台获取到 <el-form-item label="选择店铺"> <el-select v-model="value& ...