修复6155人员信息第一个字体缺失问题,画布取值加载预热机制
This commit is contained in:
@ -34,7 +34,9 @@
|
|||||||
currentCanvasWidth: 0,
|
currentCanvasWidth: 0,
|
||||||
currentCanvasHeight: 0,
|
currentCanvasHeight: 0,
|
||||||
// Canvas上下文(复用)
|
// Canvas上下文(复用)
|
||||||
ctx: null
|
ctx: null,
|
||||||
|
// 标记是否已经预热过画布
|
||||||
|
canvasWarmed: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -62,10 +64,67 @@
|
|||||||
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
|
this.ctx.fillRect(0, 0, this.currentCanvasWidth, this.currentCanvasHeight);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 预热画布,确保画布和字体完全准备好(解决APP重新打开后第一次获取数据不完整的问题)
|
||||||
|
*/
|
||||||
|
async warmupCanvas() {
|
||||||
|
if (this.canvasWarmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 设置画布尺寸
|
||||||
|
this.currentCanvasWidth = 16;
|
||||||
|
this.currentCanvasHeight = 16;
|
||||||
|
|
||||||
|
// 清空画布
|
||||||
|
this.clearCanvas();
|
||||||
|
|
||||||
|
// 绘制一个测试字符来预热字体和画布
|
||||||
|
this.ctx.setFillStyle(this.color);
|
||||||
|
this.ctx.setFontSize(this.fontSize);
|
||||||
|
this.ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
|
||||||
|
this.ctx.setTextBaseline('middle');
|
||||||
|
this.ctx.fillText('测', 0, 8);
|
||||||
|
|
||||||
|
// 等待画布绘制完成
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
this.ctx.draw(false, () => {
|
||||||
|
// 获取一次测试数据,确保canvasGetImageData API已准备好
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.canvasGetImageData({
|
||||||
|
canvasId: 'reusableCanvas',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 16,
|
||||||
|
height: 16,
|
||||||
|
success: () => {
|
||||||
|
this.canvasWarmed = true;
|
||||||
|
resolve();
|
||||||
|
},
|
||||||
|
fail: () => {
|
||||||
|
this.canvasWarmed = true;
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 额外等待确保字体完全加载
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 200));
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("画布预热异常:", ex);
|
||||||
|
this.canvasWarmed = true; // 即使失败也标记为已预热,避免重复尝试
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 复用单个Canvas处理所有文本行
|
* 复用单个Canvas处理所有文本行
|
||||||
*/
|
*/
|
||||||
async drawAndGetPixels() {
|
async drawAndGetPixels() {
|
||||||
|
// 第一次调用时先预热画布(解决APP重新打开后第一次获取数据不完整的问题)
|
||||||
|
await this.warmupCanvas();
|
||||||
|
|
||||||
let convertCharToMatrix=function(imageData) {
|
let convertCharToMatrix=function(imageData) {
|
||||||
// console.log("imgData=",imageData)
|
// console.log("imgData=",imageData)
|
||||||
@ -119,7 +178,7 @@
|
|||||||
|
|
||||||
// 3. 设置文字样式
|
// 3. 设置文字样式
|
||||||
ctx.setFillStyle(this.color);
|
ctx.setFillStyle(this.color);
|
||||||
ctx.setTextBaseline('middle');
|
ctx.setTextBaseline('middle');
|
||||||
// ctx.setTextAlign('center')
|
// ctx.setTextAlign('center')
|
||||||
ctx.setFontSize(this.fontSize);
|
ctx.setFontSize(this.fontSize);
|
||||||
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
|
ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
|
||||||
|
|||||||
@ -1528,78 +1528,58 @@
|
|||||||
|
|
||||||
var promise = new Promise((resolve, reject) => {
|
var promise = new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
|
// 设备协议:FA 06/07/08 01 00 + 256字节数据 + FF
|
||||||
|
// 每个文本行只需要一个261字节的包
|
||||||
|
const bufferSize = 261;
|
||||||
|
const dataSize = 256; // 数据部分固定256字节
|
||||||
|
|
||||||
let packetSize = rgbdata.length; //每包均分的数量
|
let buffer = new ArrayBuffer(bufferSize);
|
||||||
let mode = rgbdata.length % packetSize; //最后一包的数量
|
let dataView = new DataView(buffer);
|
||||||
let cnt =
|
|
||||||
1; // parseInt(rgbdata.length / packetSize) + (mode > 0 ? 1 :0); //总包数量
|
|
||||||
let curr = 1; //当前包序号
|
|
||||||
|
|
||||||
let sendNext = () => {
|
// 写入头部:FA 06/07/08 01 00
|
||||||
|
dataView.setUint8(0, 0xFA);
|
||||||
if (curr > cnt) {
|
dataView.setUint8(1, type);
|
||||||
resolve();
|
dataView.setUint8(2, 0x01);
|
||||||
return;
|
dataView.setUint8(3, 0x00);
|
||||||
}
|
|
||||||
|
|
||||||
let bufferSize = 261;
|
|
||||||
|
|
||||||
console.log("bufferSize=", bufferSize)
|
|
||||||
|
|
||||||
let buffer = new ArrayBuffer(bufferSize);
|
|
||||||
let dataView = new DataView(buffer);
|
|
||||||
let startIndex = (curr - 1) * packetSize;
|
|
||||||
|
|
||||||
let endIndex = Math.min(startIndex + packetSize, rgbdata
|
|
||||||
.length);
|
|
||||||
if (startIndex > endIndex) {
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let packetData = rgbdata.slice(startIndex,
|
|
||||||
endIndex); //取一片数据发送
|
|
||||||
console.log("packetData.length=", packetData.length);
|
|
||||||
let start = 0;
|
|
||||||
if (curr == 1) {
|
|
||||||
dataView.setUint8(0, 0xFA);
|
|
||||||
dataView.setUint8(1, type);
|
|
||||||
dataView.setUint8(2, 0x01);
|
|
||||||
dataView.setUint8(3, 0x00);
|
|
||||||
|
|
||||||
|
|
||||||
start = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < packetData.length; i++) {
|
|
||||||
dataView.setUint8(start + i, packetData[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
dataView.setUint8(bufferSize - 1, 0xFF);
|
|
||||||
|
|
||||||
let inteval = 200;
|
|
||||||
//parseInt(this.inteval ? this.inteval : 80);
|
|
||||||
//console.log("inteval=", inteval)
|
|
||||||
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
|
|
||||||
.wirteCharactId, 30).then(() => {
|
|
||||||
|
|
||||||
curr++;
|
|
||||||
setTimeout(sendNext, inteval);
|
|
||||||
}).catch(err => {
|
|
||||||
|
|
||||||
if (err.code == '10007') {
|
|
||||||
setTimeout(sendNext, inteval);
|
|
||||||
} else {
|
|
||||||
reject(err);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// 写入数据(最多256字节),确保数据是数字格式
|
||||||
|
let actualDataSize = Math.min(rgbdata.length, dataSize);
|
||||||
|
for (let i = 0; i < actualDataSize; i++) {
|
||||||
|
// 确保数据是数字格式,如果是字符串则转换
|
||||||
|
let byteValue = typeof rgbdata[i] === 'string' ? these.toByteValue(rgbdata[i]) : rgbdata[i];
|
||||||
|
dataView.setUint8(4 + i, byteValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendNext();
|
// 用0填充剩余数据部分(如果数据不足256字节)
|
||||||
} catch (ex) {
|
for (let i = 4 + actualDataSize; i < bufferSize - 1; i++) {
|
||||||
console.log("ex=", ex);
|
dataView.setUint8(i, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 写入尾部:FF
|
||||||
|
dataView.setUint8(bufferSize - 1, 0xFF);
|
||||||
|
|
||||||
|
console.log(`发送文本数据包: type=0x${type.toString(16)}, 数据长度=${actualDataSize}, 总长度=${bufferSize}`);
|
||||||
|
|
||||||
|
// 发送数据包
|
||||||
|
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
|
||||||
|
.wirteCharactId, 100).then(() => {
|
||||||
|
resolve();
|
||||||
|
}).catch(err => {
|
||||||
|
if (err.code == '10007') {
|
||||||
|
// 重试
|
||||||
|
setTimeout(() => {
|
||||||
|
ble.sendData(f.deviceId, buffer, f.writeServiceId, f
|
||||||
|
.wirteCharactId, 100).then(() => {
|
||||||
|
resolve();
|
||||||
|
}).catch(reject);
|
||||||
|
}, 100);
|
||||||
|
} else {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (ex) {
|
||||||
|
console.log("构建数据包异常:", ex);
|
||||||
reject(ex);
|
reject(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1612,9 +1592,10 @@
|
|||||||
var result = null;
|
var result = null;
|
||||||
try {
|
try {
|
||||||
console.log("this.$refs.textToHex=", this.$refs.textToHex);
|
console.log("this.$refs.textToHex=", this.$refs.textToHex);
|
||||||
|
// 获取像素数据(组件内部会自动预热画布)
|
||||||
result = await this.$refs.textToHex.drawAndGetPixels();
|
result = await this.$refs.textToHex.drawAndGetPixels();
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.log("ex=", ex);
|
console.log("获取画布数据异常:", ex);
|
||||||
}
|
}
|
||||||
if (!result) {
|
if (!result) {
|
||||||
hideLoading(this);
|
hideLoading(this);
|
||||||
@ -1622,7 +1603,10 @@
|
|||||||
}
|
}
|
||||||
console.log("result=", result);
|
console.log("result=", result);
|
||||||
result = result.map(level1 => {
|
result = result.map(level1 => {
|
||||||
return level1.flat(Infinity);
|
return level1.flat(Infinity).map(item => {
|
||||||
|
// 确保数据转换为数字格式,避免字符串格式导致的问题
|
||||||
|
return typeof item === 'string' ? these.toByteValue(item) : item;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
console.log("result=", result);
|
console.log("result=", result);
|
||||||
|
|
||||||
@ -1643,6 +1627,9 @@
|
|||||||
let h3dic = [0x06, 0x07, 0x08];
|
let h3dic = [0x06, 0x07, 0x08];
|
||||||
let pros = [];
|
let pros = [];
|
||||||
let flag = true;
|
let flag = true;
|
||||||
|
// 在开始发送前添加延迟,确保数据完全准备好(解决第一次发送第一个字缺失的问题)
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
|
|
||||||
for (var i = 0; i < result.length; i++) {
|
for (var i = 0; i < result.length; i++) {
|
||||||
|
|
||||||
let str = this.formData.textLines[i];
|
let str = this.formData.textLines[i];
|
||||||
@ -1651,14 +1638,32 @@
|
|||||||
|
|
||||||
let width = str.length * 16;
|
let width = str.length * 16;
|
||||||
var rgb = result[i];
|
var rgb = result[i];
|
||||||
|
|
||||||
|
// 确保数据是数组且已转换
|
||||||
|
if (!Array.isArray(rgb)) {
|
||||||
|
console.error(`第${i+1}行数据格式错误:`, rgb);
|
||||||
|
flag = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一次发送前额外延迟,确保设备完全准备好
|
||||||
|
if (i === 0) {
|
||||||
|
console.log("准备发送第一个文本行,等待设备准备好...");
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// console.log("1111");
|
console.log(`开始发送第${i+1}个文本行 (type=0x${h3dic[i].toString(16)})`);
|
||||||
await sendTxtPackge(rgb, h3dic[i], str);
|
await sendTxtPackge(rgb, h3dic[i], str);
|
||||||
// console.log("222222");
|
console.log(`第${i+1}个文本行发送完成`);
|
||||||
|
|
||||||
|
// 每个文本行发送完成后,添加延迟确保设备处理完成
|
||||||
|
if (i < result.length - 1) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 300));
|
||||||
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
flag = false;
|
flag = false;
|
||||||
console.log("33333");
|
console.error(`发送第${i+1}个文本行出现异常:`, ex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user