feat:2.6.2 增加数字点连线、数物填写等涂色卡

This commit is contained in:
R524809
2025-12-24 14:51:17 +08:00
parent 20496c3cc8
commit 58423eb31a
16 changed files with 610 additions and 18 deletions
@@ -8,6 +8,7 @@
"toy-button": "../../ui/button/button",
"share-guide-popup": "../../components/share-guide-popup/share-guide-popup",
"math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons",
"draw-ad": "../../components/draw-ad/draw-ad"
"draw-ad": "../../components/draw-ad/draw-ad",
"math-type-selector": "../../components/math-type-selector/math-type-selector"
}
}
@@ -18,11 +18,33 @@ createMathPage({
functionId: '',
hasContent: false,
showShareDialog: false,
} as CanvasDataState,
showTypeSelector: true, // 控制是否显示类型选择器
currentMode: 'match', // 'match' 连线 或 'fill' 填写
currentModeName: '连线',
typeActions: [
{ name: '连线', value: 'match' },
{ name: '填写', value: 'fill' },
],
} as CanvasDataState & {
showTypeSelector: boolean;
currentMode: string;
currentModeName: string;
typeActions: Array<{ name: string; value: string }>;
},
onLoad(options: { id?: string }) {
onLoad(options: { id?: string; mode?: string }) {
const functionId = options.id || 'number-object-match';
this.initPageInfo(functionId, '数物对应');
const isFill = functionId === 'number-object-fill';
const currentMode = options.mode || (isFill ? 'fill' : 'match');
this.setData({
currentMode,
currentModeName: currentMode === 'fill' ? '填写' : '连线',
typeActions: [
{ name: '连线', value: 'match' },
{ name: '填写', value: 'fill' },
],
});
},
onReady() {
@@ -51,7 +73,7 @@ createMathPage({
}
try {
await this.drawService.draw(this.matchData);
await this.drawService.draw(this.matchData, this.data.currentMode);
this.setData({ hasContent: true });
} catch (error) {
console.error('绘制失败:', error);
@@ -142,4 +164,15 @@ createMathPage({
this.drawCanvas();
},
/** 选择类型 */
onSelectType(event: any) {
const { name, value } = event.detail;
this.setData({
currentMode: value,
currentModeName: name,
});
// 重新生成数据
this.onRandom();
},
});
@@ -3,4 +3,4 @@
<template
is="canvasPageTemplate"
data="{{boxWidth: boxWidth, boxHeight: boxHeight, hasTypeSelector: false, adType: 'mathDraw', disabled: !hasContent, showShareDialog: showShareDialog}}" />
data="{{boxWidth: boxWidth, boxHeight: boxHeight, hasTypeSelector: true, currentModeName: currentModeName, typeActions: typeActions, adType: 'mathDraw', disabled: !hasContent, showShareDialog: showShareDialog}}" />
@@ -43,13 +43,13 @@ class NumberObjectMatchDraw extends BaseDrawService {
/**
* 绘制数物对应内容
*/
async draw(matchData: NumberObjectMatchData) {
if (
!matchData ||
!matchData.gridImages ||
!matchData.bottomImages ||
!matchData.bottomNumbers
) {
async draw(matchData: NumberObjectMatchData, mode: string = 'match') {
if (!matchData || !matchData.gridImages || !matchData.bottomImages) {
return;
}
// 连线模式需要 bottomNumbers,填写模式不需要
if (mode === 'match' && !matchData.bottomNumbers) {
return;
}
@@ -62,6 +62,7 @@ class NumberObjectMatchDraw extends BaseDrawService {
matchData: this.matchData,
canvasWidth: this.canvasWidth,
startY: this.currentY,
mode: mode,
});
}
@@ -74,8 +75,9 @@ class NumberObjectMatchDraw extends BaseDrawService {
matchData: NumberObjectMatchData;
canvasWidth: number;
startY: number;
mode?: string; // 'match' 连线 或 'fill' 填写
}): Promise<void> {
const { canvas, ctx, matchData, canvasWidth } = params;
const { canvas, ctx, matchData, canvasWidth, mode = 'match' } = params;
let { startY } = params;
startY = startY + 25;
@@ -140,8 +142,127 @@ class NumberObjectMatchDraw extends BaseDrawService {
this.drawDashedDivider(dividerY, margin);
// ========== 绘制下面区域 ==========
if (mode === 'fill') {
// 填写模式:两行四列网格
await this.drawFillMode({
canvas,
ctx,
matchData,
canvasWidth,
dividerY,
margin,
});
} else {
// 连线模式:保持原有逻辑
await this.drawMatchMode({
canvas,
ctx,
matchData,
canvasWidth,
dividerY,
margin,
});
}
}
/**
* 绘制填写模式
*/
private async drawFillMode(params: {
canvas: WechatMiniprogram.Canvas;
ctx: RenderingContext;
matchData: NumberObjectMatchData;
canvasWidth: number;
dividerY: number;
margin: number;
}): Promise<void> {
const { canvas, ctx, matchData, canvasWidth, dividerY, margin } =
params;
const bottomStartY = dividerY + 30;
const bottomImageSize = 75; // 下面图片大小
const imagePadding = 10; // 图片内边距
const bottomBoxSize = bottomImageSize + imagePadding * 2; // 图片框大小
const gridRows = 2; // 两行
const gridCols = 4; // 四列
const cellSize = bottomBoxSize; // 格子大小
// 计算网格总宽度
const gridWidth = cellSize * gridCols;
const gridStartX = margin + (canvasWidth - margin * 2 - gridWidth) / 2; // 居中
// 绘制网格线
this.drawGridLines(
gridStartX,
bottomStartY,
cellSize,
cellSize,
gridCols,
gridRows,
);
// 第一行:绘制图片
for (let i = 0; i < matchData.bottomImages.length; i++) {
const item = matchData.bottomImages[i];
const col = i;
const boxX = gridStartX + col * cellSize;
const boxY = bottomStartY;
const imageX = boxX + imagePadding;
const imageY = boxY + imagePadding;
// 加载并绘制图片
let image: any = null;
try {
const imagePath = `/mathPages/shared/assets/${item.folder}/${item.imageIndex}.png`;
image = await getImage(canvas, imagePath);
} catch (error) {
console.error(
`加载图片失败: ${item.folder}/${item.imageIndex}`,
error,
);
continue;
}
if (image) {
// 计算图片高度(等比例缩放)
// @ts-ignore - 微信小程序图片对象有 width 和 height 属性
const scaledHeight =
(image.height / image.width) * bottomImageSize;
// 绘制图片(居中)
const drawImageX =
imageX + (bottomImageSize - bottomImageSize) / 2;
const drawImageY =
imageY + (bottomImageSize - scaledHeight) / 2;
ctx.drawImage(
image,
drawImageX,
drawImageY,
bottomImageSize,
scaledHeight,
);
}
}
// 第二行:空着,让小朋友填写数字(只绘制网格线,不绘制内容)
}
/**
* 绘制连线模式
*/
private async drawMatchMode(params: {
canvas: WechatMiniprogram.Canvas;
ctx: RenderingContext;
matchData: NumberObjectMatchData;
canvasWidth: number;
dividerY: number;
margin: number;
}): Promise<void> {
const { canvas, ctx, matchData, canvasWidth, dividerY, margin } =
params;
const bottomStartY = dividerY + 30;
const bottomImageSize = 50; // 下面图片大小
const imagePadding = 10; // 图片内边距
const bottomBoxSize = bottomImageSize + imagePadding * 2; // 图片框大小
const bottomSpacing = 40; // 图片间距
const bottomRowSpacing = 80; // 两行间距