284 lines
9.8 KiB
TypeScript
284 lines
9.8 KiB
TypeScript
// import TextDrawService from '../../canvasService/textDrawService';
|
||
// import TextDrawServiceV2 from '../../canvasService/textDrawServiceV2';
|
||
import { PAPER_SIZE } from '../../canvasService/constant';
|
||
import TextDrawServiceV3 from '../../canvasService/textDrawServiceV3';
|
||
|
||
Page({
|
||
canvas: null as Canvas | null,
|
||
ctx: null as RenderingContext | null,
|
||
data: {
|
||
characters: ['鱼', '鸟', '牛', '羊'] as const, // 固定汉字类型
|
||
colorMap: {
|
||
鱼: '#2196F3', // 蓝色
|
||
鸟: '#FFEB3B', // 黄色
|
||
牛: '#FF9800', // 橙色
|
||
羊: '#9C27B0', // 紫色
|
||
} as Record<string, string>,
|
||
matrix: [] as string[], // 随机汉字矩阵
|
||
selectedColor: '', // 当前选中颜色
|
||
selectedChar: '', // 当前选中汉字
|
||
},
|
||
|
||
onLoad() {
|
||
console.log('textPaint2 onLoad');
|
||
// this.setCanvasBoxSize();
|
||
// this.generateMatrix();
|
||
},
|
||
|
||
onReady() {
|
||
wx.nextTick(() => {
|
||
this.setCanvasBoxSize();
|
||
});
|
||
},
|
||
|
||
// setCanvasBoxSize() {
|
||
// const { width: paperWidth, height: paperHeight } = PAPER_SIZE['A4'];
|
||
|
||
// // 逻辑尺寸(容器宽高)
|
||
// const boxWidth = windowWidth - 40;
|
||
// const boxHeight = boxWidth / (paperWidth / paperHeight);
|
||
// console.log('boxWidth---:', boxWidth);
|
||
// console.log('boxHeight---:', boxHeight);
|
||
// this.setData({ boxWidth, boxHeight });
|
||
// // // 实际像素尺寸(需乘以设备像素比)
|
||
// // const canvasWidth = boxWidth * pixelRatio;
|
||
// // const canvasHeight = boxHeight * pixelRatio;
|
||
|
||
// // // 更新 Canvas 节点属性
|
||
// // const query = wx.createSelectorQuery().select('#textCanvas');
|
||
// // query.fields({ node: true, size: true }).exec((res) => {
|
||
// // const canvas = res[0].node;
|
||
// // canvas.width = canvasWidth;
|
||
// // canvas.height = canvasHeight;
|
||
// // // 缩放上下文以适配逻辑尺寸
|
||
// // const ctx = canvas.getContext('2d');
|
||
// // ctx.scale(pixelRatio, pixelRatio);
|
||
|
||
// // this.canvas = canvas;
|
||
// // this.ctx = ctx;
|
||
|
||
// // const textDrawService = new TextDrawServiceV3(canvas, ctx);
|
||
// // textDrawService.draw();
|
||
// // ctx.fillStyle = '#fff'; // 设置背景色为白色
|
||
// // ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
||
// // });
|
||
// },
|
||
|
||
// 生成6列随机矩阵
|
||
generateMatrix() {
|
||
const shuffled = [...this.data.characters]
|
||
.sort(() => Math.random() - 0.5)
|
||
.concat(
|
||
...Array(42)
|
||
.fill(null)
|
||
.map(() => this.data.characters[Math.floor(Math.random() * 4)]),
|
||
);
|
||
this.setData({ matrix: shuffled.slice(0, 42) }); // 6列x7行
|
||
},
|
||
|
||
setCanvasBoxSize() {
|
||
const { width, height } = PAPER_SIZE['A4'];
|
||
const { windowWidth } = wx.getWindowInfo();
|
||
const boxWidth = windowWidth - 20;
|
||
const boxHeight = boxWidth / (width / height);
|
||
console.log('boxWidth----:', boxWidth);
|
||
console.log('boxHeight----:', boxHeight);
|
||
this.setData({ boxHeight, boxWidth }, () => {
|
||
this.initCanvas();
|
||
});
|
||
},
|
||
|
||
// 初始化A4画布(300DPI)
|
||
initCanvas() {
|
||
wx.createSelectorQuery()
|
||
.select('#textCanvas')
|
||
.fields({
|
||
node: true,
|
||
size: true,
|
||
})
|
||
.exec((res) => {
|
||
if (res[0] && res[0].node) {
|
||
const canvas = res[0].node;
|
||
const ctx = canvas.getContext('2d');
|
||
if (ctx) {
|
||
this.canvas = canvas;
|
||
this.ctx = ctx;
|
||
const rect = res[0];
|
||
console.log('rect-----:', rect);
|
||
// const width = rect.width * dpr;
|
||
// const height = rect.height * dpr;
|
||
|
||
// 设置canvas的实际尺寸
|
||
// canvas.width = width;
|
||
// canvas.height = height;
|
||
// ctx.scale(dpr, dpr);
|
||
|
||
// 使用TextDrawServiceV3绘制
|
||
const textDrawService = new TextDrawServiceV3(canvas, ctx);
|
||
textDrawService.draw();
|
||
}
|
||
}
|
||
|
||
// const canvas = res[0].node;
|
||
// const ctx = canvas.getContext('2d');
|
||
// this.canvas = canvas;
|
||
// this.ctx = ctx;
|
||
|
||
// const textDrawService = new TextDrawServiceV3(canvas, ctx);
|
||
// textDrawService.draw();
|
||
|
||
// this.setCanvasSize(canvas, ctx);
|
||
// ctx.fillRect(0, 0, 2480, 3508);
|
||
// this.drawGameBoard(ctx);
|
||
});
|
||
},
|
||
|
||
setCanvasSize(canvas: Canvas, ctx: RenderingContext) {
|
||
const A4 = {
|
||
width: 2480,
|
||
height: 3508,
|
||
};
|
||
const { pixelRatio: dpr, windowWidth, windowHeight } = wx.getWindowInfo();
|
||
// const printWidth = A4.width;
|
||
// const printHeight = A4.height;
|
||
// @ts-ignore
|
||
const originWidth = canvas._width || windowWidth;
|
||
// @ts-ignore
|
||
const originHeight = canvas._height || windowHeight;
|
||
|
||
console.log('originWidth---:', originWidth);
|
||
console.log('originHeight---:', originHeight);
|
||
|
||
canvas.width = A4.width;
|
||
canvas.height = A4.height;
|
||
console.log('canvas----:', canvas);
|
||
|
||
// 计算显示比例
|
||
// const scaleRatio = Math.min(originWidth / printWidth, originHeight / printHeight);
|
||
// console.log('scaleRatio---:', scaleRatio);
|
||
// console.log('dpr---:', dpr);
|
||
// 设置坐标系
|
||
// ctx.scale(scaleRatio * dpr, scaleRatio * dpr);
|
||
},
|
||
|
||
// 绘制完整游戏界面
|
||
drawGameBoard(ctx?: RenderingContext) {
|
||
const canvas = this.canvas as Canvas;
|
||
ctx = ctx || (this.ctx as RenderingContext);
|
||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
ctx.fillStyle = '#fff'; // 设置填充色为白色
|
||
ctx.fillRect(0, 0, 2480, 3508); // 覆盖整个A4画布
|
||
|
||
// 绘制标题
|
||
// 绘制标题并居中显示
|
||
ctx.font = 'bold 80px "Microsoft Yahei"';
|
||
ctx.fillStyle = '#333';
|
||
ctx.textAlign = 'center';
|
||
const titleX = canvas.width / 2;
|
||
const titleY = 150;
|
||
ctx.fillText('找一找 涂 色', titleX, titleY);
|
||
// 绘制颜色示例(顶部)
|
||
this.drawColorLegend(ctx, 250);
|
||
|
||
// 绘制汉字矩阵(主体)
|
||
this.drawCharacterMatrix(ctx, 600);
|
||
},
|
||
|
||
// 绘制颜色示例
|
||
drawColorLegend(ctx: RenderingContext, y: number) {
|
||
console.log('this.data:', this.data);
|
||
let x = 500;
|
||
this.data.characters.forEach((char) => {
|
||
ctx.beginPath();
|
||
ctx.arc(x, y, 50, 0, Math.PI * 2);
|
||
ctx.fillStyle = this.data.colorMap[char] as string;
|
||
ctx.fill();
|
||
ctx.strokeStyle = '#333';
|
||
ctx.lineWidth = 4;
|
||
ctx.stroke();
|
||
x += 300;
|
||
});
|
||
},
|
||
|
||
// 绘制汉字矩阵(6列x7行)
|
||
drawCharacterMatrix(ctx: RenderingContext, startY: number) {
|
||
const cols = 6;
|
||
const cellSize = 350; // 每个单元格大小
|
||
const colorMap = this.data.colorMap;
|
||
|
||
this.data.matrix.forEach((char: string, index) => {
|
||
char = char || '';
|
||
const row = Math.floor(index / cols);
|
||
const col = index % cols;
|
||
|
||
// 计算坐标
|
||
const x = 300 + col * cellSize;
|
||
const y = startY + row * cellSize;
|
||
|
||
// 绘制圆形
|
||
ctx.beginPath();
|
||
ctx.arc(x, y, 120, 0, Math.PI * 2);
|
||
ctx.fillStyle = '#fff';
|
||
ctx.fill();
|
||
ctx.strokeStyle = '#333';
|
||
ctx.lineWidth = 4;
|
||
ctx.stroke();
|
||
|
||
// 绘制汉字
|
||
ctx.font = 'bold 100px "Microsoft Yahei"';
|
||
ctx.fillStyle = (colorMap[char] as string) || '';
|
||
ctx.textAlign = 'center';
|
||
ctx.textBaseline = 'middle';
|
||
ctx.fillText(char, x, y);
|
||
});
|
||
},
|
||
|
||
// 点击颜色选择
|
||
handleColorSelect(e: WechatMiniprogram.TouchEvent) {
|
||
const index = e.currentTarget.dataset.index;
|
||
const selectedChar = this.data.characters[index];
|
||
this.setData({
|
||
selectedColor: this.data.colorMap[selectedChar],
|
||
selectedChar,
|
||
});
|
||
},
|
||
|
||
// 点击汉字涂色
|
||
handleCharacterTap(e: WechatMiniprogram.TouchEvent) {
|
||
const index = e.currentTarget.dataset.index;
|
||
if (!this.data.selectedColor) return;
|
||
|
||
const matrix = this.data.matrix.map((char, i) =>
|
||
i === index ? this.data.selectedChar : char,
|
||
);
|
||
|
||
this.setData({ matrix }, () => {
|
||
this.drawGameBoard();
|
||
});
|
||
},
|
||
|
||
// 导出A4图片
|
||
exportToPrint() {
|
||
console.log('this.canvas:', this.canvas);
|
||
if (this.canvas) {
|
||
wx.canvasToTempFilePath({
|
||
canvas: this.canvas,
|
||
fileType: 'png',
|
||
quality: 1,
|
||
success: (res) => {
|
||
wx.getImageInfo({
|
||
src: res.tempFilePath,
|
||
success: (res) =>
|
||
console.log('getImageInfo image size :', res.width, res.height), // 应输出2480x3508
|
||
});
|
||
wx.saveImageToPhotosAlbum({
|
||
filePath: res.tempFilePath,
|
||
success: () => wx.showToast({ title: '保存成功' }),
|
||
});
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
},
|
||
});
|