前言

一年一度的支付宝“集五福”活动在年跟前儿又上线啦,今年支付宝推出了写福字儿的活动,完成任务即可收集福卡。这么多年了,尽管每年都只能分那么块儿八毛的,但是集福热度一点儿没减,毕竟过年也没什么像样的集体活动,特别是今年又被留在“帝都”就地过年了,就用集五福这事儿提醒自己过了一个年吧!

正文

自己突然冒突出了一个想法

写完支付宝的福字儿后,自己成功收集到了一张和谐福。最后,我还把自己写的福字儿保存成了壁纸,不怕大家笑话,请看下图(不好看也别喷我哈):

#yyds干货盘点#一个小白模仿了一把支付宝新春的写“福”字功能_数据

欣赏着这张壁纸时,自己冒出一个想法:这个功能好实现吗?自己可以搞定吗?

开始动手DIY

带着这个想法,自己开始构思如何实现这个功能,毕竟咱们多少还是有点想法的💡,哈哈😄。暂定用 VUE 框架实现吧,开始搞!

新建一个 VUE 工程

使用 VSCode 新建一个 VUE 工程,包含基础的文件和目录结构,如下图所示:

#yyds干货盘点#一个小白模仿了一把支付宝新春的写“福”字功能_音视频_02

简单介绍一个工程结构,其中 build 目录,包含了项目构建的相关代码;
config 目录,包含了项目的配置信息,比如路径、服务端口等;
node_modules 目录,包含了项目依赖的第三库;
src 目录,包含了项目的所有源码文件;
static 目录,静态资源目录;
index.html,项目首页入口文件;
package.json,项目配置文件。

设计画布

简单的引入一张图片作为画布,同时定义“重写”和“完成”两个按钮,相关代码如下:

<img
v-if="showTian"
src="../assets/tian.png"
:style="{ width: this.canvasSize + 'px' }"
class="zmiti-tian-img"
ref="tian"
/>

<div class="zmiti-btn-group" v-if="showBtnGroup">
<div @click="rewrite"><img src="../assets/rewrite.png" /></div>
<div @click="finish"><img src="../assets/done.png" /></div>
</div>

田字画布如下:

#yyds干货盘点#一个小白模仿了一把支付宝新春的写“福”字功能_支付宝_03

重写方法定义如下:

rewrite() {
this.ctx.clearRect(0, 0, this.canvasSize, this.canvasSize);
},

完成方法定义如下:

finished() {
this.reelContext.save();
this.reelContext.drawImage(
this.ctx.canvas,
this.viewW / 2 - this.canvasSize / 2,
(3.2 * this.viewW) / 10
);
this.reelContext.restore();
}

设计画笔

接下来,我们开始设计画笔,包括画笔的粗细、颜色、特效等,相关代码如下:

touchstart(e) {
this.startX = e.changedTouches[0].pageX;
this.startY = e.changedTouches[0].pageY;

this.moveFlag = true;
this.has = this.has || [];
this.upof = this.getXY(e);
},
touchmove(e) {
this.endX = e.changedTouches[0].pageX;
this.endY = e.changedTouches[0].pageY;

if (!this.moveFlag) return;
var of = this.getXY(e);

this.ctx.fillStyle = "rgba(0,0,0,0.25)";
var up = this.upof;
var ur = this.radius;
this.has.unshift({
time: new Date().getTime(),
dis: this.distance(up, of),
});
var dis = 0;
var time = 0;
for (var n = 0; n < this.has.length - 1; n++) {
dis += this.has[n].dis;
time += this.has[n].time - this.has[n + 1].time;
if (dis > this.smoothness) break;
}
var or =
Math.min(
(time / dis) * this.linePressure + this.lineMin,
this.lineMax
) / 2;
this.radius = or;
this.upof = of;
if (this.has.length <= 1) return;
var len = Math.round(this.has[0].dis / 2) + 1;
for (var i = 0; i < len; i++) {
var x = up.x + ((of.x - up.x) / len) * i;
var y = up.y + ((of.y - up.y) / len) * i;
var r = ur + ((or - ur) / len) * i;
this.ctx.beginPath();
this.ctx.arc(x, y, r / 2, 0, 2 * Math.PI, true);
this.ctx.fill();
}
},
touchend() {
this.moveFlag = false;
},
getXY(e) {
var e = e.changedTouches[0];
return {
x:
e.clientX -
(this.viewW - this.canvasSize) / 2 +
(document.body.scrollLeft || document.documentElement.scrollLeft),
y:
e.clientY -
this.canvas.offsetTop +
(document.body.scrollTop || document.documentElement.scrollTop),
};
},
distance(a, b) {
var x = b.x - a.x,
y = b.y - a.y;
return Math.sqrt(x * x + y * y);
},

写出的福字效果如下图所示:

#yyds干货盘点#一个小白模仿了一把支付宝新春的写“福”字功能_音视频_04


结尾

由于时间紧张,完整的功能还没有实现全,如果任意数据能上双(比如点赞数>9,或者评论数>9,或者收藏数>9),我就加班加点把功能实现完,并放到 github 上供大佬们“指点江山”。


作者简介:😄大家好,我是 Data-Mining(liuzhen007),是一位典型的音视频技术爱好者,前后就职于传统广电巨头和音视频互联网公司,具有丰富的音视频直播和点播相关经验,对 WebRTC、FFmpeg 和 Electron 有非常深入的了解,😄公众号:玩转音视频。同时也是 CSDN 博客专家、华为云享专家(共创编辑)、InfoQ 签约作者,欢迎关注我分享更多干货!😄