小程序:利用canvas制作文字特效

982 阅读1分钟

先上一图:,这个是最终效果:

直观一点可以看视频

www.ixigua.com/69684358313…

在线体验:体验路径-》wx:完美工具--》闪耀爱豆

简要说明实现思路:

1、先将文字画在canvas,2、利用getImageData()获取图像数据,3、将图像数据中黑色(你可以用其他颜色)按一定间隔取值(获取坐标),4、在获取的坐标画矩形(你画其他形状也是可以的),5、使用requestAnimationFrame,变换矩形颜色。这样就闪烁起来了~~

直接上代码

var i = 0

Page({

/**

* 页面的初始数据

*/

data: {

hideNav: false,

colors: ["#fff", "#FF6E40", "#FFAB40", "#FFFF00", "#EEFF41", "#B2FF59", "#69F0AE", "#64FFDA", "#18FFFF", "#40C4FF", "#E040FB", "#FF4081", "#ff5252"],

text: '肖战',

scroll: false,

setting: false

},

/**

* 生命周期函数--监听页面加载

*/

onLoad: function (options) {

let that = this, text = wx.getStorageSync('blinkText') || this.data.text;

this.setData({

text

})

this.init()

},

init() {

wx.createSelectorQuery()

.select('#canvas')

.fields({

node: true,

size: true,

})

.exec((res) => {

let that = this,

text = this.data.text

const width = res[0].width

const height = res[0].height

const canvas = res[0].node

const ctx = canvas.getContext('2d')

const dpr = 1 //wx.getSystemInfoSync().pixelRatio

canvas.width = width * dpr

canvas.height = height * dpr

ctx.scale(dpr, dpr)

i = (canvas.width - that.getByteLen(text) * 100) / 2

ctx.fillStyle = "#ffffff";

ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.font = "bolder 200px Arial";

ctx.fillStyle = 'black';

ctx.textBaseline = 'top';

ctx.fillText(text, 0, 100);

// ctx.lineWidth = 5;

// ctx.strokeText(text, 0, 100);

let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data;

// console.log(imageData)

ctx.fillStyle = "#ffffff";

ctx.fillRect(0, 0, canvas.width, canvas.height);

this.data.canvas = canvas

this.data.ctx = ctx

this.data.imageData = imageData

console.log(canvas.width, canvas.height)

// this.drawText()

const renderLoop = () => {

this.drawText()

canvas.requestAnimationFrame(renderLoop)

}

// canvas.cancelAnimationFrame(renderLoop)

canvas.requestAnimationFrame(renderLoop)

})

},

drawText() {

var gap = 7,

{

imageData,

canvas,

ctx,

text,

scroll

} = this.data

if (scroll) {

if (i >= canvas.width) {

i = -canvas.width

}

i += 2

}

ctx.clearRect(0, 0, canvas.width, canvas.height)

for (var h = 0; h < canvas.height; h += gap) {

for (var w = 0; w < canvas.width; w += gap) {

var position = (canvas.width * h + w) * 4;

var r = imageData[position],

g = imageData[position + 1],

b = imageData[position + 2];

if (r + g + b == 0) {

ctx.fillStyle = this.data.colors[Math.floor(Math.random() * this.data.colors.length)];

ctx.fillRect(w + i, h, 5, 5);

}

}

}

},

toggleSetting() {

this.setData({

setting: this.data.setting ? false : true

})

},

setText(e) {

let that = this

wx.cloud.callFunction({

name: 'msgSecCheck',

data: {

op: 'textCheck',

content: e.detail.value

},

success(res) {

console.log('ContentCheck-res', res)

if (res.result.code == 300) {

console.log(res.result.msg)

wx.showToast({

icon: 'none',

title: res.result.msg,

})

that.setData({

'text': ''

})

} else {

that.setData({

setting: false,

'text': e.detail.value

})

that.init()

}

},

fail(err) {

console.log('ContentCheck-errxxxx', err)

}

})

},

getByteLen(str) {

var len = 0;

for (var i = 0; i < str.length; i++) {

var length = str.charCodeAt(i);

if (length >= 0 && length <= 128) {

len += 1;

} else {

len += 2;

}

}

console.log('文字长度',len)

return len;

},

donothing() {

},

/**

* 生命周期函数--监听页面初次渲染完成

*/

onReady: function () {

},

/**

* 生命周期函数--监听页面显示

*/

onShow: function () {

},

/**

* 生命周期函数--监听页面隐藏

*/

onHide: function () {

},

/**

* 生命周期函数--监听页面卸载

*/

onUnload: function () {

wx.setStorage({

data: this.data.text,

key: 'blinkText',

})

},

/**

* 页面相关事件处理函数--监听用户下拉动作

*/

onPullDownRefresh: function () {

},

/**

* 页面上拉触底事件的处理函数

*/

onReachBottom: function () {

},

/**

* 用户点击右上角分享

*/

onShareAppMessage: function () {

}

})