feat:精简draw服务
This commit is contained in:
@@ -1,19 +1,27 @@
|
||||
/**
|
||||
* 加减法计算绘制服务
|
||||
*/
|
||||
|
||||
import { BaseDrawService } from '../../../service/baseDraw';
|
||||
import { drawAdditionContent } from './additionContentDraw';
|
||||
import { getImage } from '../../../utils/index';
|
||||
|
||||
/**
|
||||
* 加减法计算数据
|
||||
*/
|
||||
export interface AdditionData {
|
||||
problems: Array<{
|
||||
type: 'addition' | 'subtraction';
|
||||
left: number;
|
||||
right: number;
|
||||
result: number;
|
||||
}>;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加减法计算绘制服务
|
||||
* 组合使用基础绘制服务和内容区域绘制服务
|
||||
*/
|
||||
class AdditionDraw extends BaseDrawService {
|
||||
calculationData: {
|
||||
problems: Array<{
|
||||
type: 'addition' | 'subtraction';
|
||||
left: number;
|
||||
right: number;
|
||||
result: number;
|
||||
}>;
|
||||
} | null;
|
||||
calculationData: AdditionData | null = null;
|
||||
|
||||
constructor(
|
||||
canvas: Canvas,
|
||||
@@ -24,15 +32,11 @@ class AdditionDraw extends BaseDrawService {
|
||||
this.calculationData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制加减法计算内容
|
||||
*/
|
||||
async draw(
|
||||
calculationData: {
|
||||
problems: Array<{
|
||||
type: 'addition' | 'subtraction';
|
||||
left: number;
|
||||
right: number;
|
||||
result: number;
|
||||
}>;
|
||||
},
|
||||
calculationData: AdditionData,
|
||||
_calculationType: string = 'addition-5', // 保留参数以保持接口兼容性
|
||||
_imageType?: string, // 可选,不再使用,每个运算会随机选择图片类型
|
||||
) {
|
||||
@@ -40,21 +44,10 @@ class AdditionDraw extends BaseDrawService {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setPrintConfig();
|
||||
this.calculationData = calculationData;
|
||||
this.clear();
|
||||
this.setPaper();
|
||||
|
||||
// 绘制Header
|
||||
if (this.headerType !== 'minimal') {
|
||||
await this.drawHeader();
|
||||
} else {
|
||||
this.drawMiniHeader();
|
||||
}
|
||||
|
||||
// 绘制内容区域(加减法计算)
|
||||
this.drawDivider();
|
||||
await drawAdditionContent({
|
||||
this.prepareDraw();
|
||||
await this.drawHeaderAndDivider();
|
||||
await this.drawContent({
|
||||
canvas: this.canvas,
|
||||
ctx: this.ctx,
|
||||
problems: this.calculationData.problems,
|
||||
@@ -62,6 +55,613 @@ class AdditionDraw extends BaseDrawService {
|
||||
startY: this.currentY,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制内容区域
|
||||
*/
|
||||
private async drawContent(params: {
|
||||
canvas: WechatMiniprogram.Canvas;
|
||||
ctx: RenderingContext;
|
||||
problems: Array<{
|
||||
type: 'addition' | 'subtraction';
|
||||
left: number;
|
||||
right: number;
|
||||
result: number;
|
||||
}>;
|
||||
canvasWidth: number;
|
||||
startY: number;
|
||||
}): Promise<void> {
|
||||
const { canvas, ctx, problems, canvasWidth, startY } = params;
|
||||
|
||||
// 根据图片类型确定图片目录和最大索引
|
||||
const imageConfig = {
|
||||
'twelve-animals': {
|
||||
folder: 'twelve-animals',
|
||||
maxIndex: 12,
|
||||
},
|
||||
fruits: {
|
||||
folder: 'fruits',
|
||||
maxIndex: 22,
|
||||
},
|
||||
};
|
||||
|
||||
const leftMargin = 24;
|
||||
const rightMargin = 24;
|
||||
const itemSpacing = 140;
|
||||
// 调整左右框宽度比例:6:4 (约420:280)
|
||||
const leftBoxWidth = 334; // 左侧图片框固定宽度
|
||||
const rightBoxWidth = 196; // 右侧答案框固定宽度
|
||||
const boxHeight = 110;
|
||||
const borderRadius = 12;
|
||||
|
||||
const imageSpacing = 0; // 图片之间的间距(水平方向)
|
||||
const rowSpacing = 4; // 第一行和第二行之间的间距(垂直方向)
|
||||
const padding = 15; // 框内边距
|
||||
const startYPos = startY + 20;
|
||||
const plusSignSize = 20; // 加号大小(缩小)
|
||||
const plusSignSpacing = 15; // 加号左右间距(方便修改和调试)
|
||||
|
||||
// 计算左侧和右侧的起始X位置
|
||||
const leftBoxX = leftMargin;
|
||||
const rightBoxX = canvasWidth - rightMargin - rightBoxWidth;
|
||||
|
||||
// 为每个题目随机选择图片类型和图片索引
|
||||
const problemImageConfigs: Array<{
|
||||
type: 'twelve-animals' | 'fruits';
|
||||
imageIndex: number;
|
||||
}> = [];
|
||||
|
||||
for (let i = 0; i < problems.length; i++) {
|
||||
// 随机选择图片类型
|
||||
const imageTypes: ('twelve-animals' | 'fruits')[] = [
|
||||
'twelve-animals',
|
||||
'fruits',
|
||||
];
|
||||
const randomType =
|
||||
imageTypes[Math.floor(Math.random() * imageTypes.length)];
|
||||
const config = imageConfig[randomType];
|
||||
|
||||
// 为当前题目生成唯一的图片索引
|
||||
const availableImageIndices = Array.from(
|
||||
{ length: config.maxIndex },
|
||||
(_, i) => i + 1,
|
||||
);
|
||||
const randomIndex = Math.floor(
|
||||
Math.random() * availableImageIndices.length,
|
||||
);
|
||||
const imageIndex = availableImageIndices[randomIndex];
|
||||
|
||||
problemImageConfigs.push({
|
||||
type: randomType,
|
||||
imageIndex,
|
||||
});
|
||||
}
|
||||
|
||||
// 绘制每一行的内容
|
||||
for (let i = 0; i < problems.length; i++) {
|
||||
const problem = problems[i];
|
||||
const boxY = startYPos + i * itemSpacing;
|
||||
const imageConfigItem = problemImageConfigs[i];
|
||||
const config = imageConfig[imageConfigItem.type];
|
||||
|
||||
// 根据图片类型获取图片大小
|
||||
const imageSize = this.getImageSize(imageConfigItem.type);
|
||||
|
||||
// 加载图片
|
||||
let image: any = null;
|
||||
try {
|
||||
const imagePath = `/mathPages/assets/${config.folder}/${imageConfigItem.imageIndex}.png`;
|
||||
image = await getImage(canvas, imagePath);
|
||||
} catch (error) {
|
||||
console.error('图片加载失败:', error);
|
||||
}
|
||||
|
||||
// ========== 绘制左侧图片框 ==========
|
||||
ctx.strokeStyle = '#999';
|
||||
ctx.lineWidth = 1;
|
||||
this.drawRoundedRectInternal(
|
||||
ctx,
|
||||
leftBoxX,
|
||||
boxY,
|
||||
leftBoxWidth,
|
||||
boxHeight,
|
||||
borderRadius,
|
||||
true,
|
||||
);
|
||||
|
||||
const leftBoxCenterY = boxY + boxHeight / 2;
|
||||
const leftBoxContentX = leftBoxX + padding;
|
||||
|
||||
if (problem.type === 'addition') {
|
||||
// 加法:左侧图片 + 加号 + 右侧图片
|
||||
const leftImageCount = problem.left;
|
||||
const rightImageCount = problem.right;
|
||||
|
||||
/**
|
||||
* 根据数量计算每行最多展示的图片数
|
||||
*/
|
||||
const getMaxImagesPerRow = (count: number): number => {
|
||||
if (count <= 6) return 3;
|
||||
if (count <= 8) return 4;
|
||||
return 5; // 8-10
|
||||
};
|
||||
|
||||
const leftMaxPerRow = getMaxImagesPerRow(leftImageCount);
|
||||
const rightMaxPerRow = getMaxImagesPerRow(rightImageCount);
|
||||
const leftRows = Math.min(
|
||||
2,
|
||||
Math.ceil(leftImageCount / leftMaxPerRow),
|
||||
);
|
||||
const rightRows = Math.min(
|
||||
2,
|
||||
Math.ceil(rightImageCount / rightMaxPerRow),
|
||||
);
|
||||
|
||||
// 计算左侧图片区域的宽度和高度
|
||||
// 需要根据实际行数计算每行的最大宽度
|
||||
const leftFirstRowCount = Math.min(
|
||||
leftImageCount,
|
||||
leftMaxPerRow,
|
||||
);
|
||||
const leftSecondRowCount = Math.max(
|
||||
0,
|
||||
Math.min(leftMaxPerRow, leftImageCount - leftMaxPerRow),
|
||||
);
|
||||
const leftImagesWidth =
|
||||
Math.max(
|
||||
leftFirstRowCount * imageSize +
|
||||
(leftFirstRowCount - 1) * imageSpacing,
|
||||
leftSecondRowCount * imageSize +
|
||||
(leftSecondRowCount - 1) * imageSpacing,
|
||||
) || imageSize; // 至少为 imageSize
|
||||
|
||||
// 计算右侧图片区域的宽度和高度
|
||||
const rightFirstRowCount = Math.min(
|
||||
rightImageCount,
|
||||
rightMaxPerRow,
|
||||
);
|
||||
const rightSecondRowCount = Math.max(
|
||||
0,
|
||||
Math.min(rightMaxPerRow, rightImageCount - rightMaxPerRow),
|
||||
);
|
||||
const rightImagesWidth =
|
||||
Math.max(
|
||||
rightFirstRowCount * imageSize +
|
||||
(rightFirstRowCount - 1) * imageSpacing,
|
||||
rightSecondRowCount * imageSize +
|
||||
(rightSecondRowCount - 1) * imageSpacing,
|
||||
) || imageSize; // 至少为 imageSize
|
||||
|
||||
// 获取图片实际高度(用于垂直居中计算)
|
||||
let imageActualHeight = imageSize;
|
||||
if (image) {
|
||||
// @ts-ignore
|
||||
imageActualHeight =
|
||||
(image.height / image.width) * imageSize;
|
||||
}
|
||||
|
||||
// 计算左侧图片区域的实际高度(考虑图片的实际高度和行间距)
|
||||
const leftImagesHeight =
|
||||
leftRows * imageActualHeight + (leftRows - 1) * rowSpacing;
|
||||
// 计算右侧图片区域的实际高度
|
||||
const rightImagesHeight =
|
||||
rightRows * imageActualHeight +
|
||||
(rightRows - 1) * rowSpacing;
|
||||
|
||||
// 计算加号位置(居中,包含左右间距)
|
||||
const totalContentWidth =
|
||||
leftImagesWidth +
|
||||
plusSignSpacing +
|
||||
plusSignSize +
|
||||
plusSignSpacing +
|
||||
rightImagesWidth;
|
||||
const availableWidth = leftBoxWidth - padding * 2;
|
||||
const contentStartX =
|
||||
leftBoxContentX + (availableWidth - totalContentWidth) / 2;
|
||||
|
||||
const leftImagesStartX = contentStartX;
|
||||
// 垂直居中:使用图片实际高度计算
|
||||
const leftImagesStartY = leftBoxCenterY - leftImagesHeight / 2;
|
||||
|
||||
// 绘制左侧图片(最多两行)
|
||||
for (let j = 0; j < Math.min(leftImageCount, 10); j++) {
|
||||
const row = Math.floor(j / leftMaxPerRow);
|
||||
const col = j % leftMaxPerRow;
|
||||
|
||||
// 如果超过两行,停止绘制
|
||||
if (row >= 2) break;
|
||||
|
||||
const imagesInThisRow = Math.min(
|
||||
leftMaxPerRow,
|
||||
leftImageCount - row * leftMaxPerRow,
|
||||
);
|
||||
const rowWidth =
|
||||
imagesInThisRow * imageSize +
|
||||
(imagesInThisRow - 1) * imageSpacing;
|
||||
const rowStartX =
|
||||
leftImagesStartX + (leftImagesWidth - rowWidth) / 2;
|
||||
|
||||
const imageX = rowStartX + col * (imageSize + imageSpacing);
|
||||
// 使用图片实际高度和行间距计算垂直位置
|
||||
const imageY =
|
||||
leftImagesStartY +
|
||||
row * (imageActualHeight + rowSpacing);
|
||||
|
||||
if (image) {
|
||||
// @ts-ignore
|
||||
const scaledHeight =
|
||||
(image.height / image.width) * imageSize;
|
||||
ctx.drawImage(
|
||||
image,
|
||||
imageX,
|
||||
imageY,
|
||||
imageSize,
|
||||
scaledHeight,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制加号(左右有间距)
|
||||
const plusX =
|
||||
leftImagesStartX +
|
||||
leftImagesWidth +
|
||||
plusSignSpacing +
|
||||
plusSignSize / 2;
|
||||
const plusY = leftBoxCenterY;
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
// 横线
|
||||
ctx.moveTo(plusX - plusSignSize / 2, plusY);
|
||||
ctx.lineTo(plusX + plusSignSize / 2, plusY);
|
||||
// 竖线
|
||||
ctx.moveTo(plusX, plusY - plusSignSize / 2);
|
||||
ctx.lineTo(plusX, plusY + plusSignSize / 2);
|
||||
ctx.stroke();
|
||||
|
||||
const rightImagesStartX =
|
||||
plusX + plusSignSize / 2 + plusSignSpacing;
|
||||
// 垂直居中:使用图片实际高度计算
|
||||
const rightImagesStartY =
|
||||
leftBoxCenterY - rightImagesHeight / 2;
|
||||
|
||||
// 绘制右侧图片(最多两行)
|
||||
for (let j = 0; j < Math.min(rightImageCount, 10); j++) {
|
||||
const row = Math.floor(j / rightMaxPerRow);
|
||||
const col = j % rightMaxPerRow;
|
||||
|
||||
// 如果超过两行,停止绘制
|
||||
if (row >= 2) break;
|
||||
|
||||
const imagesInThisRow = Math.min(
|
||||
rightMaxPerRow,
|
||||
rightImageCount - row * rightMaxPerRow,
|
||||
);
|
||||
const rowWidth =
|
||||
imagesInThisRow * imageSize +
|
||||
(imagesInThisRow - 1) * imageSpacing;
|
||||
const rowStartX =
|
||||
rightImagesStartX + (rightImagesWidth - rowWidth) / 2;
|
||||
|
||||
const imageX = rowStartX + col * (imageSize + imageSpacing);
|
||||
// 使用图片实际高度和行间距计算垂直位置
|
||||
const imageY =
|
||||
rightImagesStartY +
|
||||
row * (imageActualHeight + rowSpacing);
|
||||
|
||||
if (image) {
|
||||
// @ts-ignore
|
||||
const scaledHeight =
|
||||
(image.height / image.width) * imageSize;
|
||||
ctx.drawImage(
|
||||
image,
|
||||
imageX,
|
||||
imageY,
|
||||
imageSize,
|
||||
scaledHeight,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 减法:展示总数量的图片,后几个加划线
|
||||
const totalCount = problem.left; // 总数
|
||||
const subtractCount = problem.right; // 要减去的数量
|
||||
|
||||
// 获取图片实际高度(用于垂直居中计算)
|
||||
let imageActualHeight = imageSize;
|
||||
if (image) {
|
||||
// @ts-ignore
|
||||
imageActualHeight =
|
||||
(image.height / image.width) * imageSize;
|
||||
}
|
||||
|
||||
// 计算图片布局
|
||||
const imagesPerRow = 5;
|
||||
const totalRows = Math.ceil(totalCount / imagesPerRow);
|
||||
// 使用图片实际高度和行间距计算总高度
|
||||
const totalHeight =
|
||||
totalRows * imageActualHeight +
|
||||
(totalRows - 1) * rowSpacing;
|
||||
const imagesStartY = leftBoxCenterY - totalHeight / 2;
|
||||
|
||||
// 绘制所有图片
|
||||
for (let j = 0; j < totalCount; j++) {
|
||||
const row = Math.floor(j / imagesPerRow);
|
||||
const col = j % imagesPerRow;
|
||||
const imagesInThisRow = Math.min(
|
||||
imagesPerRow,
|
||||
totalCount - row * imagesPerRow,
|
||||
);
|
||||
const rowWidth =
|
||||
imagesInThisRow * imageSize +
|
||||
(imagesInThisRow - 1) * imageSpacing;
|
||||
const rowStartX =
|
||||
leftBoxContentX +
|
||||
(leftBoxWidth - padding * 2 - rowWidth) / 2;
|
||||
|
||||
const imageX = rowStartX + col * (imageSize + imageSpacing);
|
||||
// 使用图片实际高度和行间距计算垂直位置
|
||||
const imageY =
|
||||
imagesStartY + row * (imageActualHeight + rowSpacing);
|
||||
|
||||
if (image) {
|
||||
// @ts-ignore
|
||||
const scaledHeight =
|
||||
(image.height / image.width) * imageSize;
|
||||
ctx.drawImage(
|
||||
image,
|
||||
imageX,
|
||||
imageY,
|
||||
imageSize,
|
||||
scaledHeight,
|
||||
);
|
||||
|
||||
// 如果是后几个图片,绘制虚线删除线(表示减去)
|
||||
if (j >= totalCount - subtractCount) {
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.setLineDash([4, 3]); // 设置虚线样式
|
||||
ctx.beginPath();
|
||||
// 绘制第一条虚线对角线(从左上到右下)
|
||||
ctx.moveTo(imageX, imageY);
|
||||
ctx.lineTo(
|
||||
imageX + imageSize,
|
||||
imageY + scaledHeight,
|
||||
);
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]); // 重置为实线,防止影响后续绘制
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 绘制右侧答案框 ==========
|
||||
this.drawAnswerBoxArea(ctx, {
|
||||
rightBoxX,
|
||||
boxY,
|
||||
rightBoxWidth,
|
||||
borderRadius,
|
||||
boxHeight,
|
||||
padding,
|
||||
problemType: problem.type,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制圆角矩形(虚线或实线边框)
|
||||
*/
|
||||
private drawRoundedRectInternal(
|
||||
ctx: RenderingContext,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
radius: number,
|
||||
isDashed: boolean = true,
|
||||
) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + radius, y);
|
||||
ctx.lineTo(x + width - radius, y);
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
||||
ctx.lineTo(x + width, y + height - radius);
|
||||
ctx.quadraticCurveTo(
|
||||
x + width,
|
||||
y + height,
|
||||
x + width - radius,
|
||||
y + height,
|
||||
);
|
||||
ctx.lineTo(x + radius, y + height);
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
||||
ctx.lineTo(x, y + radius);
|
||||
ctx.quadraticCurveTo(x, y, x + radius, y);
|
||||
ctx.closePath();
|
||||
|
||||
if (isDashed) {
|
||||
ctx.setLineDash([2, 2]); // 虚线
|
||||
} else {
|
||||
ctx.setLineDash([]); // 实线
|
||||
}
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]); // 重置为实线
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制实线圆角方框(用于填写答案)
|
||||
*/
|
||||
private drawAnswerBox(
|
||||
ctx: RenderingContext,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
) {
|
||||
const radius = 6; // 圆角大小
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.setLineDash([]); // 实线
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x + radius, y);
|
||||
ctx.lineTo(x + width - radius, y);
|
||||
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
|
||||
ctx.lineTo(x + width, y + height - radius);
|
||||
ctx.quadraticCurveTo(
|
||||
x + width,
|
||||
y + height,
|
||||
x + width - radius,
|
||||
y + height,
|
||||
);
|
||||
ctx.lineTo(x + radius, y + height);
|
||||
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
|
||||
ctx.lineTo(x, y + radius);
|
||||
ctx.quadraticCurveTo(x, y, x + radius, y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制右侧答案框
|
||||
*/
|
||||
private drawAnswerBoxArea(
|
||||
ctx: RenderingContext,
|
||||
params: {
|
||||
rightBoxX: number;
|
||||
boxY: number;
|
||||
rightBoxWidth: number;
|
||||
borderRadius: number;
|
||||
boxHeight: number;
|
||||
padding: number;
|
||||
problemType: 'addition' | 'subtraction';
|
||||
},
|
||||
) {
|
||||
const {
|
||||
rightBoxX,
|
||||
boxY,
|
||||
rightBoxWidth,
|
||||
borderRadius,
|
||||
boxHeight,
|
||||
padding,
|
||||
problemType,
|
||||
} = params;
|
||||
|
||||
const plusSignSize = 18; // 加号大小(缩小)
|
||||
const minusSignSize = 18; // 减号大小(缩小)
|
||||
const equalsSignSize = 18; // 等号大小(缩小)
|
||||
const spacing = 8; // 加号左右间距(方便修改和调试)
|
||||
const answerBoxWidth = 34; // 答案框宽度
|
||||
const answerBoxHeight = 34; // 答案框高度
|
||||
|
||||
// 绘制右侧答案框边框
|
||||
ctx.strokeStyle = '#999';
|
||||
ctx.lineWidth = 1;
|
||||
this.drawRoundedRectInternal(
|
||||
ctx,
|
||||
rightBoxX,
|
||||
boxY,
|
||||
rightBoxWidth,
|
||||
boxHeight,
|
||||
borderRadius,
|
||||
true,
|
||||
);
|
||||
|
||||
const rightBoxCenterY = boxY + boxHeight / 2;
|
||||
const rightBoxAvailableWidth = rightBoxWidth - padding * 2;
|
||||
const answerStartY = rightBoxCenterY - answerBoxHeight / 2;
|
||||
|
||||
// 根据问题类型确定运算符号大小
|
||||
const operatorSignSize =
|
||||
problemType === 'addition' ? plusSignSize : minusSignSize;
|
||||
|
||||
// 计算总宽度并水平居中(加法和减法逻辑相同)
|
||||
const totalAnswerWidth =
|
||||
answerBoxWidth +
|
||||
spacing +
|
||||
operatorSignSize +
|
||||
spacing +
|
||||
answerBoxWidth +
|
||||
spacing +
|
||||
equalsSignSize +
|
||||
spacing +
|
||||
answerBoxWidth;
|
||||
const answerStartX =
|
||||
rightBoxX +
|
||||
padding +
|
||||
(rightBoxAvailableWidth - totalAnswerWidth) / 2;
|
||||
|
||||
// 计算各个元素的位置
|
||||
const box1X = answerStartX;
|
||||
const operatorX = box1X + answerBoxWidth + spacing;
|
||||
const box2X = operatorX + plusSignSize + spacing;
|
||||
const equalsX = box2X + answerBoxWidth + spacing;
|
||||
const box3X = equalsX + equalsSignSize + spacing;
|
||||
|
||||
// 绘制第一个方框(圆角)
|
||||
this.drawAnswerBox(
|
||||
ctx,
|
||||
box1X,
|
||||
answerStartY,
|
||||
answerBoxWidth,
|
||||
answerBoxHeight,
|
||||
);
|
||||
|
||||
// 绘制运算符号(加号或减号)
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
if (problemType === 'addition') {
|
||||
// 加号:横线和竖线
|
||||
ctx.moveTo(operatorX, rightBoxCenterY);
|
||||
ctx.lineTo(operatorX + operatorSignSize, rightBoxCenterY);
|
||||
ctx.moveTo(
|
||||
operatorX + operatorSignSize / 2,
|
||||
rightBoxCenterY - operatorSignSize / 2,
|
||||
);
|
||||
ctx.lineTo(
|
||||
operatorX + operatorSignSize / 2,
|
||||
rightBoxCenterY + operatorSignSize / 2,
|
||||
);
|
||||
} else {
|
||||
// 减号:只有横线
|
||||
ctx.moveTo(operatorX, rightBoxCenterY);
|
||||
ctx.lineTo(operatorX + operatorSignSize, rightBoxCenterY);
|
||||
}
|
||||
ctx.stroke();
|
||||
|
||||
// 绘制第二个方框(圆角)
|
||||
this.drawAnswerBox(
|
||||
ctx,
|
||||
box2X,
|
||||
answerStartY,
|
||||
answerBoxWidth,
|
||||
answerBoxHeight,
|
||||
);
|
||||
|
||||
// 绘制等号(缩短)
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 2;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(equalsX, rightBoxCenterY - 3);
|
||||
ctx.lineTo(equalsX + equalsSignSize, rightBoxCenterY - 3);
|
||||
ctx.moveTo(equalsX, rightBoxCenterY + 3);
|
||||
ctx.lineTo(equalsX + equalsSignSize, rightBoxCenterY + 3);
|
||||
ctx.stroke();
|
||||
|
||||
// 绘制第三个方框(答案,圆角)
|
||||
this.drawAnswerBox(
|
||||
ctx,
|
||||
box3X,
|
||||
answerStartY,
|
||||
answerBoxWidth,
|
||||
answerBoxHeight,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据图片类型设置图片大小
|
||||
*/
|
||||
private getImageSize(imageType: 'twelve-animals' | 'fruits'): number {
|
||||
return imageType === 'twelve-animals' ? 40 : 36;
|
||||
}
|
||||
}
|
||||
|
||||
export default AdditionDraw;
|
||||
|
||||
Reference in New Issue
Block a user