feat: 初始化页面

This commit is contained in:
zhangyi
2025-03-18 15:17:30 +08:00
parent e4e9f6d527
commit cdf57ee562
477 changed files with 12379 additions and 0 deletions
@@ -0,0 +1,13 @@
.page-container {
height: 100vh;
background-color: transparent;
overflow-y: hidden;
.text-canvas {
margin: 20rpx 20rpx 60rpx;
width: calc(100% - 40rpx);
height: calc(100% - 80rpx);
border: 1rpx solid #333;
background-color: #fff;
}
}
@@ -0,0 +1,95 @@
Page({
canvas: null as WechatMiniprogram.Canvas | null,
ctx: null as CanvasRenderingContext2D | null,
data: {
showModal: false,
texts: ['', '', '', ''],
},
onReady: function () {
this.initCanvas();
},
initCanvas() {
const query = wx.createSelectorQuery();
query
.select('#textCanvas')
.fields({ node: true, size: true })
.exec((res) => {
console.log('res----:', res);
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
this.canvas = canvas;
this.ctx = ctx;
const dpi = 300; // 明确声明 DPI
const mmToInch = 25.4;
const width = (210 / mmToInch) * dpi; // 2480px
const height = (297 / mmToInch) * dpi; // 3508px
const pixelRatio = wx.getWindowInfo().pixelRatio;
// 设置画布实际像素为 A4 尺寸
canvas.width = width;
canvas.height = height;
// 适配屏幕显示(非必须,仅用于预览)
canvas.style = canvas.style || {};
canvas.style.width = `${width / pixelRatio}px`;
canvas.style.height = `${height / pixelRatio}px`;
// 缩放上下文以适配高清屏
ctx.scale(pixelRatio, pixelRatio);
this.drawCircles();
});
},
setCanvasSize() {},
drawCircles: function () {
if (!this.canvas) {
return;
}
const ctx = this.ctx as CanvasRenderingContext2D;
const { texts } = this.data;
// 清空画布
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// 绘制4个圆圈
for (let i = 0; i < 4; i++) {
const x = 50 + i * 100;
const y = 50;
ctx.beginPath();
ctx.arc(x, y, 40, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
ctx.strokeStyle = 'black';
ctx.stroke();
if (texts[i]) {
ctx.fillStyle = 'black';
ctx.font = '20px sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(texts[i], x, y);
}
}
},
showInput: function () {
this.setData({ showModal: true });
},
updateText: function (e: WechatMiniprogram.CustomEvent) {
const index = e.currentTarget.dataset.index;
const value = e.detail.value;
const { texts } = this.data;
texts[index] = value;
this.setData({ texts });
},
confirmInput: function () {
this.setData({ showModal: false });
this.drawCircles();
},
});
@@ -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>