Files
doodle-mini/miniprogram/demoPages/textPaint2/textPaint.ts
T
2025-03-21 17:23:53 +08:00

208 lines
6.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import TextDrawService from '../../canvasService/textDrawService';
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.generateMatrix();
this.initCanvas();
},
// 生成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行
},
// 初始化A4画布(300DPI
initCanvas() {
wx.createSelectorQuery()
.select('#textCanvas')
.fields({
node: true,
size: true,
})
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const textDrawService = new TextDrawService(canvas, ctx);
textDrawService.draw();
this.canvas = canvas;
this.ctx = ctx;
// 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;
}
},
});