feat: 初始化页面
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"navigationBarTitleText": "文本绘制 示例",
|
||||
"navigationBarBackgroundColor": "#798154",
|
||||
"homeButton": false,
|
||||
"backgroundColorContent": "#ffffff00",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
.color-picker {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.color-circle {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
margin: 0 40rpx;
|
||||
border: 4rpx solid #333;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
width: 60%;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
margin: 40rpx auto;
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
Page({
|
||||
canvas: null as WechatMiniprogram.Canvas | null,
|
||||
ctx: null as CanvasRenderingContext2D | null,
|
||||
data: {
|
||||
characters: ['鱼', '鸟', '牛', '羊'] as const, // 固定汉字类型
|
||||
colorMap: new Map([
|
||||
// 颜色映射关系
|
||||
['鱼', '#2196F3'], // 蓝色
|
||||
['鸟', '#FFEB3B'], // 黄色
|
||||
['牛', '#FF9800'], // 橙色
|
||||
['羊', '#9C27B0'], // 紫色
|
||||
]),
|
||||
matrix: [] as string[], // 随机汉字矩阵
|
||||
selectedColor: '', // 当前选中颜色
|
||||
selectedChar: '', // 当前选中汉字
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.generateMatrix();
|
||||
},
|
||||
|
||||
// 生成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() {
|
||||
const dpi = 300;
|
||||
const width = 2480,
|
||||
height = 3508; // A4精确像素
|
||||
|
||||
wx.createSelectorQuery()
|
||||
.select('#canvas')
|
||||
.node()
|
||||
.exec((res) => {
|
||||
const canvas = res[0].node;
|
||||
this.canvas = canvas;
|
||||
const ctx = canvas.getContext('2d');
|
||||
this.ctx = ctx;
|
||||
|
||||
// 设置物理尺寸
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
// 适配屏幕显示
|
||||
const ratio = wx.getWindowInfo().pixelRatio;
|
||||
canvas.style.width = `${width / ratio}px`;
|
||||
ctx.scale(ratio, ratio);
|
||||
|
||||
this.drawGameBoard(ctx);
|
||||
});
|
||||
},
|
||||
|
||||
// 绘制完整游戏界面
|
||||
drawGameBoard(ctx?: CanvasRenderingContext2D) {
|
||||
ctx = ctx || (this.ctx as CanvasRenderingContext2D);
|
||||
ctx.clearRect(0, 0, 2480, 3508);
|
||||
|
||||
// 绘制标题
|
||||
ctx.font = 'bold 80px "Microsoft Yahei"';
|
||||
ctx.fillStyle = '#333';
|
||||
ctx.fillText('找一找 涂 色', 1240 - ctx.measureText('找一找 涂 色').width / 2, 150);
|
||||
|
||||
// 绘制颜色示例(顶部)
|
||||
this.drawColorLegend(ctx, 250);
|
||||
|
||||
// 绘制汉字矩阵(主体)
|
||||
this.drawCharacterMatrix(ctx, 600);
|
||||
},
|
||||
|
||||
// 绘制颜色示例
|
||||
drawColorLegend(ctx: CanvasRenderingContext2D, y: number) {
|
||||
let x = 500;
|
||||
this.data.characters.forEach((char) => {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 50, 0, Math.PI * 2);
|
||||
ctx.fillStyle = this.data.colorMap.get(char) as string;
|
||||
ctx.fill();
|
||||
ctx.strokeStyle = '#333';
|
||||
ctx.lineWidth = 4;
|
||||
ctx.stroke();
|
||||
x += 300;
|
||||
});
|
||||
},
|
||||
|
||||
// 绘制汉字矩阵(6列x7行)
|
||||
drawCharacterMatrix(ctx: CanvasRenderingContext2D, startY: number) {
|
||||
const cols = 6;
|
||||
const cellSize = 350; // 每个单元格大小
|
||||
|
||||
this.data.matrix.forEach((char, index) => {
|
||||
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 = this.data.colorMap.get(char) || '';
|
||||
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.get(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() {
|
||||
if (this.canvas) {
|
||||
wx.canvasToTempFilePath({
|
||||
canvas: this.canvas,
|
||||
fileType: 'png',
|
||||
quality: 1,
|
||||
success: (res) => {
|
||||
wx.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => wx.showToast({ title: '保存成功' }),
|
||||
});
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
<view class="container">
|
||||
<!-- 颜色选择区 -->
|
||||
<view class="color-picker">
|
||||
<block wx:for="{{characters}}" wx:key="index">
|
||||
<view
|
||||
class="color-circle"
|
||||
style="background: {{colorMap.get(item)}}"
|
||||
bindtap="handleColorSelect"
|
||||
data-index="{{index}}"></view>
|
||||
</block>
|
||||
</view>
|
||||
|
||||
<!-- 画布容器 -->
|
||||
<canvas type="2d" id="canvas" style="width: 100%; height: 80vh" />
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<button class="action-btn" bindtap="exportToPrint">导出A4图片</button>
|
||||
</view>
|
||||
Reference in New Issue
Block a user