feat: 增加找字模板
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
import { PAPER_SIZE } from '../constants/colors';
|
||||
import { getMiniCodeImage, getImage } from '../utils/index';
|
||||
import { ShapeCard } from '../constants/shapes';
|
||||
import { drawShape } from './drawShape';
|
||||
import {
|
||||
drawHeader as drawHeaderCommon,
|
||||
drawMiniHeader as drawMiniHeaderCommon,
|
||||
} from './headerDrawService';
|
||||
|
||||
/**
|
||||
* 计算图形在画布上的位置,避免重叠
|
||||
@@ -36,8 +39,16 @@ function calculateShapePositions(
|
||||
const col = i % cols;
|
||||
|
||||
// 在单元格内随机位置
|
||||
const x = padding + col * cellWidth + (cellWidth - shapeSize) / 2 + (Math.random() - 0.5) * (cellWidth - shapeSize) * 0.3;
|
||||
const y = padding + row * cellHeight + (cellHeight - shapeSize) / 2 + (Math.random() - 0.5) * (cellHeight - shapeSize) * 0.3;
|
||||
const x =
|
||||
padding +
|
||||
col * cellWidth +
|
||||
(cellWidth - shapeSize) / 2 +
|
||||
(Math.random() - 0.5) * (cellWidth - shapeSize) * 0.3;
|
||||
const y =
|
||||
padding +
|
||||
row * cellHeight +
|
||||
(cellHeight - shapeSize) / 2 +
|
||||
(Math.random() - 0.5) * (cellHeight - shapeSize) * 0.3;
|
||||
|
||||
positions.push({ x, y });
|
||||
}
|
||||
@@ -45,7 +56,6 @@ function calculateShapePositions(
|
||||
return positions;
|
||||
}
|
||||
|
||||
|
||||
class ShapeDrawService {
|
||||
headerType: PrintHeader;
|
||||
canvas: WechatMiniprogram.Canvas;
|
||||
@@ -102,74 +112,38 @@ class ShapeDrawService {
|
||||
}
|
||||
|
||||
async drawHeader() {
|
||||
const { canvas, ctx } = this;
|
||||
const { appName, appHint, title, subTitle } = this.options;
|
||||
|
||||
this.currentX = 80;
|
||||
this.currentY = 80;
|
||||
let titleX = this.currentX + 200 + 48;
|
||||
const titleY = 80;
|
||||
|
||||
const logoX = 80;
|
||||
const logoY = 60;
|
||||
const logoWidth = 200;
|
||||
const logoHeight = 200;
|
||||
|
||||
switch (this.headerType) {
|
||||
case 'LogoImage': {
|
||||
const image = await getImage(canvas, '/assets/imgs/doodle-logo.png');
|
||||
ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight);
|
||||
break;
|
||||
}
|
||||
case 'noLogoImage': {
|
||||
titleX = 120;
|
||||
break;
|
||||
}
|
||||
case 'minimal': {
|
||||
titleX = 120;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const image = await getMiniCodeImage(canvas);
|
||||
ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.font = 'bold 64px "Microsoft Yahei"';
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'top';
|
||||
|
||||
ctx.fillText(appName, titleX, titleY);
|
||||
|
||||
ctx.font = '48px "Microsoft Yahei"';
|
||||
ctx.fillStyle = '#666';
|
||||
ctx.fillText(appHint, titleX, 186);
|
||||
|
||||
ctx.font = 'bold 64px "Microsoft Yahei"';
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.fillText(title, 1015, titleY);
|
||||
|
||||
ctx.font = '48px "Microsoft Yahei"';
|
||||
ctx.fillStyle = '#666';
|
||||
ctx.fillText(subTitle, 1015, 186);
|
||||
|
||||
this.currentY = 304;
|
||||
this.drawLine(this.currentY);
|
||||
await drawHeaderCommon({
|
||||
canvas: this.canvas,
|
||||
ctx: this.ctx,
|
||||
headerType: this.headerType,
|
||||
options: {
|
||||
appName: this.options.appName || '涂鸦丫小程序',
|
||||
appHint: this.options.appHint || '涂色|识字|画画|打印',
|
||||
title: this.options.title || '找一找 涂 色',
|
||||
subTitle: this.options.subTitle || '给图形涂上相同的颜色',
|
||||
},
|
||||
onHeaderDrawn: (currentY) => {
|
||||
this.currentY = currentY;
|
||||
this.drawLine(this.currentY);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
drawMiniHeader() {
|
||||
const { canvas, ctx } = this;
|
||||
const { appName, title } = this.options;
|
||||
const titleY = 120;
|
||||
|
||||
ctx.font = 'bold 64px "Microsoft Yahei"';
|
||||
ctx.fillStyle = '#000';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText(appName + ' ' + title, canvas.width / 2, titleY);
|
||||
this.currentY = 200;
|
||||
this.drawLine(this.currentY);
|
||||
drawMiniHeaderCommon({
|
||||
canvas: this.canvas,
|
||||
ctx: this.ctx,
|
||||
options: {
|
||||
appName: this.options.appName || '涂鸦丫小程序',
|
||||
title: this.options.title || '找一找 涂 色',
|
||||
},
|
||||
onHeaderDrawn: (currentY) => {
|
||||
this.currentY = currentY;
|
||||
this.drawLine(this.currentY);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
drawLegend() {
|
||||
@@ -245,7 +219,9 @@ class ShapeDrawService {
|
||||
|
||||
// 每行最多能放多少个图形(考虑最小间距40)
|
||||
const minGap = 40;
|
||||
const maxPerRow = Math.floor((contentWidth + minGap) / (shapeSize + minGap));
|
||||
const maxPerRow = Math.floor(
|
||||
(contentWidth + minGap) / (shapeSize + minGap),
|
||||
);
|
||||
|
||||
// 总共要绘制多少个图形(每行都填满)
|
||||
const totalShapes = maxPerRow * ROW_COUNT;
|
||||
@@ -263,14 +239,20 @@ class ShapeDrawService {
|
||||
}
|
||||
|
||||
// 生成所有图形的位置
|
||||
let positions: { x: number, y: number }[] = [];
|
||||
let positions: { x: number; y: number }[] = [];
|
||||
for (let row = 0; row < ROW_COUNT; row++) {
|
||||
// 本行起始Y
|
||||
const y = contentTop + row * (shapeSize + VERTICAL_GAP) + shapeSize / 2;
|
||||
const y =
|
||||
contentTop + row * (shapeSize + VERTICAL_GAP) + shapeSize / 2;
|
||||
// 本行实际间距
|
||||
const gap = maxPerRow > 1
|
||||
? Math.max(minGap, (contentWidth - maxPerRow * shapeSize) / (maxPerRow - 1))
|
||||
: 0;
|
||||
const gap =
|
||||
maxPerRow > 1
|
||||
? Math.max(
|
||||
minGap,
|
||||
(contentWidth - maxPerRow * shapeSize) /
|
||||
(maxPerRow - 1),
|
||||
)
|
||||
: 0;
|
||||
// 本行起始X(水平居中)
|
||||
let startX = leftMargin;
|
||||
if (maxPerRow > 1) {
|
||||
@@ -282,7 +264,7 @@ class ShapeDrawService {
|
||||
for (let col = 0; col < maxPerRow; col++) {
|
||||
positions.push({
|
||||
x: startX + col * (shapeSize + gap) + shapeSize / 2,
|
||||
y: y
|
||||
y: y,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -297,7 +279,9 @@ class ShapeDrawService {
|
||||
}
|
||||
|
||||
// 记录实际绘制的图形数量
|
||||
console.log(`绘制图形:计划${totalShapes}个,实际${positions.length}个;每行${maxPerRow}个,共${ROW_COUNT}行;边距 左右=${leftMargin}/${rightMargin},顶部=${topGap}(基于legend底线)`);
|
||||
console.log(
|
||||
`绘制图形:计划${totalShapes}个,实际${positions.length}个;每行${maxPerRow}个,共${ROW_COUNT}行;边距 左右=${leftMargin}/${rightMargin},顶部=${topGap}(基于legend底线)`,
|
||||
);
|
||||
|
||||
// 绘制所有图形
|
||||
positions.forEach((pos, index) => {
|
||||
|
||||
Reference in New Issue
Block a user