Files
doodle-mini/miniprogram/demoPages/textPaint2/textPaint.ts
T

284 lines
9.8 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';
// 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;
}
},
});