先上一图:,这个是最终效果:
直观一点可以看视频
在线体验:体验路径-》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 () {
}
})