diff --git a/miniprogram/app.json b/miniprogram/app.json index 084aecb..58f45e0 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -27,7 +27,8 @@ "pages": [ "gridDrawing/gridDrawing", "shape/shape", - "positionColoring/positionColoring" + "positionColoring/positionColoring", + "shapeSymbol/shapeSymbol" ], "independent": false } diff --git a/miniprogram/constants/colors.ts b/miniprogram/constants/colors.ts index cd0689c..e71582c 100644 --- a/miniprogram/constants/colors.ts +++ b/miniprogram/constants/colors.ts @@ -85,6 +85,48 @@ export const WATER_COLORS = { ], }; +/** + * 数字颜色映射(柔和12色) + * 用于数学页面的数字显示和涂色 + */ +export const NUMBER_COLORS: Record = { + 1: '#ED6D50', // 柔和红色 + 2: '#F9A857', // 柔和橙色 + 3: '#FFE176', // 柔和黄色 + 4: '#B2D94B', // 柔和黄绿色 + 5: '#53D1B6', // 柔和绿色 + 6: '#6CD2EA', // 柔和青色 + 7: '#79A7ED', // 柔和蓝色 + 8: '#9C98DE', // 柔和紫色 + 9: '#F2A4C0', // 柔和粉色 + 10: '#FC9B6C', // 柔和橙红色 + 11: '#BC8F71', // 柔和棕色 + 12: '#666666', // 柔和黑灰 + 13: '#FF2222', // 鲜艳大红 + 14: '#FF9900', // 鲜艳橙色 + 15: '#FFD700', // 鲜艳金黄 + 16: '#32CD32', // 鲜艳亮绿 + 17: '#21C5E4', // 鲜艳青色 + 18: '#3777FF', // 鲜艳蓝色 + 19: '#9D27E3', // 鲜艳紫色 + 20: '#FF40A0', // 鲜艳玫粉 +}; + +/** + * 获取所有数字颜色数组 + */ +export function getNumberColors(): string[] { + return Object.values(NUMBER_COLORS); +} + +/** + * 随机获取一个数字颜色 + */ +export function getRandomNumberColor(): string { + const colors = getNumberColors(); + return colors[Math.floor(Math.random() * colors.length)]; +} + export const PAPER_SIZE = { A4: { // width: 2480, diff --git a/miniprogram/constants/focusFunctions.ts b/miniprogram/constants/focusFunctions.ts index bb4145b..8a5435a 100644 --- a/miniprogram/constants/focusFunctions.ts +++ b/miniprogram/constants/focusFunctions.ts @@ -16,6 +16,14 @@ export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [ desc: '识别形状,涂一涂', icon: '🔍', }, + // 图形符号配对 + { + id: 'shape-symbol', + page: 'shapeSymbol', + title: '图形符号配对', + desc: '根据图形画对应的符号', + icon: '🔗', + }, // 方位涂涂乐 { id: 'position-coloring', diff --git a/miniprogram/constants/mathFunctions.ts b/miniprogram/constants/mathFunctions.ts index e5eb920..d586c6f 100644 --- a/miniprogram/constants/mathFunctions.ts +++ b/miniprogram/constants/mathFunctions.ts @@ -110,37 +110,3 @@ export const MATH_FUNCTION_TYPES: MathFunctionType[] = [ icon: '🔢', }, ]; - -/** - * 数字颜色映射(柔和12色) - * 用于数学页面的数字显示和涂色 - */ -export const NUMBER_COLORS: Record = { - 1: '#ED6D50', // 柔和红色 - 2: '#F9A857', // 柔和橙色 - 3: '#FFE176', // 柔和黄色 - 4: '#B2D94B', // 柔和黄绿色 - 5: '#53D1B6', // 柔和绿色 - 6: '#6CD2EA', // 柔和青色 - 7: '#79A7ED', // 柔和蓝色 - 8: '#9C98DE', // 柔和紫色 - 9: '#F2A4C0', // 柔和粉色 - 10: '#FC9B6C', // 柔和橙红色 - 11: '#BC8F71', // 柔和棕色 - 12: '#666666', // 柔和黑灰 -}; - -/** - * 获取所有数字颜色数组 - */ -export function getNumberColors(): string[] { - return Object.values(NUMBER_COLORS); -} - -/** - * 随机获取一个数字颜色 - */ -export function getRandomNumberColor(): string { - const colors = getNumberColors(); - return colors[Math.floor(Math.random() * colors.length)]; -} diff --git a/miniprogram/focusPages/shapeSymbol/shapeSymbol.json b/miniprogram/focusPages/shapeSymbol/shapeSymbol.json new file mode 100644 index 0000000..cbaf7e9 --- /dev/null +++ b/miniprogram/focusPages/shapeSymbol/shapeSymbol.json @@ -0,0 +1,12 @@ +{ + "navigationBarTitleText": "图形符号配对", + "navigationBarBackgroundColor": "#FFD719", + "homeButton": true, + "backgroundColor": "#F6F6F6", + "enablePullDownRefresh": false, + "usingComponents": { + "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" + } +} diff --git a/miniprogram/focusPages/shapeSymbol/shapeSymbol.ts b/miniprogram/focusPages/shapeSymbol/shapeSymbol.ts new file mode 100644 index 0000000..ef58c78 --- /dev/null +++ b/miniprogram/focusPages/shapeSymbol/shapeSymbol.ts @@ -0,0 +1,155 @@ +import ShapeSymbolDraw from '../shared/service/shapeSymbolDraw'; +import { createFocusPage } from '../shared/common/focusPageMixin'; +import { ShapeSymbolData } from '../shared/service/shapeSymbolDraw'; +import { SHAPE_SYMBOL_SHAPES } from '../shared/shapes/shapeSymbolShapes'; +import { getRandomNumberColor } from '../../constants/colors'; + +createFocusPage({ + canvas: null as Canvas | null, + ctx: null as RenderingContext | null, + boxHeight: 0, + boxWidth: 0, + drawService: null as ShapeSymbolDraw | null, + gridData: null as ShapeSymbolData | null, + + data: { + pageTitle: '图形符号配对', + functionId: '', + hasContent: false, + showShareDialog: false, + }, + + onLoad(options: { id?: string }) { + const functionId = options.id || 'shape-symbol'; + this.setData({ + functionId, + }); + this.initPageInfo(functionId, '图形符号配对'); + }, + + onReady() { + this.initCanvas({ + createDrawService: ( + canvas: Canvas, + ctx: RenderingContext, + options?: Record, + ) => { + return new ShapeSymbolDraw(canvas, ctx, options); + }, + drawServiceOptions: { + title: this.data.pageTitle, + subTitle: '根据图形画对应的符号', + functionId: this.data.functionId, + }, + onCanvasReady: () => { + // 初始随机生成 + this.onRandom(); + }, + }); + }, + + /** + * 绘制Canvas内容 + */ + async drawCanvas() { + if (!this.ctx || !this.drawService || !this.gridData) { + return; + } + + try { + await this.drawService.draw(this.gridData); + this.setData({ hasContent: true }); + } catch (error) { + console.error('绘制失败:', error); + this.setData({ hasContent: false }); + } + }, + + /** + * 随机生成 + */ + onRandom() { + // 从9种图形中随机选择4个 + const shuffled = [...SHAPE_SYMBOL_SHAPES].sort( + () => Math.random() - 0.5, + ); + const selectedShapes = shuffled.slice(0, 4); + + // 符号类型:加号、减号、乘号、对号 + const symbols = ['+', '-', '×', '✓']; + // 随机打乱符号顺序 + const shuffledSymbols = [...symbols].sort(() => Math.random() - 0.5); + + // 创建图形和符号的映射关系(按位置对应),并为每个图形分配不同的颜色 + const shapeColorMap = new Map(); // 存储每个图形ID对应的颜色 + const usedColors = new Set(); // 记录已使用的颜色,确保4个图形颜色不同 + const legendMapping: Array<{ + shapeId: string; + symbol: string; + color: string; + }> = []; + + for (let i = 0; i < 4; i++) { + const shape = selectedShapes[i]; + + // 为每个图形分配颜色,确保4个图形颜色都不相同 + let color: string; + if (shapeColorMap.has(shape.id)) { + // 如果这个图形已经分配过颜色,使用之前的颜色 + color = shapeColorMap.get(shape.id)!; + } else { + // 生成新颜色,确保不与已使用的颜色重复 + do { + color = getRandomNumberColor(); + } while (usedColors.has(color)); + shapeColorMap.set(shape.id, color); + usedColors.add(color); + } + + legendMapping.push({ + shapeId: shape.id, + symbol: shuffledSymbols[i], + color: color, + }); + } + + // 生成练习区域的数据(6行7列,每两行一组) + const practiceRows: Array< + Array<{ shapeId: string | null; symbol: string | null }> + > = []; + for (let groupIndex = 0; groupIndex < 4; groupIndex++) { + // 每组第一行:随机展示图形 + const shapeRow: Array<{ + shapeId: string | null; + symbol: string | null; + }> = []; + for (let col = 0; col < 8; col++) { + // 随机选择一个图形(从选中的4个中选) + const randomShape = + selectedShapes[ + Math.floor(Math.random() * selectedShapes.length) + ]; + shapeRow.push({ shapeId: randomShape.id, symbol: null }); + } + practiceRows.push(shapeRow); + + // 每组第二行:空着,让小朋友涂符号 + const symbolRow: Array<{ + shapeId: string | null; + symbol: string | null; + }> = []; + for (let col = 0; col < 8; col++) { + symbolRow.push({ shapeId: null, symbol: null }); + } + practiceRows.push(symbolRow); + } + + this.gridData = { + legendMapping, + practiceRows, + shapeColorMap: Object.fromEntries(shapeColorMap), // 转换为普通对象传递给绘制服务 + }; + + this.drawCanvas(); + }, +}); diff --git a/miniprogram/focusPages/shapeSymbol/shapeSymbol.wxml b/miniprogram/focusPages/shapeSymbol/shapeSymbol.wxml new file mode 100644 index 0000000..5d3cbdb --- /dev/null +++ b/miniprogram/focusPages/shapeSymbol/shapeSymbol.wxml @@ -0,0 +1,37 @@ + + + 预览打印效果 + + + + + + + + + + 随机生成 + + + + + + + diff --git a/miniprogram/focusPages/shapeSymbol/shapeSymbol.wxss b/miniprogram/focusPages/shapeSymbol/shapeSymbol.wxss new file mode 100644 index 0000000..ddc41cc --- /dev/null +++ b/miniprogram/focusPages/shapeSymbol/shapeSymbol.wxss @@ -0,0 +1 @@ +@import '../../base/baseDrawPage.wxss'; diff --git a/miniprogram/focusPages/shared/service/positionColoringDraw.ts b/miniprogram/focusPages/shared/service/positionColoringDraw.ts index 4f54b8f..6d26bb3 100644 --- a/miniprogram/focusPages/shared/service/positionColoringDraw.ts +++ b/miniprogram/focusPages/shared/service/positionColoringDraw.ts @@ -121,14 +121,7 @@ class PositionColoringDraw extends BaseDrawService { // 绘制虚线分隔 const dividerY = referenceGridY + gridHeight + 30; - ctx.strokeStyle = '#999'; - ctx.lineWidth = 1; - ctx.setLineDash([4, 4]); // 虚线 - ctx.beginPath(); - ctx.moveTo(margin, dividerY); - ctx.lineTo(canvasWidth - margin, dividerY); - ctx.stroke(); - ctx.setLineDash([]); // 重置为实线 + this.drawDashedDivider(dividerY, margin); // 绘制任务区域(三行三列) const taskStartY = dividerY + 30; diff --git a/miniprogram/focusPages/shared/service/shapeSymbolDraw.ts b/miniprogram/focusPages/shared/service/shapeSymbolDraw.ts new file mode 100644 index 0000000..b9fb4d3 --- /dev/null +++ b/miniprogram/focusPages/shared/service/shapeSymbolDraw.ts @@ -0,0 +1,265 @@ +/** + * 图形符号配对绘制服务 + */ + +import { BaseDrawService } from '../../../service/baseDraw'; +import { drawShapeSymbolShape } from '../shapes/shapeSymbolShapes'; + +/** + * 图形符号配对数据 + */ +export interface ShapeSymbolData { + /** 图例映射(4个图形和符号的对应关系) */ + legendMapping: Array<{ + shapeId: string; + symbol: string; + color: string; + }>; + /** 练习区域的行数据(6行,每两行一组) */ + practiceRows: Array< + Array<{ shapeId: string | null; symbol: string | null }> + >; + /** 图形颜色映射 */ + shapeColorMap: Record; +} + +/** + * 图形符号配对绘制服务 + */ +class ShapeSymbolDraw extends BaseDrawService { + gridData: ShapeSymbolData | null = null; + + constructor( + canvas: Canvas, + ctx: RenderingContext, + options?: Record, + ) { + super(canvas, ctx, options); + } + + /** + * 绘制图形符号配对内容 + */ + async draw(gridData: ShapeSymbolData) { + if (!gridData || !gridData.legendMapping || !gridData.practiceRows) { + return; + } + + this.setPrintConfig(); + this.gridData = gridData; + this.clear(); + this.setPaper(); + + // 绘制Header + if (this.headerType !== 'minimal') { + await this.drawHeader(); + } else { + this.drawMiniHeader(); + } + + // 绘制内容区域 + this.drawDivider(); + this.drawContent({ + ctx: this.ctx, + gridData: this.gridData, + canvasWidth: this.canvasWidth, + startY: this.currentY, + }); + } + + /** + * 绘制内容区域 + */ + private drawContent(params: { + ctx: RenderingContext; + gridData: ShapeSymbolData; + canvasWidth: number; + startY: number; + }): void { + const { ctx, gridData, canvasWidth } = params; + let { startY } = params; + + startY = startY + 25; + + const margin = 40; // 左右边距 + const legendCols = 4; // 图例列数 + const legendRows = 2; // 图例行数 + const cellSize = 65; // 每个格子的大小 + const gridWidth = cellSize * legendCols; + const gridHeight = cellSize * legendRows; + + // 绘制参考网格(上面的九宫格) + const legendStartX = + margin + (canvasWidth - margin * 2 - gridWidth) / 2; // 居中 + const legendStartY = startY; + + // 绘制参考网格的网格线 + this.drawGridLines( + ctx, + legendStartX, + legendStartY, + gridWidth, + gridHeight, + cellSize, + legendCols, + legendRows, + ); + + // 绘制图例内容 + // 优化常量设置,减少重复计算,增强可维护性 + // const legendColSpacing = 24; // 列间距(px),如需调整只此一处 + // const legendCellHeight = cellSize; // 图例格子的高度,当前与cellSize一致 + + gridData.legendMapping.forEach((mapping, index: number) => { + if (!mapping) return; + + const shapeX = legendStartX + index * cellSize + cellSize / 2; // 图片居中,假设图片大小50x50 + const shapeY = legendStartY + cellSize / 2; + + const shapeSize = 42; + const shapeColor = mapping.color || '#000'; + drawShapeSymbolShape( + ctx, + mapping.shapeId, + shapeX, + shapeY, + shapeSize, + shapeColor, + ); + + // 第二行:绘制符号(使用 emoji) + const symbolX = legendStartX + index * cellSize + cellSize / 2; // 图片居中,假设图片大小50x50 + const symbolY = legendStartY + cellSize + cellSize / 2 + 5; + this.drawSymbol(ctx, symbolX, symbolY, mapping.symbol, 30); + }); + + const dividerY = legendStartY + legendRows * cellSize + 30; + this.drawDashedDivider(dividerY, margin); + + // 绘制练习区域(六行七列,使用网格线,确保正方形格子) + const practiceStartY = dividerY + 30; + const practiceCols = 8; + const practiceRows = 8; + const practiceCellSize = 60; // 练习格子大小(正方形) + const practiceGridWidth = practiceCellSize * practiceCols; + const practiceGridHeight = practiceCellSize * practiceRows; + + // 计算练习区域起始X位置(居中) + const practiceStartX = + margin + (canvasWidth - margin * 2 - practiceGridWidth) / 2; + + // 绘制练习区域网格线(使用 drawGridLines) + this.drawGridLines( + ctx, + practiceStartX, + practiceStartY, + practiceGridWidth, + practiceGridHeight, + practiceCellSize, + practiceCols, + practiceRows, + ); + + // 绘制练习内容 + for (let row = 0; row < practiceRows; row++) { + const practiceRow = gridData.practiceRows[row]; + if (!practiceRow) continue; + + const rowY = practiceStartY + row * practiceCellSize; + const cellCenterY = rowY + practiceCellSize / 2; + + for (let col = 0; col < practiceCols; col++) { + const cell = practiceRow[col]; + if (!cell) continue; + + const colX = practiceStartX + col * practiceCellSize; + const cellCenterX = colX + practiceCellSize / 2; + + // 如果第一行(图形行),绘制图形(使用相同颜色,无边框,居中) + if (row % 2 === 0 && cell.shapeId) { + const shapeSize = 42; + const shapeColor = + gridData.shapeColorMap[cell.shapeId] || '#000'; + drawShapeSymbolShape( + ctx, + cell.shapeId, + cellCenterX, + cellCenterY, + shapeSize, + shapeColor, + ); + } + // 第二行(符号行)留空,让小朋友涂符号 + } + } + } + + /** + * 绘制符号(使用 emoji 文字) + */ + private drawSymbol( + ctx: RenderingContext, + x: number, + y: number, + symbol: string, + fontSize: number, + ): void { + ctx.save(); + + // 符号映射:将符号转换为 emoji + const symbolMap: Record = { + '+': '➕', + '-': '➖', + '×': '✖️', + '✓': '✔️', + }; + + const emojiSymbol = symbolMap[symbol] || symbol; + + ctx.font = `bold ${fontSize}px Arial`; + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.fillStyle = '#000'; + ctx.fillText(emojiSymbol, x, y); + + ctx.restore(); + } + + /** + * 绘制网格线 + */ + private drawGridLines( + ctx: RenderingContext, + gridStartX: number, + gridStartY: number, + gridWidth: number, + gridHeight: number, + cellSize: number, + legendCols: number, + legendRows: number, + ): void { + ctx.strokeStyle = '#000'; + ctx.lineWidth = 1; + ctx.setLineDash([]); // 实线 + + // 绘制垂直线 + for (let i = 0; i <= legendCols; i++) { + const x = gridStartX + i * cellSize; + ctx.beginPath(); + ctx.moveTo(x, gridStartY); + ctx.lineTo(x, gridStartY + gridHeight); + ctx.stroke(); + } + + // 绘制水平线 + for (let i = 0; i <= legendRows; i++) { + const y = gridStartY + i * cellSize; + ctx.beginPath(); + ctx.moveTo(gridStartX, y); + ctx.lineTo(gridStartX + gridWidth, y); + ctx.stroke(); + } + } +} + +export default ShapeSymbolDraw; diff --git a/miniprogram/focusPages/shared/shapes/shapeSymbolShapes.ts b/miniprogram/focusPages/shared/shapes/shapeSymbolShapes.ts new file mode 100644 index 0000000..b89836a --- /dev/null +++ b/miniprogram/focusPages/shared/shapes/shapeSymbolShapes.ts @@ -0,0 +1,155 @@ +/** + * 图形符号配对专用的图形定义 + * 所有图形保持大小一致 + */ + +export interface ShapeSymbolShape { + id: string; + name: string; +} + +export const SHAPE_SYMBOL_SHAPES: ShapeSymbolShape[] = [ + { id: 'circle', name: '圆形' }, + { id: 'square', name: '正方形' }, + { id: 'triangle', name: '三角形' }, + { id: 'diamond', name: '菱形' }, + { id: 'trapezoid', name: '梯形' }, + { id: 'ellipse', name: '椭圆' }, + { id: 'star', name: '五角星' }, + { id: 'pentagon', name: '五边形' }, + { id: 'heart', name: '心形' }, +]; + +/** + * 绘制图形(无边框,仅填充) + * 所有图形保持相同的大小 + */ +export function drawShapeSymbolShape( + ctx: RenderingContext, + shapeId: string, + x: number, + y: number, + size: number, + fillColor: string, +): void { + ctx.save(); + ctx.translate(x, y); + + const radius = size / 2; + + ctx.fillStyle = fillColor; + + switch (shapeId) { + case 'circle': + ctx.beginPath(); + ctx.arc(0, 0, radius, 0, Math.PI * 2); + ctx.fill(); + break; + + case 'square': + ctx.fillRect(-radius, -radius, size, size); + break; + + case 'triangle': + ctx.beginPath(); + ctx.moveTo(0, -radius); + ctx.lineTo(-radius, radius); + ctx.lineTo(radius, radius); + ctx.closePath(); + ctx.fill(); + break; + + case 'diamond': + ctx.beginPath(); + ctx.moveTo(0, -radius); + ctx.lineTo(radius, 0); + ctx.lineTo(0, radius); + ctx.lineTo(-radius, 0); + ctx.closePath(); + ctx.fill(); + break; + + case 'trapezoid': + ctx.beginPath(); + const topWidth = radius * 0.6; + ctx.moveTo(-topWidth, -radius * 0.7); + ctx.lineTo(topWidth, -radius * 0.7); + ctx.lineTo(radius, radius * 0.7); + ctx.lineTo(-radius, radius * 0.7); + ctx.closePath(); + ctx.fill(); + break; + + case 'ellipse': + ctx.beginPath(); + ctx.ellipse(0, 0, radius * 0.8, radius * 0.6, 0, 0, Math.PI * 2); + ctx.fill(); + break; + + case 'star': + // 五角星 + ctx.beginPath(); + for (let i = 0; i < 5; i++) { + const angle1 = (i * 2 * Math.PI) / 5 - Math.PI / 2; + const angle2 = ((i + 0.5) * 2 * Math.PI) / 5 - Math.PI / 2; + const r1 = radius; + const r2 = radius * 0.4; + const x1 = Math.cos(angle1) * r1; + const y1 = Math.sin(angle1) * r1; + const x2 = Math.cos(angle2) * r2; + const y2 = Math.sin(angle2) * r2; + if (i === 0) { + ctx.moveTo(x1, y1); + } else { + ctx.lineTo(x1, y1); + } + ctx.lineTo(x2, y2); + } + ctx.closePath(); + ctx.fill(); + break; + + case 'pentagon': + ctx.beginPath(); + for (let i = 0; i < 5; i++) { + const angle = (i * 2 * Math.PI) / 5 - Math.PI / 2; + const px = Math.cos(angle) * radius; + const py = Math.sin(angle) * radius; + if (i === 0) ctx.moveTo(px, py); + else ctx.lineTo(px, py); + } + ctx.closePath(); + ctx.fill(); + break; + + case 'heart': + // 爱心路径(参考 shapes.ts 中的 SVG 路径) + // SVG路径:M50,35 C35,20 20,35 25,50 C30,65 50,80 50,80 C50,80 70,65 75,50 C80,35 65,20 50,35Z + // SVG中心为(50,50),高度约为60(从y=20到y=80) + // 使用scale=60使心形高度约为size,与其他图形保持一致 + const scale = 60; + function tx(px: number) { + return ((px - 50) / scale) * size; + } + function ty(py: number) { + return ((py - 50) / scale) * size; + } + ctx.beginPath(); + ctx.moveTo(tx(50), ty(35)); + ctx.bezierCurveTo(tx(35), ty(20), tx(20), ty(35), tx(25), ty(50)); + ctx.bezierCurveTo(tx(30), ty(65), tx(50), ty(80), tx(50), ty(80)); + ctx.bezierCurveTo(tx(50), ty(80), tx(70), ty(65), tx(75), ty(50)); + ctx.bezierCurveTo(tx(80), ty(35), tx(65), ty(20), tx(50), ty(35)); + ctx.closePath(); + ctx.fill(); + break; + + default: + // 默认绘制圆形 + ctx.beginPath(); + ctx.arc(0, 0, radius, 0, Math.PI * 2); + ctx.fill(); + } + + ctx.restore(); +} diff --git a/miniprogram/mathPages/missingNumber/missingNumber.ts b/miniprogram/mathPages/missingNumber/missingNumber.ts index f92c411..c4bf62f 100644 --- a/miniprogram/mathPages/missingNumber/missingNumber.ts +++ b/miniprogram/mathPages/missingNumber/missingNumber.ts @@ -1,4 +1,4 @@ -import { getRandomNumberColor } from '../../constants/mathFunctions'; +import { getRandomNumberColor } from '../../constants/colors'; import MissingNumberDraw from '../shared/service/missingNumberDraw'; import { createMathPage, diff --git a/miniprogram/mathPages/shared/service/countMatchContentDraw.ts b/miniprogram/mathPages/shared/service/countMatchContentDraw.ts index a51ca72..10546c5 100644 --- a/miniprogram/mathPages/shared/service/countMatchContentDraw.ts +++ b/miniprogram/mathPages/shared/service/countMatchContentDraw.ts @@ -1,5 +1,5 @@ import { getImage } from '../../../utils/index'; -import { getRandomNumberColor } from '../../../constants/mathFunctions'; +import { getRandomNumberColor } from '../../../constants/colors'; interface DrawCountMatchContentParams { canvas: WechatMiniprogram.Canvas; diff --git a/miniprogram/mathPages/shared/service/countingSelectContentDraw.ts b/miniprogram/mathPages/shared/service/countingSelectContentDraw.ts index 0ca74c3..448050a 100644 --- a/miniprogram/mathPages/shared/service/countingSelectContentDraw.ts +++ b/miniprogram/mathPages/shared/service/countingSelectContentDraw.ts @@ -1,5 +1,5 @@ import { getImage } from '../../../utils/index'; -import { getRandomNumberColor } from '../../../constants/mathFunctions'; +import { getRandomNumberColor } from '../../../constants/colors'; interface DrawCountingSelectContentParams { canvas: WechatMiniprogram.Canvas; diff --git a/miniprogram/mathPages/shared/service/numberColorContentDraw.ts b/miniprogram/mathPages/shared/service/numberColorContentDraw.ts index 13cb4ec..4718c46 100644 --- a/miniprogram/mathPages/shared/service/numberColorContentDraw.ts +++ b/miniprogram/mathPages/shared/service/numberColorContentDraw.ts @@ -1,4 +1,4 @@ -import { getNumberColors } from '../../../constants/mathFunctions'; +import { getNumberColors } from '../../../constants/colors'; interface DrawNumberColorContentParams { canvas: WechatMiniprogram.Canvas; diff --git a/miniprogram/mathPages/shared/service/numberDecomposeContentDraw.ts b/miniprogram/mathPages/shared/service/numberDecomposeContentDraw.ts index 0a3f59d..157fac1 100644 --- a/miniprogram/mathPages/shared/service/numberDecomposeContentDraw.ts +++ b/miniprogram/mathPages/shared/service/numberDecomposeContentDraw.ts @@ -1,5 +1,5 @@ import { getImage } from '../../../utils/index'; -import { getRandomNumberColor } from '../../../constants/mathFunctions'; +import { getRandomNumberColor } from '../../../constants/colors'; interface DrawNumberDecomposeContentParams { canvas: WechatMiniprogram.Canvas; diff --git a/miniprogram/mathPages/shared/service/numberPreviewDraw.ts b/miniprogram/mathPages/shared/service/numberPreviewDraw.ts index e5c46ac..ec39752 100644 --- a/miniprogram/mathPages/shared/service/numberPreviewDraw.ts +++ b/miniprogram/mathPages/shared/service/numberPreviewDraw.ts @@ -1,5 +1,5 @@ import { getImage } from '../../../utils/index'; -import { NUMBER_COLORS } from '../../../constants/mathFunctions'; +import { NUMBER_COLORS } from '../../../constants/colors'; /** * 数字到英文单词的映射 diff --git a/miniprogram/service/baseDraw.ts b/miniprogram/service/baseDraw.ts index ecde550..d8c5b81 100644 --- a/miniprogram/service/baseDraw.ts +++ b/miniprogram/service/baseDraw.ts @@ -146,4 +146,29 @@ export class BaseDrawService { this.currentY = dividerY + 10; // 分割线下方10px间距 } + + /** + * 绘制虚线分割线(逻辑像素,尺寸除以3) + * @param y 分割线的Y坐标 + * @param margin 左右边距,默认为40 + * @param color 线条颜色,默认为'#999' + * @param lineWidth 线条宽度,默认为1 + */ + drawDashedDivider( + y: number, + margin: number = 40, + color: string = '#999', + lineWidth: number = 1, + ) { + const { ctx, canvasWidth } = this; + + ctx.strokeStyle = color; + ctx.lineWidth = lineWidth; + ctx.setLineDash([4, 4]); // 虚线 + ctx.beginPath(); + ctx.moveTo(margin, y); + ctx.lineTo(canvasWidth - margin, y); + ctx.stroke(); + ctx.setLineDash([]); // 重置为实线 + } } diff --git a/project.private.config.json b/project.private.config.json index aab1907..2d5af9b 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -23,12 +23,19 @@ "condition": { "miniprogram": { "list": [ + { + "name": "focusPages/shapeSymbol/shapeSymbol", + "pathName": "focusPages/shapeSymbol/shapeSymbol", + "query": "id=shape-symbol", + "scene": null, + "launchMode": "default" + }, { "name": "focusPages/positionColoring/positionColoring", "pathName": "focusPages/positionColoring/positionColoring", "query": "id=position-coloring", - "scene": null, - "launchMode": "default" + "launchMode": "default", + "scene": null }, { "name": "pages/focusIndex/focusIndex",