<template>
	<view>
		<canvas type="2d" canvas-id="reusableCanvas" :width="currentCanvasWidth" :height="currentCanvasHeight"
			class="offscreen-canvas"></canvas>
	</view>
</template>

<script>
	export default {
		name: "TextToHexV1",
		props: {
			txts: {
				type: Array,
				default: () => [],
				validator: (value) => value.every(item => typeof item === 'string')
			},
			fontSize: {
				type: Number,
				default: 16,
				validator: (value) => value > 0 && value <= 100
			},
			bgColor: {
				type: String,
				default: "#ffffff"
			},
			color: {
				type: String,
				default: "#000000"
			}
		},
		data() {
			return {
				// 当前Canvas的宽高（动态调整）
				currentCanvasWidth: 0,
				currentCanvasHeight: 0,
				// Canvas上下文（复用）
				ctx: null,
				// 标记是否已经预热过画布
				canvasWarmed: false
			};
		},
		computed: {
			validTxts() {
				return this.txts.filter(line => line.trim() !== '');
			}
		},
		mounted() {
			// 初始化Canvas上下文（只创建一次）
			this.ctx = uni.createCanvasContext('reusableCanvas', this);
		},
		methods: {
			/**
			 * 估算单行文本所需的Canvas宽度
			 */
			calcLineWidth(textLine) {
				return textLine.length * 16;
			},

			/**
			 * 清除Canvas内容
			 */
			clearCanvas() {
				this.ctx.setFillStyle(this.bgColor);
				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处理所有文本行
			 */
			async drawAndGetPixels() {
				// 第一次调用时先预热画布（解决APP重新打开后第一次获取数据不完整的问题）
				// await this.warmupCanvas();
				
				let convertCharToMatrix=function(imageData) {
					debugger;
					// console.log("imgData=",imageData)
					let matrix = [];

					// 逐行处理
					for (let y = 0; y < 16; y++) {
						let byte1 = 0,
							byte2 = 0;

						// 每行16个像素，分为两个字节
						for (let x = 0; x < 16; x++) {
							// 计算像素在imageData中的索引 (RGBA格式)
							let index = (y * 16 + x) * 4;
							let red = imageData[index];

							// 黑色像素（R值较低）视为1，白色视为0
							let isBlack = red < 128;

							if (x < 8) {
								// 第一个字节（左8位）
								if (isBlack) {
									byte1 |= 0x80 >> x; // 从左到右设置位
								}
							} else {
								// 第二个字节（右8位）
								if (isBlack) {
									byte2 |= 0x80 >> (x - 8);
								}
							}
						}

						// 将字节转换为两位十六进制字符串
						matrix.push('0x' + byte1.toString(16).padStart(2, '0').toUpperCase());
						matrix.push('0x' + byte2.toString(16).padStart(2, '0').toUpperCase());
					}

					return matrix;
				}

				let  drawTxt=async (textLine)=> {
					debugger;
					let result = {};
					let ctx = this.ctx;

					// 1. 动态调整Canvas尺寸
					this.currentCanvasWidth = this.calcLineWidth(textLine);
					this.currentCanvasHeight = 16;

					// 2. 清空Canvas（绘制背景）
					this.clearCanvas();

					// 3. 设置文字样式
					ctx.setFillStyle(this.color);
					ctx.setTextBaseline('middle');
					// ctx.setTextAlign('center')
					ctx.setFontSize(this.fontSize);
					ctx.font = `${this.fontSize}px "PingFangBold", "PingFang SC", Arial, sans-serif`;
					
					// 4. 绘制当前行文本
					let currentX = 0;
					let currentY = this.fontSize / 2;
					for (let j = 0; j < textLine.length; j++) {
						let char = textLine[j];
						ctx.fillText(char, currentX, currentY);
						// 按实际字符宽度计算间距
						let charWidth = ctx.measureText(char).width;
						currentX += charWidth;
					}

					// 5. 异步绘制并获取像素数据（串行处理避免冲突）
					await new Promise((resolve, reject) => {
						ctx.draw(false, () => {
							uni.canvasGetImageData({
								canvasId: 'reusableCanvas',
								x: 0,
								y: 0,
								width: this.currentCanvasWidth,
								height: this.currentCanvasHeight,
								success: res => {
									
									result={
										line: textLine,
										pixelData: res.data,
										width: this.currentCanvasWidth,
										height: this.currentCanvasHeight
									};
									resolve();
								},
								fail: err => {
									// console.error(`处理第${i+1}行失败:`, err);
									reject(err)
								}
							});
						});
					});

					return result;
				}
				let arr = [];
				// 循环处理每行文本
				for (let i = 0; i < this.validTxts.length; i++) {
debugger;
					let linePixls = [];
					let item = this.validTxts[i];
				
					for (var j = 0; j < item.length; j++) {
						let result = await drawTxt(item[j]);
						linePixls.push(convertCharToMatrix(result.pixelData));
					}
					// console.log("hexs=",linePixls.join(","));
					arr.push(linePixls);
				}
				
				return arr;
			}
		}
	};
</script>

<style>
	.offscreen-canvas {
		position: fixed;
		left: -9999px;
		top: -9999px;
		visibility: hidden;
	}
</style>