特效

canvas 文字粒子特效

2019-04-24  本文已影响0人  没事儿啊

转自博客原文连接:https://tong-h.github.io/2019/04/23/canvas-fontparticle/

想要往仓库多填一些干货,一个文字粒子效果 点这里看效果

效果图

随机初始化部分粒子

1、首先要明白每个粒子都是一个对象,都有自己的移动轨迹,起点,移动速度,终点

2、粒子活动轨迹:初始化 ---- 聚合拼合文字形状 ---- 散开 ---- 再聚合 ---- 散开...

3、我们需要根据动画时间调整粒子移动的速度来安排他们的位置

    class Point{
        constructor() {
            this.startx = Math.floor(Math.random() * docsize[0]),   // 初始起点
            this.starty = Math.floor(Math.random() * docsize[1]),
            this.speedx = (Math.random() * 2 - 1) * pointspeed,     // 移动速度
            this.speedy = (Math.random() * 2 - 1) * pointspeed, 
            this.endx = 0,                                          // 终点
            this.endy = 0,                    
            this.color = Math.floor(Math.random() * 5)              // 粒子颜色
        }
        endpoint(x, y) {
            this.endx = x
            this.endy = y
        }
        animal() {
            this.startx += this.speedx
            this.starty += this.speedy

            // 到达边界改变粒子运动方向
            this.speedx *= this.startx > docsize[0] || this.startx < 0 ? -1 : 1
            this.speedy *= this.starty > docsize[1] || this.starty < 0 ? -1 : 1

            // 调整点的移动速度用以聚和拼合文字
            if(time === 100 || time === 600 || time === 1100) { 
                this.speedx = (this.endx - this.startx) / joinspeed
                this.speedy = (this.endy - this.starty) / joinspeed
            }

            // 到达终点后静止不动
            if(time === 100 + joinspeed || time === 600 + joinspeed || time === 1100 + joinspeed) {
                this.speedx = 0
                this.speedy = 0
            }

            // 散开
            if(time === 300 || time === 800) {
                this.speedx = (Math.random() * 2 - 1) * pointspeed
                this.speedy = (Math.random() * 2 - 1) * pointspeed
            }

            maincontent.beginPath()
            maincontent.fillStyle = color[this.color]
            maincontent.arc(this.startx, this.starty, 7, 0, Math.PI * 2)
            maincontent.fill()
        }
    }

使用 canvas 画板生成文字

// 【文字面积,循环时用于判读y轴高度,粒子大小间隔, 文字宽度】
let [imgdata, cyclic, size, textwith] = [{}, 1, 16, 0]

textcontext.font = "normal 900 " + fontsize +"px Avenir, Helvetica Neue, Helvetica, Arial, sans-serif"
textwith = Math.floor(textcontext.measureText(text).width)
textcontext.fillStyle = '#ff0000'
textcontext.fillText(text, (docsize[0] - textwith) / 2, (docsize[1]) / 2)
textwith = ~~ (textwith) * size + size

遍历 imageData 获取文字区域的像素坐标

不了解 imagedata 怎么用? 看看这篇文章cannvas的imagedata对象

获取坐标这里有很多种方法,我看了一些教程好像没人像我这么写,要注意的是

// 获取文字所在区域,尽可能减小面积
imgdata = textcontext.getImageData(0,0, textwith, fontsize * 2)
textcontext.clearRect(0, 0, docsize[0], docsize[1])

// 粒子圆心坐标,粒子数组
let [x, y, len] = [0, 0, 0]

// 遍历data数据查找文字所在的坐标
for (var i = 0; i < imgdata.data.length; i += size * 4) {
    if (imgdata.data[i] === 255 && imgdata.data[i+3] === 255) {

        // 判断当前粒子数量是否能够拼合文字
        if (len > pointarr.length - 1) pointarr.push(new Point)

        // 获取每个粒子聚拢的终点
        pointarr[len].endpoint(i /4 % textwith, cyclic)
        len ++
    }
    if (i/4 == cyclic * textwith) {
        cyclic += size
        i = textwith * (cyclic-1) * 4
    } 
}

pointarr.length - 1 - len > 0 ? pointarr.splice(len, pointarr.length - len) : ''

源码带有详细的注解点这儿

更多效果
开源不易,觉得还不错点个 start 吧 (´▽`ʃ♡ƪ)

上一篇 下一篇

猜你喜欢

热点阅读