diff --git a/miniprogram/app.json b/miniprogram/app.json index c5f21d8..63b59a8 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -1,6 +1,7 @@ { "pages": [ "pages/mathIndex/mathIndex", + "pages/focusIndex/focusIndex", "pages/index/index", "pages/shape/index", "pages/copyBook/copyBook", @@ -20,6 +21,12 @@ "numberDecompose/numberDecompose" ], "independent": false + }, + { + "root": "focusPages", + "name": "focusPages", + "pages": ["gridDrawing/gridDrawing"], + "independent": false } ], "preloadRule": { @@ -62,6 +69,12 @@ "selectedIconPath": "assets/tabBar/icon-math-active.png", "text": "数感启蒙" }, + { + "pagePath": "pages/focusIndex/focusIndex", + "iconPath": "assets/tabBar/icon-word.png", + "selectedIconPath": "assets/tabBar/icon-word-active.png", + "text": "专注力" + }, { "pagePath": "pages/index/index", "iconPath": "assets/tabBar/icon-word.png", diff --git a/miniprogram/mathPages/shared/common/mathPage.less b/miniprogram/base/baseDrawPage.less similarity index 100% rename from miniprogram/mathPages/shared/common/mathPage.less rename to miniprogram/base/baseDrawPage.less diff --git a/miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.json b/miniprogram/components/math-bottom-buttons/math-bottom-buttons.json similarity index 52% rename from miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.json rename to miniprogram/components/math-bottom-buttons/math-bottom-buttons.json index d00f5a4..432d016 100644 --- a/miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.json +++ b/miniprogram/components/math-bottom-buttons/math-bottom-buttons.json @@ -1,6 +1,6 @@ { "component": true, "usingComponents": { - "toy-button": "../../../../ui/button/button" + "toy-button": "../../ui/button/button" } } diff --git a/miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.less b/miniprogram/components/math-bottom-buttons/math-bottom-buttons.less similarity index 100% rename from miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.less rename to miniprogram/components/math-bottom-buttons/math-bottom-buttons.less diff --git a/miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.ts b/miniprogram/components/math-bottom-buttons/math-bottom-buttons.ts similarity index 100% rename from miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.ts rename to miniprogram/components/math-bottom-buttons/math-bottom-buttons.ts diff --git a/miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.wxml b/miniprogram/components/math-bottom-buttons/math-bottom-buttons.wxml similarity index 100% rename from miniprogram/mathPages/shared/components/math-bottom-buttons/math-bottom-buttons.wxml rename to miniprogram/components/math-bottom-buttons/math-bottom-buttons.wxml diff --git a/miniprogram/components/math-type-selector/math-type-selector.json b/miniprogram/components/math-type-selector/math-type-selector.json new file mode 100644 index 0000000..7c86d18 --- /dev/null +++ b/miniprogram/components/math-type-selector/math-type-selector.json @@ -0,0 +1,7 @@ +{ + "component": true, + "usingComponents": { + "toy-button": "../../ui/button/button", + "van-action-sheet": "../../miniprogram_npm/@vant/weapp/action-sheet/index" + } +} diff --git a/miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.less b/miniprogram/components/math-type-selector/math-type-selector.less similarity index 100% rename from miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.less rename to miniprogram/components/math-type-selector/math-type-selector.less diff --git a/miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.ts b/miniprogram/components/math-type-selector/math-type-selector.ts similarity index 100% rename from miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.ts rename to miniprogram/components/math-type-selector/math-type-selector.ts diff --git a/miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.wxml b/miniprogram/components/math-type-selector/math-type-selector.wxml similarity index 100% rename from miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.wxml rename to miniprogram/components/math-type-selector/math-type-selector.wxml diff --git a/miniprogram/constants/focusFunctions.ts b/miniprogram/constants/focusFunctions.ts index 2fe8429..55f67ea 100644 --- a/miniprogram/constants/focusFunctions.ts +++ b/miniprogram/constants/focusFunctions.ts @@ -7,12 +7,12 @@ export interface FocusFunctionType { } export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [ - // 第一阶段:认识数字(最基础) + // 格子仿画 { - id: 'number-find', - page: 'numberFind', - title: '找数字,涂一涂', - desc: '找一找下面相同的数字,涂上颜色', - icon: '🔍', + id: 'grid-drawing', + page: 'gridDrawing', + title: '格子仿画', + desc: '在网格中填充颜色,形成各种形状', + icon: '🎨', }, ]; diff --git a/miniprogram/focusPages/gridDrawing/gridDrawing.json b/miniprogram/focusPages/gridDrawing/gridDrawing.json new file mode 100644 index 0000000..57c0785 --- /dev/null +++ b/miniprogram/focusPages/gridDrawing/gridDrawing.json @@ -0,0 +1,12 @@ +{ + "navigationBarTitleText": "格子仿画", + "navigationBarBackgroundColor": "#FFD719", + "homeButton": true, + "backgroundColor": "#F6F6F6", + "enablePullDownRefresh": false, + "usingComponents": { + "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", + "math-type-selector": "../../components/math-type-selector/math-type-selector", + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" + } +} diff --git a/miniprogram/focusPages/gridDrawing/gridDrawing.ts b/miniprogram/focusPages/gridDrawing/gridDrawing.ts new file mode 100644 index 0000000..6210c16 --- /dev/null +++ b/miniprogram/focusPages/gridDrawing/gridDrawing.ts @@ -0,0 +1,125 @@ +import GridDraw from '../shared/service/gridDraw'; +import { createFocusPage } from '../shared/common/focusPageMixin'; +import { GridDrawingData } from '../shared/service/gridDraw'; +import { generateCompletePattern } from '../shared/utils/gridUtils'; +import { getRandom3x3Shape } from '../shared/shapes/gridShapes3x3'; +import { getRandom5x5Shape } from '../shared/shapes/gridShapes5x5'; +import { getRandom7x7Shape } from '../shared/shapes/gridShapes7x7'; +import { ShapeTemplate } from '../shared/types/gridTypes'; + +createFocusPage({ + canvas: null as Canvas | null, + ctx: null as RenderingContext | null, + boxHeight: 0, + boxWidth: 0, + drawService: null as GridDraw | null, + gridData: null as GridDrawingData | null, + + data: { + pageTitle: '格子仿画', + functionId: '', + hasContent: false, + showShareDialog: false, + currentMode: '3x3', // '3x3', '5x5', '7x7' + currentModeName: '3×3', + typeActions: [ + { name: '3×3', value: '3x3' }, + { name: '5×5', value: '5x5' }, + { name: '7×7', value: '7x7' }, + ], + }, + + onLoad(options: { id?: string }) { + const functionId = options.id || 'grid-drawing'; + this.setData({ + functionId, + }); + this.initPageInfo(functionId, '格子仿画'); + }, + + onReady() { + this.initCanvas({ + createDrawService: ( + canvas: Canvas, + ctx: RenderingContext, + options?: Record, + ) => { + return new GridDraw(canvas, ctx, options); + }, + drawServiceOptions: { + subTitle: '在网格中填充颜色,形成各种形状', + functionId: this.data.functionId, + }, + onCanvasReady: () => { + // 初始随机生成 + this.onRandom(); + }, + }); + }, + + /** + * 绘制Canvas内容 + */ + async drawCanvas() { + if (!this.ctx || !this.drawService || !this.gridData) { + return; + } + + try { + // 更新 Header 的 Title + if (this.drawService) { + this.drawService.options.title = this.data.currentModeName; + } + + await this.drawService.draw(this.gridData); + this.setData({ hasContent: true }); + } catch (error) { + console.error('绘制失败:', error); + this.setData({ hasContent: false }); + } + }, + + /** + * 随机生成 + */ + onRandom() { + const mode = this.data.currentMode; + let shape: ShapeTemplate; + let config: GridConfig; + + // 根据模式选择形状和配置 + if (mode === '3x3') { + shape = getRandom3x3Shape(); + config = { rows: 3, cols: 3 }; + } else if (mode === '5x5') { + shape = getRandom5x5Shape(); + config = { rows: 5, cols: 5 }; + } else { + // 7x7 + shape = getRandom7x7Shape(); + config = { rows: 7, cols: 7 }; + } + + // 生成完整的格子数据 + const cells = generateCompletePattern(shape); + + this.gridData = { + config, + cells, + name: shape.name, + }; + + this.drawCanvas(); + }, + + /** 选择类型 */ + onSelectType(event: any) { + const { name, value } = event.detail; + this.setData({ + currentMode: value, + currentModeName: name, + }); + // 重新生成数据 + this.onRandom(); + }, +}); diff --git a/miniprogram/focusPages/gridDrawing/gridDrawing.wxml b/miniprogram/focusPages/gridDrawing/gridDrawing.wxml new file mode 100644 index 0000000..d8594f4 --- /dev/null +++ b/miniprogram/focusPages/gridDrawing/gridDrawing.wxml @@ -0,0 +1,30 @@ + + + 预览打印效果 + + + + + + + + + + + + + diff --git a/miniprogram/focusPages/common/focusPageMixin.ts b/miniprogram/focusPages/shared/common/focusPageMixin.ts similarity index 95% rename from miniprogram/focusPages/common/focusPageMixin.ts rename to miniprogram/focusPages/shared/common/focusPageMixin.ts index 033dadd..e6adfa0 100644 --- a/miniprogram/focusPages/common/focusPageMixin.ts +++ b/miniprogram/focusPages/shared/common/focusPageMixin.ts @@ -3,7 +3,7 @@ * 基于通用 pageMixin,提供专注力模块特定的配置 */ -import { createPage, PageCommonMethodsConfig } from '../../base/pageMixin'; +import { createPage, PageCommonMethodsConfig } from '../../../base/pageMixin'; /** * 专注力模块的函数类型定义 diff --git a/miniprogram/focusPages/shared/service/gridDraw.ts b/miniprogram/focusPages/shared/service/gridDraw.ts new file mode 100644 index 0000000..8474716 --- /dev/null +++ b/miniprogram/focusPages/shared/service/gridDraw.ts @@ -0,0 +1,125 @@ +/** + * 格子仿画绘制服务 + * 合并了基础绘制和内容绘制逻辑 + */ + +import { BaseDrawService } from '../../../service/baseDraw'; +import { GridCell, GridConfig } from '../types/gridTypes'; + +/** + * 格子仿画数据 + */ +export interface GridDrawingData { + config: GridConfig; + cells: GridCell[]; + name?: string; +} + +/** + * 格子仿画绘制服务 + */ +class GridDraw extends BaseDrawService { + gridData: GridDrawingData | null = null; + + constructor( + canvas: Canvas, + ctx: RenderingContext, + options?: Record, + ) { + super(canvas, ctx, options); + } + + /** + * 绘制格子仿画内容 + */ + async draw(gridData: GridDrawingData) { + if (!gridData || !gridData.cells) { + return; + } + + this.setPrintConfig(); + this.gridData = gridData; + this.clear(); + this.setPaper(); + + // 绘制Header + if (this.headerType !== 'minimal') { + await this.drawHeader(); + } else { + this.drawMiniHeader(); + } + + // 绘制内容区域(网格和填充) + this.drawDivider(); + await this.drawGridContent({ + canvas: this.canvas, + ctx: this.ctx, + gridData: this.gridData, + canvasWidth: this.canvasWidth, + startY: this.currentY, + }); + } + + /** + * 绘制网格内容 + */ + private async drawGridContent(params: { + canvas: WechatMiniprogram.Canvas; + ctx: RenderingContext; + gridData: GridDrawingData; + canvasWidth: number; + startY: number; + }): Promise { + const { ctx, gridData, canvasWidth, startY } = params; + const { config, cells } = gridData; + const { rows, cols } = config; + + // 计算网格尺寸 + const margin = 40; // 左右边距 + const availableWidth = canvasWidth - margin * 2; + const cellSize = Math.floor(availableWidth / cols); + const gridWidth = cellSize * cols; + const gridHeight = cellSize * rows; + + // 计算网格起始位置(居中) + const gridStartX = margin + (availableWidth - gridWidth) / 2; + const gridStartY = startY + 30; // 顶部间距 + + // 绘制网格线 + ctx.strokeStyle = config.gridLineColor || '#000000'; + ctx.lineWidth = config.gridLineWidth || 1; + ctx.setLineDash([]); // 实线 + + // 绘制垂直线 + for (let i = 0; i <= cols; i++) { + const x = gridStartX + i * cellSize; + ctx.beginPath(); + ctx.moveTo(x, gridStartY); + ctx.lineTo(x, gridStartY + gridHeight); + ctx.stroke(); + } + + // 绘制水平线 + for (let i = 0; i <= rows; i++) { + const y = gridStartY + i * cellSize; + ctx.beginPath(); + ctx.moveTo(gridStartX, y); + ctx.lineTo(gridStartX + gridWidth, y); + ctx.stroke(); + } + + // 绘制填充的格子 + for (const cell of cells) { + if (cell.x >= 0 && cell.x < cols && cell.y >= 0 && cell.y < rows) { + const x = gridStartX + cell.x * cellSize; + const y = gridStartY + cell.y * cellSize; + + // 填充颜色 + ctx.fillStyle = cell.color; + ctx.fillRect(x + 1, y + 1, cellSize - 2, cellSize - 2); + } + } + } +} + +export default GridDraw; diff --git a/miniprogram/focusPages/shared/shapes/gridShapes3x3.ts b/miniprogram/focusPages/shared/shapes/gridShapes3x3.ts new file mode 100644 index 0000000..ea96a5e --- /dev/null +++ b/miniprogram/focusPages/shared/shapes/gridShapes3x3.ts @@ -0,0 +1,117 @@ +/** + * 格子仿画 - 3x3 网格形状数据 + * 适用于入门级,低龄儿童 + */ + +import { GridCell, ShapeTemplate } from '../types/gridTypes'; + +// ==================== 3x3 形状模板 ==================== + +/** 简单十字形 */ +export const CROSS_3X3: ShapeTemplate = { + id: 'cross-3x3-001', + name: '十字形', + recommendedSize: { rows: 3, cols: 3 }, + category: 'geometric', + difficulty: 1, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 1, y: 0, color: '#FFFF00' }, // 顶部 + { x: 0, y: 1, color: '#FFFF00' }, // 左侧 + { x: 1, y: 1, color: '#FFFF00' }, // 中心 + { x: 2, y: 1, color: '#FFFF00' }, // 右侧 + { x: 1, y: 2, color: '#FFFF00' }, // 底部 + ], +}; + +/** L形 */ +export const L_SHAPE_3X3: ShapeTemplate = { + id: 'l-3x3-001', + name: 'L形', + recommendedSize: { rows: 3, cols: 3 }, + category: 'geometric', + difficulty: 1, + supportSymmetry: false, + isComplete: true, + cells: [ + { x: 0, y: 0, color: '#0000FF' }, + { x: 0, y: 1, color: '#0000FF' }, + { x: 0, y: 2, color: '#0000FF' }, + { x: 1, y: 2, color: '#0000FF' }, + { x: 2, y: 2, color: '#0000FF' }, + ], +}; + +/** 对角线 */ +export const DIAGONAL_3X3: ShapeTemplate = { + id: 'diagonal-3x3-001', + name: '对角线', + recommendedSize: { rows: 3, cols: 3 }, + category: 'geometric', + difficulty: 1, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 0, y: 0, color: '#FF0000' }, + { x: 1, y: 1, color: '#FF0000' }, + { x: 2, y: 2, color: '#FF0000' }, + ], +}; + +/** 小房子 */ +export const HOUSE_3X3: ShapeTemplate = { + id: 'house-3x3-001', + name: '小房子', + recommendedSize: { rows: 3, cols: 3 }, + category: 'object', + difficulty: 1, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: true, + cells: [ + { x: 1, y: 0, color: '#FF0000' }, // 屋顶 + { x: 0, y: 1, color: '#FFFF00' }, // 左侧墙 + { x: 1, y: 1, color: '#FFFF00' }, // 中间墙 + { x: 2, y: 1, color: '#FFFF00' }, // 右侧墙 + { x: 1, y: 2, color: '#8B4513' }, // 门 + ], +}; + +/** 小星星 */ +export const STAR_3X3: ShapeTemplate = { + id: 'star-3x3-001', + name: '小星星', + recommendedSize: { rows: 3, cols: 3 }, + category: 'geometric', + difficulty: 1, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 1, y: 0, color: '#FFD700' }, // 顶部 + { x: 0, y: 1, color: '#FFD700' }, + { x: 1, y: 1, color: '#FFD700' }, // 中心 + { x: 2, y: 1, color: '#FFD700' }, + { x: 1, y: 2, color: '#FFD700' }, // 底部 + ], +}; + +/** 所有 3x3 形状模板 */ +export const ALL_3X3_SHAPES: ShapeTemplate[] = [ + CROSS_3X3, + L_SHAPE_3X3, + DIAGONAL_3X3, + HOUSE_3X3, + STAR_3X3, +]; + +/** + * 随机获取一个 3x3 形状 + */ +export function getRandom3x3Shape(): ShapeTemplate { + const randomIndex = Math.floor(Math.random() * ALL_3X3_SHAPES.length); + return ALL_3X3_SHAPES[randomIndex]; +} diff --git a/miniprogram/focusPages/shared/shapes/gridShapes5x5.ts b/miniprogram/focusPages/shared/shapes/gridShapes5x5.ts new file mode 100644 index 0000000..d20728c --- /dev/null +++ b/miniprogram/focusPages/shared/shapes/gridShapes5x5.ts @@ -0,0 +1,218 @@ +/** + * 格子仿画 - 5x5 网格形状数据 + * 适用于常用尺寸,适中难度 + */ + +import { GridCell, ShapeTemplate } from '../types/gridTypes'; + +// ==================== 5x5 形状模板 ==================== + +/** 十字形 */ +export const CROSS_5X5: ShapeTemplate = { + id: 'cross-5x5-001', + name: '十字形', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 1, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 2, y: 0, color: '#FFFF00' }, // 顶部 + { x: 2, y: 1, color: '#FFFF00' }, + { x: 0, y: 2, color: '#FFFF00' }, // 左侧 + { x: 1, y: 2, color: '#FFFF00' }, + { x: 2, y: 2, color: '#FFFF00' }, // 中心 + { x: 3, y: 2, color: '#FFFF00' }, + { x: 4, y: 2, color: '#FFFF00' }, // 右侧 + { x: 2, y: 3, color: '#FFFF00' }, + { x: 2, y: 4, color: '#FFFF00' }, // 底部 + ], +}; + +/** X形 */ +export const X_SHAPE_5X5: ShapeTemplate = { + id: 'x-5x5-001', + name: 'X形', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 2, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 0, y: 0, color: '#0000FF' }, + { x: 1, y: 1, color: '#0000FF' }, + { x: 2, y: 2, color: '#0000FF' }, + { x: 3, y: 3, color: '#0000FF' }, + { x: 4, y: 4, color: '#0000FF' }, + { x: 4, y: 0, color: '#0000FF' }, + { x: 3, y: 1, color: '#0000FF' }, + { x: 1, y: 3, color: '#0000FF' }, + { x: 0, y: 4, color: '#0000FF' }, + ], +}; + +/** 星星 */ +export const STAR_5X5: ShapeTemplate = { + id: 'star-5x5-001', + name: '星星', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 3, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 2, y: 0, color: '#FFD700' }, // 顶部 + { x: 1, y: 1, color: '#FFD700' }, + { x: 3, y: 1, color: '#FFD700' }, + { x: 0, y: 2, color: '#FFD700' }, + { x: 2, y: 2, color: '#FFD700' }, // 中心 + { x: 4, y: 2, color: '#FFD700' }, + { x: 1, y: 3, color: '#FFD700' }, + { x: 3, y: 3, color: '#FFD700' }, + { x: 2, y: 4, color: '#FFD700' }, // 底部 + ], +}; + +/** Z字形 */ +export const ZIGZAG_5X5: ShapeTemplate = { + id: 'zigzag-5x5-001', + name: 'Z字形', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 2, + supportSymmetry: false, + isComplete: true, + cells: [ + { x: 0, y: 0, color: '#800080' }, + { x: 1, y: 0, color: '#800080' }, + { x: 2, y: 0, color: '#800080' }, + { x: 2, y: 1, color: '#800080' }, + { x: 1, y: 2, color: '#800080' }, + { x: 0, y: 2, color: '#800080' }, + { x: 0, y: 3, color: '#800080' }, + { x: 1, y: 3, color: '#800080' }, + { x: 2, y: 4, color: '#800080' }, + { x: 3, y: 4, color: '#800080' }, + { x: 4, y: 4, color: '#800080' }, + ], +}; + +/** V字形 */ +export const V_SHAPE_5X5: ShapeTemplate = { + id: 'v-5x5-001', + name: 'V字形', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 2, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: true, + cells: [ + { x: 0, y: 0, color: '#00FF00' }, + { x: 4, y: 0, color: '#00FF00' }, + { x: 0, y: 1, color: '#00FF00' }, + { x: 4, y: 1, color: '#00FF00' }, + { x: 1, y: 2, color: '#00FF00' }, + { x: 3, y: 2, color: '#00FF00' }, + { x: 2, y: 3, color: '#00FF00' }, + { x: 2, y: 4, color: '#00FF00' }, + ], +}; + +/** I字形 */ +export const I_SHAPE_5X5: ShapeTemplate = { + id: 'i-5x5-001', + name: 'I字形', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 1, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: true, + cells: [ + { x: 1, y: 0, color: '#FF7F00' }, + { x: 2, y: 0, color: '#FF7F00' }, + { x: 3, y: 0, color: '#FF7F00' }, + { x: 2, y: 1, color: '#FF7F00' }, + { x: 2, y: 2, color: '#FF7F00' }, + { x: 2, y: 3, color: '#FF7F00' }, + { x: 2, y: 4, color: '#FF7F00' }, + { x: 1, y: 4, color: '#FF7F00' }, + { x: 3, y: 4, color: '#FF7F00' }, + ], +}; + +/** 棋盘格 */ +export const CHECKERBOARD_5X5: ShapeTemplate = { + id: 'checkerboard-5x5-001', + name: '棋盘格', + recommendedSize: { rows: 5, cols: 5 }, + category: 'geometric', + difficulty: 3, + supportSymmetry: true, + symmetryType: 'both', + isComplete: true, + cells: [ + { x: 0, y: 0, color: '#FFFF00' }, + { x: 2, y: 0, color: '#FFFF00' }, + { x: 4, y: 0, color: '#FFFF00' }, + { x: 1, y: 1, color: '#FFFF00' }, + { x: 3, y: 1, color: '#FFFF00' }, + { x: 0, y: 2, color: '#FFFF00' }, + { x: 2, y: 2, color: '#FFFF00' }, + { x: 4, y: 2, color: '#FFFF00' }, + { x: 1, y: 3, color: '#FFFF00' }, + { x: 3, y: 3, color: '#FFFF00' }, + { x: 0, y: 4, color: '#FFFF00' }, + { x: 2, y: 4, color: '#FFFF00' }, + { x: 4, y: 4, color: '#FFFF00' }, + ], +}; + +/** 心形(简化版) */ +export const HEART_5X5: ShapeTemplate = { + id: 'heart-5x5-001', + name: '心形', + recommendedSize: { rows: 5, cols: 5 }, + category: 'object', + difficulty: 2, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: true, + cells: [ + { x: 1, y: 0, color: '#FF69B4' }, + { x: 2, y: 0, color: '#FF69B4' }, + { x: 3, y: 0, color: '#FF69B4' }, + { x: 0, y: 1, color: '#FF69B4' }, + { x: 2, y: 1, color: '#FF69B4' }, + { x: 4, y: 1, color: '#FF69B4' }, + { x: 1, y: 2, color: '#FF69B4' }, + { x: 2, y: 2, color: '#FF69B4' }, + { x: 3, y: 2, color: '#FF69B4' }, + { x: 2, y: 3, color: '#FF69B4' }, + { x: 2, y: 4, color: '#FF69B4' }, + ], +}; + +/** 所有 5x5 形状模板 */ +export const ALL_5X5_SHAPES: ShapeTemplate[] = [ + CROSS_5X5, + X_SHAPE_5X5, + STAR_5X5, + ZIGZAG_5X5, + V_SHAPE_5X5, + I_SHAPE_5X5, + CHECKERBOARD_5X5, + HEART_5X5, +]; + +/** + * 随机获取一个 5x5 形状 + */ +export function getRandom5x5Shape(): ShapeTemplate { + const randomIndex = Math.floor(Math.random() * ALL_5X5_SHAPES.length); + return ALL_5X5_SHAPES[randomIndex]; +} diff --git a/miniprogram/focusPages/shared/shapes/gridShapes7x7.ts b/miniprogram/focusPages/shared/shapes/gridShapes7x7.ts new file mode 100644 index 0000000..4612f39 --- /dev/null +++ b/miniprogram/focusPages/shared/shapes/gridShapes7x7.ts @@ -0,0 +1,247 @@ +/** + * 格子仿画 - 7x7 网格形状数据 + * 适用于中等难度,复杂图案 + */ + +import { GridCell, ShapeTemplate } from '../types/gridTypes'; + +// ==================== 7x7 形状模板 ==================== + +/** 南瓜头 - 对称涂色(仅存储左半部分) */ +export const PUMPKIN_HEAD_7X7: ShapeTemplate = { + id: 'pumpkin-7x7-001', + name: '南瓜头', + recommendedSize: { rows: 7, cols: 7 }, + category: 'character', + difficulty: 4, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: false, // 只存储了左半部分 + colorSchemeId: 'halloween', + cells: [ + // 茎(在对称轴上) + { x: 3, y: 0, color: '#FF7F00' }, + + // 脸部轮廓(浅绿色)- 左半部分 + { x: 0, y: 1, color: '#90EE90' }, + { x: 1, y: 1, color: '#90EE90' }, + { x: 0, y: 2, color: '#90EE90' }, + { x: 1, y: 2, color: '#90EE90' }, + { x: 0, y: 3, color: '#90EE90' }, + { x: 1, y: 3, color: '#90EE90' }, + { x: 0, y: 4, color: '#90EE90' }, + { x: 1, y: 4, color: '#90EE90' }, + { x: 0, y: 5, color: '#90EE90' }, + { x: 1, y: 5, color: '#90EE90' }, + { x: 0, y: 6, color: '#90EE90' }, + { x: 1, y: 6, color: '#90EE90' }, + + // 脸部(黄色) + { x: 2, y: 1, color: '#FFFF00' }, + { x: 3, y: 1, color: '#FFFF00' }, // 对称轴上的点 + { x: 2, y: 2, color: '#FFFF00' }, + { x: 2, y: 3, color: '#FFFF00' }, + { x: 3, y: 3, color: '#FFFF00' }, + { x: 2, y: 4, color: '#FFFF00' }, + { x: 2, y: 5, color: '#FFFF00' }, + { x: 3, y: 5, color: '#FFFF00' }, + + // 眼睛(黑色)- 左眼 + { x: 2, y: 2, color: '#000000' }, + ], +}; + +/** 卡通恐龙 - 对称涂色(仅存储左半部分) */ +export const DINOSAUR_7X7: ShapeTemplate = { + id: 'dinosaur-7x7-001', + name: '卡通恐龙', + recommendedSize: { rows: 7, cols: 7 }, + category: 'animal', + difficulty: 4, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: false, // 只存储了左半部分 + cells: [ + // 身体(浅绿色) + { x: 1, y: 1, color: '#90EE90' }, + { x: 2, y: 1, color: '#90EE90' }, + { x: 1, y: 2, color: '#90EE90' }, + { x: 2, y: 2, color: '#90EE90' }, + { x: 0, y: 3, color: '#90EE90' }, + { x: 1, y: 3, color: '#90EE90' }, + { x: 2, y: 3, color: '#90EE90' }, + { x: 0, y: 4, color: '#90EE90' }, + { x: 1, y: 4, color: '#90EE90' }, + { x: 2, y: 4, color: '#90EE90' }, + { x: 0, y: 5, color: '#90EE90' }, + { x: 1, y: 5, color: '#90EE90' }, + { x: 2, y: 5, color: '#90EE90' }, + { x: 0, y: 6, color: '#90EE90' }, + { x: 1, y: 6, color: '#90EE90' }, + + // 眼睛(黑色) + { x: 2, y: 1, color: '#000000' }, + + // 嘴巴(红色) + { x: 2, y: 2, color: '#FF0000' }, + { x: 0, y: 3, color: '#FF0000' }, + + // 脚(黄色) + { x: 2, y: 5, color: '#FFFF00' }, + { x: 0, y: 6, color: '#FFFF00' }, + { x: 1, y: 6, color: '#FFFF00' }, + ], +}; + +/** 心形 - 对称涂色(仅存储左半部分,对称轴在x=3) */ +export const HEART_7X7: ShapeTemplate = { + id: 'heart-7x7-001', + name: '心形', + recommendedSize: { rows: 7, cols: 7 }, + category: 'object', + difficulty: 3, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: false, + colorSchemeId: 'warm', + cells: [ + // 左上半部分 + { x: 1, y: 0, color: '#FF69B4' }, + { x: 2, y: 0, color: '#FF69B4' }, + { x: 0, y: 1, color: '#FF69B4' }, + { x: 3, y: 1, color: '#FF69B4' }, // 对称轴上的点 + { x: 0, y: 2, color: '#FF69B4' }, + { x: 1, y: 3, color: '#FF69B4' }, + { x: 2, y: 4, color: '#FF69B4' }, + { x: 3, y: 5, color: '#FF69B4' }, // 对称轴上的点 + { x: 3, y: 6, color: '#FF69B4' }, // 对称轴上的点(底部尖端) + ], +}; + +/** 房子 */ +export const HOUSE_7X7: ShapeTemplate = { + id: 'house-7x7-001', + name: '小房子', + recommendedSize: { rows: 7, cols: 7 }, + category: 'object', + difficulty: 3, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: false, + cells: [ + // 屋顶(三角形)- 左半部分 + { x: 2, y: 0, color: '#FF0000' }, + { x: 1, y: 1, color: '#FF0000' }, + { x: 2, y: 1, color: '#FF0000' }, + { x: 3, y: 1, color: '#FF0000' }, // 对称轴上的点 + { x: 0, y: 2, color: '#FF0000' }, + { x: 1, y: 2, color: '#FF0000' }, + { x: 2, y: 2, color: '#FF0000' }, + { x: 3, y: 2, color: '#FF0000' }, + + // 墙体(黄色)- 左半部分 + { x: 1, y: 3, color: '#FFFF00' }, + { x: 2, y: 3, color: '#FFFF00' }, + { x: 3, y: 3, color: '#FFFF00' }, + { x: 1, y: 4, color: '#FFFF00' }, + { x: 2, y: 4, color: '#FFFF00' }, + { x: 3, y: 4, color: '#FFFF00' }, + { x: 1, y: 5, color: '#FFFF00' }, + { x: 2, y: 5, color: '#FFFF00' }, + { x: 3, y: 5, color: '#FFFF00' }, + + // 门(棕色)- 在对称轴上 + { x: 3, y: 4, color: '#8B4513' }, + { x: 3, y: 5, color: '#8B4513' }, + + // 窗户(蓝色) + { x: 1, y: 3, color: '#0000FF' }, + ], +}; + +/** 蝴蝶 */ +export const BUTTERFLY_7X7: ShapeTemplate = { + id: 'butterfly-7x7-001', + name: '蝴蝶', + recommendedSize: { rows: 7, cols: 7 }, + category: 'animal', + difficulty: 4, + supportSymmetry: true, + symmetryType: 'vertical', + isComplete: false, + cells: [ + // 左翅膀 + { x: 0, y: 1, color: '#FF69B4' }, + { x: 1, y: 1, color: '#FF69B4' }, + { x: 0, y: 2, color: '#FF69B4' }, + { x: 1, y: 2, color: '#FF69B4' }, + { x: 2, y: 2, color: '#FF69B4' }, + { x: 0, y: 3, color: '#FF69B4' }, + { x: 1, y: 3, color: '#FF69B4' }, + { x: 2, y: 3, color: '#FF69B4' }, + + // 身体(在对称轴上) + { x: 3, y: 1, color: '#000000' }, + { x: 3, y: 2, color: '#000000' }, + { x: 3, y: 3, color: '#000000' }, + { x: 3, y: 4, color: '#000000' }, + { x: 3, y: 5, color: '#000000' }, + + // 左下半翅膀 + { x: 1, y: 4, color: '#FF69B4' }, + { x: 2, y: 4, color: '#FF69B4' }, + { x: 0, y: 5, color: '#FF69B4' }, + { x: 1, y: 5, color: '#FF69B4' }, + { x: 2, y: 5, color: '#FF69B4' }, + ], +}; + +/** 花朵 */ +export const FLOWER_7X7: ShapeTemplate = { + id: 'flower-7x7-001', + name: '花朵', + recommendedSize: { rows: 7, cols: 7 }, + category: 'nature', + difficulty: 3, + supportSymmetry: true, + symmetryType: 'both', + isComplete: false, + cells: [ + // 花瓣(左上半部分) + { x: 1, y: 0, color: '#FF69B4' }, + { x: 2, y: 0, color: '#FF69B4' }, + { x: 0, y: 1, color: '#FF69B4' }, + { x: 1, y: 1, color: '#FF69B4' }, + { x: 2, y: 1, color: '#FF69B4' }, + { x: 3, y: 1, color: '#FF69B4' }, // 对称轴上的点 + + // 花心(中心) + { x: 2, y: 2, color: '#FFFF00' }, + { x: 3, y: 2, color: '#FFFF00' }, // 对称轴上的点 + { x: 2, y: 3, color: '#FFFF00' }, + { x: 3, y: 3, color: '#FFFF00' }, // 对称轴上的点 + + // 茎(在对称轴上) + { x: 3, y: 4, color: '#00FF00' }, + { x: 3, y: 5, color: '#00FF00' }, + { x: 3, y: 6, color: '#00FF00' }, + ], +}; + +/** 所有 7x7 形状模板 */ +export const ALL_7X7_SHAPES: ShapeTemplate[] = [ + PUMPKIN_HEAD_7X7, + DINOSAUR_7X7, + HEART_7X7, + HOUSE_7X7, + BUTTERFLY_7X7, + FLOWER_7X7, +]; + +/** + * 随机获取一个 7x7 形状 + */ +export function getRandom7x7Shape(): ShapeTemplate { + const randomIndex = Math.floor(Math.random() * ALL_7X7_SHAPES.length); + return ALL_7X7_SHAPES[randomIndex]; +} diff --git a/miniprogram/focusPages/shared/types/gridTypes.ts b/miniprogram/focusPages/shared/types/gridTypes.ts new file mode 100644 index 0000000..2c880ff --- /dev/null +++ b/miniprogram/focusPages/shared/types/gridTypes.ts @@ -0,0 +1,59 @@ +/** + * 格子仿画类型定义 + */ + +/** 单个格子数据 */ +export interface GridCell { + /** X轴坐标,从0开始,表示第几列 */ + x: number; + /** Y轴坐标,从0开始,表示第几行 */ + y: number; + /** 颜色值,十六进制格式 */ + color: string; +} + +/** 网格配置 */ +export interface GridConfig { + /** 网格行数 */ + rows: number; + /** 网格列数 */ + cols: number; + /** 网格线颜色,默认为黑色 */ + gridLineColor?: string; + /** 网格线宽度,默认为1 */ + gridLineWidth?: number; +} + +/** 形状模板 */ +export interface ShapeTemplate { + /** 模板ID */ + id: string; + /** 形状名称 */ + name: string; + /** 推荐网格尺寸 */ + recommendedSize: { rows: number; cols: number }; + /** 形状数据(如果是对称形状,这里存储的是左半部分或上半部分) */ + cells: GridCell[]; + /** 颜色方案ID */ + colorSchemeId?: string; + /** 分类 */ + category: 'animal' | 'object' | 'geometric' | 'character' | 'nature'; + /** 难度等级 1-5 */ + difficulty: number; + /** 是否支持对称模式 */ + supportSymmetry: boolean; + /** 对称轴类型 */ + symmetryType?: 'vertical' | 'horizontal' | 'both'; + /** 是否已经是对称完整的图案(false表示只存储了半边) */ + isComplete?: boolean; +} + +/** 颜色方案 */ +export const COLOR_SCHEMES: Record = { + basic: ['#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF'], + warm: ['#FF0000', '#FF7F00', '#FFFF00', '#FF69B4', '#FF4500'], + cool: ['#00FFFF', '#0000FF', '#8A2BE2', '#00FF00', '#87CEEB'], + halloween: ['#FF7F00', '#FFFF00', '#000000', '#90EE90', '#FF0000'], + nature: ['#00FF00', '#90EE90', '#006400', '#FFFF00', '#8B4513'], + rainbow: ['#FF0000', '#FF7F00', '#FFFF00', '#00FF00', '#0000FF', '#8A2BE2'], +}; diff --git a/miniprogram/focusPages/shared/utils/gridUtils.ts b/miniprogram/focusPages/shared/utils/gridUtils.ts new file mode 100644 index 0000000..dbdd30b --- /dev/null +++ b/miniprogram/focusPages/shared/utils/gridUtils.ts @@ -0,0 +1,108 @@ +/** + * 格子仿画工具函数 + * 提供对称图案生成等功能 + */ + +import { GridCell, GridConfig, ShapeTemplate } from '../types/gridTypes'; + +/** + * 移除重复的格子(保留最后一个) + */ +function removeDuplicateCells(cells: GridCell[]): GridCell[] { + const cellMap = new Map(); + + // 从后往前遍历,保留最后出现的格子 + for (let i = cells.length - 1; i >= 0; i--) { + const cell = cells[i]; + const key = `${cell.x},${cell.y}`; + if (!cellMap.has(key)) { + cellMap.set(key, cell); + } + } + + return Array.from(cellMap.values()); +} + +/** + * 根据对称轴类型,将半部分图案补全为完整图案 + * @param halfCells 半部分格子的数据(通常是左半部分或上半部分) + * @param config 网格配置 + * @param symmetryType 对称类型 + * @returns 完整的格子数据 + */ +export function generateSymmetricalPattern( + halfCells: GridCell[], + config: GridConfig, + symmetryType: 'vertical' | 'horizontal' | 'both', +): GridCell[] { + const result: GridCell[] = [...halfCells]; + const { rows, cols } = config; + + if (symmetryType === 'vertical' || symmetryType === 'both') { + // 垂直对称(关于中间列对称) + const verticalAxis = Math.floor(cols / 2); + const cellsToAdd: GridCell[] = []; + + for (const cell of halfCells) { + // 如果格子不在对称轴上,生成对称的格子 + if (cell.x < verticalAxis) { + const symmetricX = cols - 1 - cell.x; + cellsToAdd.push({ + x: symmetricX, + y: cell.y, + color: cell.color, + }); + } + } + result.push(...cellsToAdd); + } + + if (symmetryType === 'horizontal' || symmetryType === 'both') { + // 水平对称(关于中间行对称) + const horizontalAxis = Math.floor(rows / 2); + const cellsToAdd: GridCell[] = []; + + for (const cell of result) { + // 如果格子不在对称轴上,生成对称的格子 + if (cell.y < horizontalAxis) { + const symmetricY = rows - 1 - cell.y; + cellsToAdd.push({ + x: cell.x, + y: symmetricY, + color: cell.color, + }); + } + } + result.push(...cellsToAdd); + } + + // 去重(避免对称轴上的格子重复) + return removeDuplicateCells(result); +} + +/** + * 从形状模板生成完整的格子数据 + * @param template 形状模板 + * @returns 完整的格子数据 + */ +export function generateCompletePattern(template: ShapeTemplate): GridCell[] { + if (template.isComplete) { + // 如果已经是完整图案,直接返回 + return [...template.cells]; + } + + if (template.supportSymmetry && template.symmetryType) { + // 使用对称生成完整图案 + return generateSymmetricalPattern( + template.cells, + { + rows: template.recommendedSize.rows, + cols: template.recommendedSize.cols, + }, + template.symmetryType, + ); + } + + // 如果不支持对称,返回原数据 + return [...template.cells]; +} diff --git a/miniprogram/mathPages/REFACTOR_PLAN.md b/miniprogram/mathPages/REFACTOR_PLAN.md index a20f3d0..cfb74c7 100644 --- a/miniprogram/mathPages/REFACTOR_PLAN.md +++ b/miniprogram/mathPages/REFACTOR_PLAN.md @@ -68,7 +68,7 @@ import MathBottomButtons from '../components/math-bottom-buttons/math-bottom-but ```typescript import AdditionDraw from '../shared/service/additionDraw'; import { createMathPage } from '../shared/common/mathPageMixin'; -import MathBottomButtons from '../shared/components/math-bottom-buttons/math-bottom-buttons'; +import MathBottomButtons from '../../components/math-bottom-buttons/math-bottom-buttons'; ``` #### service 文件之间的导入 diff --git a/miniprogram/mathPages/addition/addition.json b/miniprogram/mathPages/addition/addition.json index 6827d7b..049ced1 100644 --- a/miniprogram/mathPages/addition/addition.json +++ b/miniprogram/mathPages/addition/addition.json @@ -6,7 +6,7 @@ "enablePullDownRefresh": false, "usingComponents": { "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-type-selector": "../shared/components/math-type-selector/math-type-selector", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons" + "math-type-selector": "../../components/math-type-selector/math-type-selector", + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" } } diff --git a/miniprogram/mathPages/addition/addition.less b/miniprogram/mathPages/addition/addition.less index 65d3fba..f0ebb3c 100644 --- a/miniprogram/mathPages/addition/addition.less +++ b/miniprogram/mathPages/addition/addition.less @@ -1 +1 @@ -@import '../shared/common/mathPage.less'; \ No newline at end of file +@import '../../base/baseDrawPage.less'; \ No newline at end of file diff --git a/miniprogram/mathPages/assets/food/1.png b/miniprogram/mathPages/assets/food/1.png new file mode 100644 index 0000000..e5dccb4 Binary files /dev/null and b/miniprogram/mathPages/assets/food/1.png differ diff --git a/miniprogram/mathPages/assets/food/10.png b/miniprogram/mathPages/assets/food/10.png new file mode 100644 index 0000000..8b59400 Binary files /dev/null and b/miniprogram/mathPages/assets/food/10.png differ diff --git a/miniprogram/mathPages/assets/food/11.png b/miniprogram/mathPages/assets/food/11.png new file mode 100644 index 0000000..ca42d8d Binary files /dev/null and b/miniprogram/mathPages/assets/food/11.png differ diff --git a/miniprogram/mathPages/assets/food/12.png b/miniprogram/mathPages/assets/food/12.png new file mode 100644 index 0000000..4a11b27 Binary files /dev/null and b/miniprogram/mathPages/assets/food/12.png differ diff --git a/miniprogram/mathPages/assets/food/13.png b/miniprogram/mathPages/assets/food/13.png new file mode 100644 index 0000000..2524464 Binary files /dev/null and b/miniprogram/mathPages/assets/food/13.png differ diff --git a/miniprogram/mathPages/assets/food/14.png b/miniprogram/mathPages/assets/food/14.png new file mode 100644 index 0000000..a57edb0 Binary files /dev/null and b/miniprogram/mathPages/assets/food/14.png differ diff --git a/miniprogram/mathPages/assets/food/15.png b/miniprogram/mathPages/assets/food/15.png new file mode 100644 index 0000000..bc6f1f7 Binary files /dev/null and b/miniprogram/mathPages/assets/food/15.png differ diff --git a/miniprogram/mathPages/assets/food/16.png b/miniprogram/mathPages/assets/food/16.png new file mode 100644 index 0000000..e2e3618 Binary files /dev/null and b/miniprogram/mathPages/assets/food/16.png differ diff --git a/miniprogram/mathPages/assets/food/17.png b/miniprogram/mathPages/assets/food/17.png new file mode 100644 index 0000000..91f90d9 Binary files /dev/null and b/miniprogram/mathPages/assets/food/17.png differ diff --git a/miniprogram/mathPages/assets/food/18.png b/miniprogram/mathPages/assets/food/18.png new file mode 100644 index 0000000..55295d6 Binary files /dev/null and b/miniprogram/mathPages/assets/food/18.png differ diff --git a/miniprogram/mathPages/assets/food/19.png b/miniprogram/mathPages/assets/food/19.png new file mode 100644 index 0000000..90ebd59 Binary files /dev/null and b/miniprogram/mathPages/assets/food/19.png differ diff --git a/miniprogram/mathPages/assets/food/2.png b/miniprogram/mathPages/assets/food/2.png new file mode 100644 index 0000000..74a8d04 Binary files /dev/null and b/miniprogram/mathPages/assets/food/2.png differ diff --git a/miniprogram/mathPages/assets/food/20.png b/miniprogram/mathPages/assets/food/20.png new file mode 100644 index 0000000..6c2273d Binary files /dev/null and b/miniprogram/mathPages/assets/food/20.png differ diff --git a/miniprogram/mathPages/assets/food/3.png b/miniprogram/mathPages/assets/food/3.png new file mode 100644 index 0000000..ffd6a74 Binary files /dev/null and b/miniprogram/mathPages/assets/food/3.png differ diff --git a/miniprogram/mathPages/assets/food/4.png b/miniprogram/mathPages/assets/food/4.png new file mode 100644 index 0000000..1c9b708 Binary files /dev/null and b/miniprogram/mathPages/assets/food/4.png differ diff --git a/miniprogram/mathPages/assets/food/5.png b/miniprogram/mathPages/assets/food/5.png new file mode 100644 index 0000000..2623d83 Binary files /dev/null and b/miniprogram/mathPages/assets/food/5.png differ diff --git a/miniprogram/mathPages/assets/food/6.png b/miniprogram/mathPages/assets/food/6.png new file mode 100644 index 0000000..6642fc1 Binary files /dev/null and b/miniprogram/mathPages/assets/food/6.png differ diff --git a/miniprogram/mathPages/assets/food/7.png b/miniprogram/mathPages/assets/food/7.png new file mode 100644 index 0000000..e2483bf Binary files /dev/null and b/miniprogram/mathPages/assets/food/7.png differ diff --git a/miniprogram/mathPages/assets/food/8.png b/miniprogram/mathPages/assets/food/8.png new file mode 100644 index 0000000..2fb4851 Binary files /dev/null and b/miniprogram/mathPages/assets/food/8.png differ diff --git a/miniprogram/mathPages/assets/food/9.png b/miniprogram/mathPages/assets/food/9.png new file mode 100644 index 0000000..f0650e9 Binary files /dev/null and b/miniprogram/mathPages/assets/food/9.png differ diff --git a/miniprogram/mathPages/compare/compare.json b/miniprogram/mathPages/compare/compare.json index 987054d..3daa7dd 100644 --- a/miniprogram/mathPages/compare/compare.json +++ b/miniprogram/mathPages/compare/compare.json @@ -7,6 +7,6 @@ "usingComponents": { "toy-button": "../../ui/button/button", "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons" + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" } } diff --git a/miniprogram/mathPages/compare/compare.less b/miniprogram/mathPages/compare/compare.less index 65d3fba..f0ebb3c 100644 --- a/miniprogram/mathPages/compare/compare.less +++ b/miniprogram/mathPages/compare/compare.less @@ -1 +1 @@ -@import '../shared/common/mathPage.less'; \ No newline at end of file +@import '../../base/baseDrawPage.less'; \ No newline at end of file diff --git a/miniprogram/mathPages/countMatch/countMatch.json b/miniprogram/mathPages/countMatch/countMatch.json index 9eda340..121f4e1 100644 --- a/miniprogram/mathPages/countMatch/countMatch.json +++ b/miniprogram/mathPages/countMatch/countMatch.json @@ -6,7 +6,7 @@ "enablePullDownRefresh": false, "usingComponents": { "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-type-selector": "../shared/components/math-type-selector/math-type-selector", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons" + "math-type-selector": "../../components/math-type-selector/math-type-selector", + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" } } diff --git a/miniprogram/mathPages/countMatch/countMatch.less b/miniprogram/mathPages/countMatch/countMatch.less index 65d3fba..f0ebb3c 100644 --- a/miniprogram/mathPages/countMatch/countMatch.less +++ b/miniprogram/mathPages/countMatch/countMatch.less @@ -1 +1 @@ -@import '../shared/common/mathPage.less'; \ No newline at end of file +@import '../../base/baseDrawPage.less'; \ No newline at end of file diff --git a/miniprogram/mathPages/countingSelect/countingSelect.json b/miniprogram/mathPages/countingSelect/countingSelect.json index a49ce52..f9ddedb 100644 --- a/miniprogram/mathPages/countingSelect/countingSelect.json +++ b/miniprogram/mathPages/countingSelect/countingSelect.json @@ -7,6 +7,6 @@ "usingComponents": { "toy-button": "../../ui/button/button", "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons" + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" } } diff --git a/miniprogram/mathPages/countingSelect/countingSelect.less b/miniprogram/mathPages/countingSelect/countingSelect.less index 65d3fba..f0ebb3c 100644 --- a/miniprogram/mathPages/countingSelect/countingSelect.less +++ b/miniprogram/mathPages/countingSelect/countingSelect.less @@ -1 +1 @@ -@import '../shared/common/mathPage.less'; \ No newline at end of file +@import '../../base/baseDrawPage.less'; \ No newline at end of file diff --git a/miniprogram/mathPages/missingNumber/missingNumber.json b/miniprogram/mathPages/missingNumber/missingNumber.json index 42774ef..caa0eb5 100644 --- a/miniprogram/mathPages/missingNumber/missingNumber.json +++ b/miniprogram/mathPages/missingNumber/missingNumber.json @@ -6,7 +6,7 @@ "enablePullDownRefresh": false, "usingComponents": { "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-type-selector": "../shared/components/math-type-selector/math-type-selector", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons" + "math-type-selector": "../../components/math-type-selector/math-type-selector", + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" } } diff --git a/miniprogram/mathPages/missingNumber/missingNumber.less b/miniprogram/mathPages/missingNumber/missingNumber.less index 65d3fba..f0ebb3c 100644 --- a/miniprogram/mathPages/missingNumber/missingNumber.less +++ b/miniprogram/mathPages/missingNumber/missingNumber.less @@ -1 +1 @@ -@import '../shared/common/mathPage.less'; \ No newline at end of file +@import '../../base/baseDrawPage.less'; \ No newline at end of file diff --git a/miniprogram/mathPages/numberDecompose/numberDecompose.json b/miniprogram/mathPages/numberDecompose/numberDecompose.json index 7eaffeb..5f0ae20 100644 --- a/miniprogram/mathPages/numberDecompose/numberDecompose.json +++ b/miniprogram/mathPages/numberDecompose/numberDecompose.json @@ -6,7 +6,7 @@ "enablePullDownRefresh": false, "usingComponents": { "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons", - "math-type-selector": "../shared/components/math-type-selector/math-type-selector" + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons", + "math-type-selector": "../../components/math-type-selector/math-type-selector" } } diff --git a/miniprogram/mathPages/numberDecompose/numberDecompose.less b/miniprogram/mathPages/numberDecompose/numberDecompose.less index 65d3fba..f0ebb3c 100644 --- a/miniprogram/mathPages/numberDecompose/numberDecompose.less +++ b/miniprogram/mathPages/numberDecompose/numberDecompose.less @@ -1 +1 @@ -@import '../shared/common/mathPage.less'; \ No newline at end of file +@import '../../base/baseDrawPage.less'; \ No newline at end of file diff --git a/miniprogram/mathPages/numberFind/numberFind.json b/miniprogram/mathPages/numberFind/numberFind.json index 716541c..526bbaf 100644 --- a/miniprogram/mathPages/numberFind/numberFind.json +++ b/miniprogram/mathPages/numberFind/numberFind.json @@ -7,6 +7,6 @@ "usingComponents": { "toy-button": "../../ui/button/button", "share-guide-popup": "../../components/share-guide-popup/share-guide-popup", - "math-bottom-buttons": "../shared/components/math-bottom-buttons/math-bottom-buttons" + "math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons" } } diff --git a/miniprogram/mathPages/numberFind/numberFind.less b/miniprogram/mathPages/numberFind/numberFind.less index 2d3aac0..f9d5a8d 100644 --- a/miniprogram/mathPages/numberFind/numberFind.less +++ b/miniprogram/mathPages/numberFind/numberFind.less @@ -1,4 +1,4 @@ -@import '../shared/common/mathPage.less'; +@import '../../base/baseDrawPage.less'; /* 数字选择区域 */ .number-selection-area { diff --git a/miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.json b/miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.json deleted file mode 100644 index 25326c0..0000000 --- a/miniprogram/mathPages/shared/components/math-type-selector/math-type-selector.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "component": true, - "usingComponents": { - "toy-button": "../../../../ui/button/button", - "van-action-sheet": "../../../../miniprogram_npm/@vant/weapp/action-sheet/index" - } -} diff --git a/miniprogram/pages/focusIndex/focusIndex.json b/miniprogram/pages/focusIndex/focusIndex.json new file mode 100644 index 0000000..8376a1d --- /dev/null +++ b/miniprogram/pages/focusIndex/focusIndex.json @@ -0,0 +1,8 @@ +{ + "navigationBarTitleText": "涂鸦丫-专注力", + "navigationBarBackgroundColor": "#FFD719", + "homeButton": true, + "backgroundColor": "#F6F6F6", + "enablePullDownRefresh": false, + "usingComponents": {} +} diff --git a/miniprogram/pages/focusIndex/focusIndex.less b/miniprogram/pages/focusIndex/focusIndex.less new file mode 100644 index 0000000..0ab6212 --- /dev/null +++ b/miniprogram/pages/focusIndex/focusIndex.less @@ -0,0 +1,171 @@ +page { + background-color: #f6f6f6; +} + +.page-container { + background-color: #f6f6f6; + padding: 0 24rpx; + box-sizing: border-box; + + .empty { + height: 190rpx; + } +} + +/* 专注力页面标题和描述 */ +.math-page-header { + margin-bottom: 40rpx; + text-align: center; + padding-top: 28rpx; +} + +.math-page-title { + font-size: 36rpx; + font-weight: 600; + color: #141414; + margin-bottom: 16rpx; +} + +.math-page-subtitle { + font-size: 24rpx; + color: #666666; + line-height: 1.5; +} + +/* 专注力功能列表样式 */ +.math-functions-list { + display: flex; + flex-direction: column; + gap: 24rpx; + margin-bottom: 40rpx; +} + +.math-function-item { + background: #ffffff; + border: 2rpx solid #e8e8e8; + border-radius: 24rpx; + padding: 32rpx; + display: flex; + align-items: center; + gap: 24rpx; + transition: all 0.2s ease-in-out; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); + position: relative; + + &::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 24rpx; + opacity: 0; + background: rgba(147, 211, 51, 0.1); + transition: opacity 0.2s ease-in-out; + } + + &:active { + &::after { + opacity: 1; + } + + border-color: #93d333; + box-shadow: 0 8rpx 24rpx rgba(147, 211, 51, 0.2); + } +} + +.function-item-image { + width: 120rpx; + height: 120rpx; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + position: relative; + z-index: 1; +} + +.function-image-placeholder { + width: 100%; + height: 100%; + background: linear-gradient(135deg, rgba(255, 215, 25, 0.2) 0%, rgba(255, 169, 64, 0.2) 100%); + border-radius: 20rpx; + display: flex; + align-items: center; + justify-content: center; + font-size: 56rpx; +} + +.function-item-content { + flex: 1; + display: flex; + flex-direction: column; + gap: 12rpx; + min-width: 0; + position: relative; + z-index: 1; +} + +.function-item-title { + font-size: 28rpx; + font-weight: 600; + color: #141414; + line-height: 1.4; +} + +.function-item-desc { + font-size: 24rpx; + color: #666666; + line-height: 1.4; +} + +.function-item-arrow { + font-size: 36rpx; + color: #999999; + flex-shrink: 0; + position: relative; + z-index: 1; +} + +/* 使用提示 */ +.usage-hint { + background: linear-gradient(135deg, #fff7e6 0%, #fffbe6 100%); + border: 2rpx solid #ffd719; + border-radius: 24rpx; + padding: 32rpx; + display: flex; + align-items: flex-start; + gap: 24rpx; + box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05); +} + +.hint-icon { + font-size: 40rpx; + flex-shrink: 0; +} + +.hint-text { + flex: 1; +} + +.hint-title { + font-size: 28rpx; + font-weight: 600; + color: #141414; + margin-bottom: 8rpx; +} + +.hint-desc { + font-size: 24rpx; + color: #666666; + line-height: 1.5; + + view { + margin-bottom: 8rpx; + + &:last-child { + margin-bottom: 0; + } + } +} \ No newline at end of file diff --git a/miniprogram/pages/focusIndex/focusIndex.ts b/miniprogram/pages/focusIndex/focusIndex.ts new file mode 100644 index 0000000..d53262d --- /dev/null +++ b/miniprogram/pages/focusIndex/focusIndex.ts @@ -0,0 +1,38 @@ +import { FOCUS_FUNCTION_TYPES } from '../../constants/focusFunctions'; + +Page({ + data: { + functionList: FOCUS_FUNCTION_TYPES, + }, + + onLoad() { + // 页面加载 + }, + + /** + * 打开专注力功能页面 + */ + openFocusFunction(e: WechatMiniprogram.TouchEvent) { + const functionId = e.currentTarget.dataset.function; + const functionItem = this.data.functionList.find( + (item) => item.id === functionId, + ); + + if (!functionItem) { + return; + } + + // 如果有page字段,跳转到对应页面 + if (functionItem.page) { + wx.navigateTo({ + url: `/focusPages/${functionItem.page}/${functionItem.page}?id=${functionId}`, + }); + } else { + wx.showToast({ + title: `功能开发中,敬请期待`, + icon: 'none', + duration: 2500, + }); + } + }, +}); diff --git a/miniprogram/pages/focusIndex/focusIndex.wxml b/miniprogram/pages/focusIndex/focusIndex.wxml new file mode 100644 index 0000000..ee4c702 --- /dev/null +++ b/miniprogram/pages/focusIndex/focusIndex.wxml @@ -0,0 +1,43 @@ + + + + 专注力训练 + + 选择功能,生成可打印的专注力训练涂鸦卡 + + + + + + + + {{item.icon}} + + + {{item.title}} + {{item.desc}} + + + + + + + + 💡 + + 使用提示 + + 1. 点击上方功能卡片选择要生成的涂鸦卡类型 + 2. 选择网格尺寸等参数 + 3. 预览生成的涂鸦卡效果 + 4. 下载A4格式PNG图片,打印后使用 + + + + +