139 lines
3.8 KiB
TypeScript
139 lines
3.8 KiB
TypeScript
import { getImage } from '../../../utils/index';
|
||
|
||
/**
|
||
* 数字到英文单词的映射
|
||
*/
|
||
const NUMBER_WORDS: Record<number, string> = {
|
||
1: 'one',
|
||
2: 'two',
|
||
3: 'three',
|
||
4: 'four',
|
||
5: 'five',
|
||
6: 'six',
|
||
7: 'seven',
|
||
8: 'eight',
|
||
9: 'nine',
|
||
10: 'ten',
|
||
};
|
||
|
||
const NUMBER_COLORS: Record<number, string> = {
|
||
1: '#9FC558',
|
||
2: '#CDB984',
|
||
3: '#B393B8',
|
||
4: '#ED7E97',
|
||
5: '#53B5B9',
|
||
6: '#B3B3B3',
|
||
7: '#EE8B7A',
|
||
8: '#F6C644',
|
||
9: '#99C1F4',
|
||
10: '#F5D25C',
|
||
};
|
||
|
||
/**
|
||
* 绘制预览区域的参数接口
|
||
*/
|
||
interface DrawNumberPreviewParams {
|
||
canvas: WechatMiniprogram.Canvas;
|
||
ctx: RenderingContext;
|
||
selectedNumber: number;
|
||
canvasWidth: number; // 逻辑像素宽度(已除以3)
|
||
startY: number; // 起始Y坐标
|
||
onDrawn?: (currentY: number) => void; // 绘制完成后的回调
|
||
}
|
||
|
||
/**
|
||
* 绘制数字预览区域服务
|
||
* 左侧:animal-number 图片
|
||
* 右侧:两个框,第一个框是finger图片,第二个框是英文单词
|
||
* 所有尺寸除以3
|
||
*/
|
||
export async function drawNumberPreview({
|
||
canvas,
|
||
ctx,
|
||
selectedNumber,
|
||
canvasWidth,
|
||
startY,
|
||
onDrawn,
|
||
}: DrawNumberPreviewParams): Promise<void> {
|
||
// 左侧 animal-number 图片位置
|
||
const animalImageWidth = 360;
|
||
const animalImageHeight = 236;
|
||
const leftMargin = 35;
|
||
const animalImageX = leftMargin;
|
||
const animalImageY = startY + 10;
|
||
|
||
// 加载并绘制 animal-number 图片
|
||
try {
|
||
const animalImagePath = `/mathPages/assets/animal-number/animal-number-${selectedNumber}.png`;
|
||
const animalImage = await getImage(canvas, animalImagePath);
|
||
ctx.drawImage(
|
||
animalImage,
|
||
animalImageX,
|
||
animalImageY,
|
||
animalImageWidth,
|
||
animalImageHeight,
|
||
);
|
||
} catch (error) {
|
||
console.error('加载animal-number图片失败:', error);
|
||
}
|
||
|
||
// 右侧两个框的位置(逻辑像素,除以3)
|
||
const boxWidth = 130;
|
||
const boxHeight = 100;
|
||
const rightMargin = 35;
|
||
const boxSpacing = 30;
|
||
const boxX = canvasWidth - rightMargin - boxWidth;
|
||
|
||
// 第一个框:finger 图片
|
||
const fingerBoxY = animalImageY;
|
||
ctx.strokeStyle = '#000';
|
||
ctx.lineWidth = 1;
|
||
ctx.strokeRect(boxX, fingerBoxY, boxWidth, boxHeight);
|
||
|
||
try {
|
||
const fingerImagePath = `/mathPages/assets/finger/finger-${selectedNumber}.png`;
|
||
const fingerImage = await getImage(canvas, fingerImagePath);
|
||
// 计算图片在框内的位置(居中显示)
|
||
const imagePadding = 10;
|
||
const imageWidth = boxWidth - imagePadding * 2;
|
||
const imageHeight = boxHeight - imagePadding * 2;
|
||
ctx.drawImage(
|
||
fingerImage,
|
||
boxX + imagePadding,
|
||
fingerBoxY + imagePadding,
|
||
imageWidth,
|
||
imageHeight,
|
||
);
|
||
} catch (error) {
|
||
console.error('加载finger图片失败:', error);
|
||
}
|
||
|
||
// 第二个框:英文单词
|
||
const wordBoxY = fingerBoxY + boxHeight + boxSpacing;
|
||
ctx.strokeRect(boxX, wordBoxY, boxWidth, boxHeight);
|
||
|
||
// 绘制英文单词(字体大小除以3)
|
||
const word = NUMBER_WORDS[selectedNumber] || '';
|
||
const color = NUMBER_COLORS[selectedNumber] || '#000';
|
||
ctx.fillStyle = color;
|
||
// 推荐使用系统内常见的圆体或幼圆体字体,更适合儿童视觉风格
|
||
ctx.font =
|
||
'bold 32px "HarmonyOS Sans", "PingFang SC", "YouYuan", "Microsoft Yahei", sans-serif';
|
||
ctx.textAlign = 'center';
|
||
ctx.textBaseline = 'middle';
|
||
ctx.fillText(
|
||
word,
|
||
boxX + boxWidth / 2,
|
||
wordBoxY + boxHeight / 2,
|
||
boxWidth - 20,
|
||
);
|
||
|
||
// 更新 currentY 为预览区域底部
|
||
const finalY =
|
||
Math.max(animalImageY + animalImageHeight, wordBoxY + boxHeight) + 10;
|
||
|
||
if (onDrawn) {
|
||
onDrawn(finalY);
|
||
}
|
||
}
|