之前我出了一个如何在网页里使用原生 JS 开发放烟花效果的教程。
竟然有一个前端小阿姨问我,如果想要烟花放出来是文字的话怎么实现,她要给男朋友做一个。
好家伙,这狗粮洒一地呀
那狗粮不能我一个人吃,分享出来,大家一起吃。
此文配有 视频教程,边吃边看,狗粮更香。
你身边有这样的程序员小姐姐吗?
之前烟花源码里的核心是,我们在创建烟花粒子的时候,赋值了烟花绽放的原点x
,y
和圆形烟花的半径radius
。在绘制烟花动效时,半径不断加大,烟花的动效就出来。
//篇幅限制,仅展现部分代码
function createFireworks(x, y) {
var count = 100;
for (var i = 0; i < count; i++) {
var p = {};
p.x = x;
p.y = y;
p.speed = (Math.random() * 5) + .4;
p.radius = p.speed;
}
}
function drawFireworks(){
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
var vx = Math.cos(p.radians) * p.radius;
var vy = Math.sin(p.radians) * p.radius + 0.4;
p.x += vx;
p.y += vy;
p.radius *= 1 - p.speed / 100;
}
}
但要实现文字烟花,我们一开始就要把烟花最后的x
,y
坐标全部精确的计算出来。所以这个烟花的绘制,我们要更改一下逻辑。在createFireworks
阶段,就计算出单个粒子的起点 x,y
和终点 fx,fy
。
代码修改后如下
//篇幅限制,仅展现部分代码
function createFireworks(x, y){
var count = 100;
for (var i = 0; i < count; i++) {
var angle = 360 / count * i;
var p = {};
p.x = x;
p.y = y;
p.radians = angle * Math.PI / 180;
p.radius = Math.random()*81+50;
p.fx = x + Math.cos(radians) * p.radius;
p.fy = y + Math.sin(radians) * p.radius;
}
}
function drawFireworks() {
for (var i = 0; i < particles.length; i++) {
var p = particles[i];
p.x += (p.fx - p.x)/10;
p.y += (p.fy - p.y)/10-(p.alpha-1)*p.speed;
}
}
这样我们就完成了第一步改造,后续我们要把文字写在画布上,并且将其转换为点阵数组,也就是所有烟花粒子的终点坐标。
其实和之前那篇《使用 Javascript 制作 BadApple 字符画视频》的原理是一样的。通过canvas
的 APIgetImageData
来获得画布指定区域内的全部点阵信息(rgba
数组)。
将createFireworks
方法改造如下
function createFireworks(x,y,text=""){
if(text!=""){
//绘制文字
}else{
//原有的烟花代码
}
}
传递一个text
参数,当此参数不为空时,我们进入文字烟花的绘制逻辑。
var fontSize = 120;
var textHeight = fontSize;
context.font=fontSize+"px Verdana";
context.fillStyle = "#ffffff";
context.fillText(text,0,textHeight);
这样我们就能把字绘制在画布上了,接着我们使用getImageData
来获得并裁剪点阵信息,因为我们只要一部分的点阵。
var imgData = textctx.getImageData(0,0,textWidth,textHeight);
for (var h = 0; h < textHeight; h+=gap) {
for(var w = 0; w < textWidth; w+=gap){
var position = (textWidth * h + w) * 4;
var r = imgData.data[position], g = imgData.data[position + 1], b = imgData.data[position + 2], a = imgData.data[position + 3];
}
}
这样我们就拿到了画布里文字绘制区域的全部点阵数据,数据的格式为
[r,g,b,a,r,g,b,a,r,g,b,a]
我们通过一个gap
值来跳跃间隔裁剪数据。由于画布是黑色,所以r
,g
,b
都为0
的点阵我们就不绘制了,现在将间隔的点阵信息再次绘制到画布中。
var fx = x + w - textWidth/2;
var fy = y + h - textHeight/2;
context.fillStyle = "#ffffff";
context.fillRect(fx,fy,1,1);
我们就会看见~
太棒了,这就是我们最终需要的文字烟花粒子的终点信息呀!
现在我们遍历全部的点阵,并创建烟花粒子吧!
for (var h = 0; h < textHeight; h+=gap) {
for(var w = 0; w < textWidth; w+=gap){
var position = (textWidth * h + w) * 4;
var r = imgData.data[position], g = imgData.data[position + 1], b = imgData.data[position + 2];
if(r+g+b==0)continue;
var p = {};
p.x = x;
p.y = y;
p.fx = x + w - textWidth/2;
p.fy = y + h - textHeight/2;
p.size = Math.floor(Math.random()*2)+1;
p.speed = 1;
setupColors(p);
particles.push(p);
}
}
至此,文字烟花效果,我们就实现了!!!
createFireworks(x, y,["杨幂","我爱你","永远"][Math.floor(Math.random()*3)]);
微信搜索“大帅老猿
”并回复“烟花
”即可获得本文全部源码
1
DIYgods 2021-05-06 10:36:58 +08:00 42
看着感觉真可怜
|
2
bug403 2021-05-06 10:42:35 +08:00
可怜+1,我也不知为什么?
|
4
caroline1022 2021-05-06 11:01:56 +08:00
标题党吧……人家也没说是挽回爱情啊,只是想给男朋友做个小礼物吧
但有一说一……有点…不太好看…如果有人做了给我,我怕是会连夜跑路 |
5
est 2021-05-06 11:02:50 +08:00 3
挽救的是你公众号的流量吧。
|
6
ezshine OP @caroline1022 哈哈
|
8
opengps 2021-05-06 11:33:25 +08:00
好像也就面向于某些群体才能用代码挽回爱情。。。悲,,,
|
9
Rxianbei 2021-05-06 11:36:16 +08:00 via Android
清醒一点,这只能挽回同性之间的爱情
|
11
domodomo 2021-05-06 12:54:37 +08:00
推广文案写得真烂
|
12
belin520 2021-05-06 13:45:09 +08:00 via iPhone
推广文写的烂,内容也差劲。不如散播焦虑来的流量多
|
13
wdssmq 2021-05-06 14:38:31 +08:00
挪到推广节点吧。。所以说,用微信公众号分享代码的真的叫码农么???
|
17
wudizaliangbing 2021-05-06 16:28:34 +08:00
答应我,不要做舔狗
|
18
a4854857 2021-05-06 16:51:19 +08:00
总所周知.v2 天生反推广..特别是公众号之类的..商家抽奖另说.
|
19
wdssmq 2021-05-06 17:16:46 +08:00
说起来我好像去年才弄微信公众号:
水水不想说 因为我真的不知道要在上边发什么,,自己的博客不好么,还能直接 md 写。。 |
20
pabupa 2021-05-06 17:27:19 +08:00
脑瘫……
|
22
ezshine OP @a4854857 嗯,可以理解,但是 V2 对内容作者的机制是不友好的。如果不引流,为什么要来 V2 发文章呢?代码发到公众号是为了关注,发到 github 难道不是为了 star,这有什么区别。
|
23
ezshine OP @wdssmq 看来你很久不发公众号了,现在的工具很厉害。我的公众号也全都是 md 写的,然后掘金,V2,知乎都复制粘贴一份就行。核心还是想把粉丝沉淀到 B 站和公众号里,V2 的机制对内容作者并不太好,不引流,在这发文的意义不大。
|
25
HankAviator 2021-05-06 20:57:25 +08:00
这分享太费小姐姐了🥺
看着自己的名字在一片漆黑(是什么场合我们要用黑底呢)中炸裂,然后慢慢消失总感觉毛骨悚然。不过效果倒是挺好看的。 |
26
iloveayu 2021-05-06 23:08:24 +08:00
你说的这个小阿姨是不是你自己
|
27
root01 2021-05-07 08:58:59 +08:00
磨磨唧唧,要想分享就别引流
|
28
Vitta 2021-05-07 12:59:14 +08:00
很好啊
|