feat: 格子仿画修改
This commit is contained in:
@@ -6,13 +6,27 @@
|
||||
import { BaseDrawService } from '../../../service/baseDraw';
|
||||
import { GridCell, GridConfig } from '../types/gridTypes';
|
||||
|
||||
/**
|
||||
* 格子组数据(一组包含一个填充的网格和一个空的网格)
|
||||
*/
|
||||
export interface GridGroup {
|
||||
/** 填充的格子数据 */
|
||||
filledCells: GridCell[];
|
||||
/** 空的格子(用于仿画) */
|
||||
emptyCells: GridCell[]; // 始终为空数组,仅用于标识
|
||||
}
|
||||
|
||||
/**
|
||||
* 格子仿画数据
|
||||
*/
|
||||
export interface GridDrawingData {
|
||||
config: GridConfig;
|
||||
cells: GridCell[];
|
||||
name?: string;
|
||||
/** 格子组数组,每组包含一个填充的网格和一个空的网格 */
|
||||
groups: GridGroup[];
|
||||
/** 每行展示的组数 */
|
||||
groupsPerRow: number;
|
||||
/** 总行数 */
|
||||
totalRows: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -33,7 +47,7 @@ class GridDraw extends BaseDrawService {
|
||||
* 绘制格子仿画内容
|
||||
*/
|
||||
async draw(gridData: GridDrawingData) {
|
||||
if (!gridData || !gridData.cells) {
|
||||
if (!gridData || !gridData.groups || gridData.groups.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -71,19 +85,139 @@ class GridDraw extends BaseDrawService {
|
||||
startY: number;
|
||||
}): Promise<void> {
|
||||
const { ctx, gridData, canvasWidth, startY } = params;
|
||||
const { config, cells } = gridData;
|
||||
const { config, groups, groupsPerRow, totalRows } = gridData;
|
||||
const { rows, cols } = config;
|
||||
|
||||
// 计算网格尺寸
|
||||
const margin = 40; // 左右边距
|
||||
const groupSpacing = 20; // 组之间的间距
|
||||
const rowSpacing = 30; // 行之间的间距
|
||||
const dividerWidth = 2; // 分割线宽度
|
||||
|
||||
// 计算每组网格的尺寸
|
||||
const availableWidth = canvasWidth - margin * 2;
|
||||
const cellSize = Math.floor(availableWidth / cols);
|
||||
const totalGroupsPerRow = groupsPerRow * 2; // 每组包含填充和空两个网格
|
||||
const groupWidth =
|
||||
(availableWidth -
|
||||
(groupsPerRow - 1) * dividerWidth -
|
||||
(totalGroupsPerRow - 1) * groupSpacing) /
|
||||
totalGroupsPerRow;
|
||||
const cellSize = Math.floor(groupWidth / cols);
|
||||
const gridWidth = cellSize * cols;
|
||||
const gridHeight = cellSize * rows;
|
||||
|
||||
// 计算网格起始位置(居中)
|
||||
const gridStartX = margin + (availableWidth - gridWidth) / 2;
|
||||
const gridStartY = startY + 30; // 顶部间距
|
||||
let currentY = startY + 30; // 顶部间距
|
||||
|
||||
// 遍历每一行
|
||||
for (let rowIndex = 0; rowIndex < totalRows; rowIndex++) {
|
||||
const rowStartIndex = rowIndex * groupsPerRow;
|
||||
const rowGroups = groups.slice(
|
||||
rowStartIndex,
|
||||
rowStartIndex + groupsPerRow,
|
||||
);
|
||||
|
||||
// 计算当前行的起始X位置(居中)
|
||||
const rowTotalWidth =
|
||||
totalGroupsPerRow * gridWidth +
|
||||
(totalGroupsPerRow - 1) * groupSpacing +
|
||||
(groupsPerRow - 1) * dividerWidth;
|
||||
const rowStartX = margin + (availableWidth - rowTotalWidth) / 2;
|
||||
|
||||
let currentX = rowStartX;
|
||||
|
||||
// 遍历当前行的每一组
|
||||
for (
|
||||
let groupIndex = 0;
|
||||
groupIndex < rowGroups.length;
|
||||
groupIndex++
|
||||
) {
|
||||
const group = rowGroups[groupIndex];
|
||||
|
||||
// 绘制填充的网格(左侧)
|
||||
this.drawSingleGrid({
|
||||
ctx,
|
||||
gridStartX: currentX,
|
||||
gridStartY: currentY,
|
||||
gridWidth,
|
||||
gridHeight,
|
||||
cellSize,
|
||||
rows,
|
||||
cols,
|
||||
cells: group.filledCells,
|
||||
config,
|
||||
});
|
||||
|
||||
currentX += gridWidth + groupSpacing;
|
||||
|
||||
// 绘制空的网格(右侧)
|
||||
this.drawSingleGrid({
|
||||
ctx,
|
||||
gridStartX: currentX,
|
||||
gridStartY: currentY,
|
||||
gridWidth,
|
||||
gridHeight,
|
||||
cellSize,
|
||||
rows,
|
||||
cols,
|
||||
cells: [], // 空网格
|
||||
config,
|
||||
});
|
||||
|
||||
currentX += gridWidth;
|
||||
|
||||
// 如果不是最后一组,绘制垂直分割线
|
||||
if (groupIndex < rowGroups.length - 1) {
|
||||
ctx.strokeStyle = '#000000';
|
||||
ctx.lineWidth = dividerWidth;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(currentX, currentY);
|
||||
ctx.lineTo(currentX, currentY + gridHeight);
|
||||
ctx.stroke();
|
||||
currentX += dividerWidth;
|
||||
}
|
||||
}
|
||||
|
||||
currentY += gridHeight + rowSpacing;
|
||||
|
||||
// 如果不是最后一行,绘制水平分割线
|
||||
if (rowIndex < totalRows - 1) {
|
||||
ctx.strokeStyle = '#000000';
|
||||
ctx.lineWidth = dividerWidth;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(margin, currentY - rowSpacing / 2);
|
||||
ctx.lineTo(canvasWidth - margin, currentY - rowSpacing / 2);
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制单个网格
|
||||
*/
|
||||
private drawSingleGrid(params: {
|
||||
ctx: RenderingContext;
|
||||
gridStartX: number;
|
||||
gridStartY: number;
|
||||
gridWidth: number;
|
||||
gridHeight: number;
|
||||
cellSize: number;
|
||||
rows: number;
|
||||
cols: number;
|
||||
cells: GridCell[];
|
||||
config: GridConfig;
|
||||
}): void {
|
||||
const {
|
||||
ctx,
|
||||
gridStartX,
|
||||
gridStartY,
|
||||
gridWidth,
|
||||
gridHeight,
|
||||
cellSize,
|
||||
rows,
|
||||
cols,
|
||||
cells,
|
||||
config,
|
||||
} = params;
|
||||
|
||||
// 绘制网格线
|
||||
ctx.strokeStyle = config.gridLineColor || '#000000';
|
||||
|
||||
Reference in New Issue
Block a user