feat:2.5.0初始化专注启蒙项目
This commit is contained in:
+4
-11
@@ -3,7 +3,6 @@
|
|||||||
"pages/mathIndex/mathIndex",
|
"pages/mathIndex/mathIndex",
|
||||||
"pages/focusIndex/focusIndex",
|
"pages/focusIndex/focusIndex",
|
||||||
"pages/index/index",
|
"pages/index/index",
|
||||||
"pages/shape/index",
|
|
||||||
"pages/copyBook/copyBook",
|
"pages/copyBook/copyBook",
|
||||||
"pages/debug/debug"
|
"pages/debug/debug"
|
||||||
],
|
],
|
||||||
@@ -25,7 +24,7 @@
|
|||||||
{
|
{
|
||||||
"root": "focusPages",
|
"root": "focusPages",
|
||||||
"name": "focusPages",
|
"name": "focusPages",
|
||||||
"pages": ["gridDrawing/gridDrawing"],
|
"pages": ["gridDrawing/gridDrawing", "shape/shape"],
|
||||||
"independent": false
|
"independent": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -71,9 +70,9 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/focusIndex/focusIndex",
|
"pagePath": "pages/focusIndex/focusIndex",
|
||||||
"iconPath": "assets/tabBar/icon-word.png",
|
"iconPath": "assets/tabBar/icon-shape.png",
|
||||||
"selectedIconPath": "assets/tabBar/icon-word-active.png",
|
"selectedIconPath": "assets/tabBar/icon-shape-active.png",
|
||||||
"text": "专注力"
|
"text": "专注启蒙"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"pagePath": "pages/index/index",
|
"pagePath": "pages/index/index",
|
||||||
@@ -81,12 +80,6 @@
|
|||||||
"selectedIconPath": "assets/tabBar/icon-word-active.png",
|
"selectedIconPath": "assets/tabBar/icon-word-active.png",
|
||||||
"text": "识字"
|
"text": "识字"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"pagePath": "pages/shape/index",
|
|
||||||
"iconPath": "assets/tabBar/icon-shape.png",
|
|
||||||
"selectedIconPath": "assets/tabBar/icon-shape-active.png",
|
|
||||||
"text": "图形"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"pagePath": "pages/copyBook/copyBook",
|
"pagePath": "pages/copyBook/copyBook",
|
||||||
"iconPath": "assets/tabBar/icon-edit.png",
|
"iconPath": "assets/tabBar/icon-edit.png",
|
||||||
|
|||||||
@@ -85,40 +85,6 @@ export const WATER_COLORS = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 数字颜色映射(柔和12色)
|
|
||||||
* 用于数学页面的数字显示和涂色
|
|
||||||
*/
|
|
||||||
export const NUMBER_COLORS: Record<number, string> = {
|
|
||||||
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)];
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PAPER_SIZE = {
|
export const PAPER_SIZE = {
|
||||||
A4: {
|
A4: {
|
||||||
// width: 2480,
|
// width: 2480,
|
||||||
|
|||||||
@@ -4,15 +4,41 @@ export interface FocusFunctionType {
|
|||||||
title: string;
|
title: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
|
mode?: string; // 用于传递默认模式参数,如 '3x3', '5x5', '7x7'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [
|
export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [
|
||||||
|
// 形状识别
|
||||||
|
{
|
||||||
|
id: 'shape-recognition',
|
||||||
|
page: 'shape',
|
||||||
|
title: '识别形状',
|
||||||
|
desc: '识别形状,涂一涂',
|
||||||
|
icon: '🔍',
|
||||||
|
},
|
||||||
// 格子仿画
|
// 格子仿画
|
||||||
{
|
{
|
||||||
id: 'grid-drawing',
|
id: 'grid-drawing-3x3',
|
||||||
page: 'gridDrawing',
|
page: 'gridDrawing',
|
||||||
title: '格子仿画',
|
title: '格子仿画 3x3',
|
||||||
desc: '在网格中填充颜色,形成各种形状',
|
desc: '🎯 简单有趣,培养专注力',
|
||||||
icon: '🎨',
|
icon: '🎨',
|
||||||
|
mode: '3x3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'grid-drawing-5x5',
|
||||||
|
page: 'gridDrawing',
|
||||||
|
title: '格子仿画 5x5',
|
||||||
|
desc: '✨ 创意挑战,提升观察力',
|
||||||
|
icon: '🎨',
|
||||||
|
mode: '5x5',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'grid-drawing-7x7',
|
||||||
|
page: 'gridDrawing',
|
||||||
|
title: '格子仿画 7x7',
|
||||||
|
desc: '🌟 大师挑战,锻炼耐心',
|
||||||
|
icon: '🎨',
|
||||||
|
mode: '7x7',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -110,3 +110,37 @@ export const MATH_FUNCTION_TYPES: MathFunctionType[] = [
|
|||||||
icon: '🔢',
|
icon: '🔢',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数字颜色映射(柔和12色)
|
||||||
|
* 用于数学页面的数字显示和涂色
|
||||||
|
*/
|
||||||
|
export const NUMBER_COLORS: Record<number, string> = {
|
||||||
|
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)];
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ALL_5X5_SHAPES } from '../shared/shapes/gridShapes5x5';
|
|||||||
import { ALL_7X7_SHAPES } from '../shared/shapes/gridShapes7x7';
|
import { ALL_7X7_SHAPES } from '../shared/shapes/gridShapes7x7';
|
||||||
import { ShapeTemplate, GridCell } from '../shared/types/gridTypes';
|
import { ShapeTemplate, GridCell } from '../shared/types/gridTypes';
|
||||||
import { GridConfig } from '../shared/types/gridTypes';
|
import { GridConfig } from '../shared/types/gridTypes';
|
||||||
|
import { FOCUS_FUNCTION_TYPES } from '../../constants/focusFunctions';
|
||||||
|
|
||||||
createFocusPage({
|
createFocusPage({
|
||||||
canvas: null as Canvas | null,
|
canvas: null as Canvas | null,
|
||||||
@@ -17,12 +18,13 @@ createFocusPage({
|
|||||||
gridData: null as GridDrawingData | null,
|
gridData: null as GridDrawingData | null,
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
pageTitle: '格子仿画',
|
pageTitle: '格子仿画 5×5',
|
||||||
functionId: '',
|
functionId: '',
|
||||||
hasContent: false,
|
hasContent: false,
|
||||||
showShareDialog: false,
|
showShareDialog: false,
|
||||||
currentMode: '3x3', // '3x3', '5x5', '7x7'
|
currentMode: '3x3', // '3x3', '5x5', '7x7'
|
||||||
currentModeName: '3×3',
|
currentModeName: '3×3',
|
||||||
|
subTitle: '', // 副标题,从配置中获取
|
||||||
typeActions: [
|
typeActions: [
|
||||||
{ name: '3×3', value: '3x3' },
|
{ name: '3×3', value: '3x3' },
|
||||||
{ name: '5×5', value: '5x5' },
|
{ name: '5×5', value: '5x5' },
|
||||||
@@ -30,10 +32,30 @@ createFocusPage({
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad(options: { id?: string }) {
|
onLoad(options: { id?: string; mode?: string }) {
|
||||||
const functionId = options.id || 'grid-drawing';
|
const functionId = options.id || 'grid-drawing';
|
||||||
|
const mode = options.mode || '3x3'; // 从参数中读取 mode,默认为 '3x3'
|
||||||
|
|
||||||
|
// 根据 mode 设置对应的模式名称
|
||||||
|
const modeNameMap: Record<string, string> = {
|
||||||
|
'3x3': '3×3',
|
||||||
|
'5x5': '5×5',
|
||||||
|
'7x7': '7×7',
|
||||||
|
};
|
||||||
|
const currentModeName = modeNameMap[mode] || '3×3';
|
||||||
|
|
||||||
|
// 根据 mode 查找配置,获取 desc 作为 subTitle
|
||||||
|
const configItem = FOCUS_FUNCTION_TYPES.find(
|
||||||
|
(item) => item.mode === mode && item.id?.startsWith('grid-drawing'),
|
||||||
|
);
|
||||||
|
const subTitle = configItem?.desc || '在网格中填充颜色,形成各种形状';
|
||||||
|
|
||||||
this.setData({
|
this.setData({
|
||||||
|
pageTitle: `格子仿画 ${mode}`,
|
||||||
functionId,
|
functionId,
|
||||||
|
currentMode: mode,
|
||||||
|
currentModeName,
|
||||||
|
subTitle,
|
||||||
});
|
});
|
||||||
this.initPageInfo(functionId, '格子仿画');
|
this.initPageInfo(functionId, '格子仿画');
|
||||||
},
|
},
|
||||||
@@ -48,7 +70,9 @@ createFocusPage({
|
|||||||
return new GridDraw(canvas, ctx, options);
|
return new GridDraw(canvas, ctx, options);
|
||||||
},
|
},
|
||||||
drawServiceOptions: {
|
drawServiceOptions: {
|
||||||
subTitle: '在网格中填充颜色,形成各种形状',
|
title: this.data.pageTitle,
|
||||||
|
subTitle:
|
||||||
|
this.data.subTitle || '在网格中填充颜色,形成各种形状',
|
||||||
functionId: this.data.functionId,
|
functionId: this.data.functionId,
|
||||||
},
|
},
|
||||||
onCanvasReady: () => {
|
onCanvasReady: () => {
|
||||||
@@ -67,11 +91,6 @@ createFocusPage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 更新 Header 的 Title
|
|
||||||
if (this.drawService) {
|
|
||||||
this.drawService.options.title = this.data.currentModeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.drawService.draw(this.gridData);
|
await this.drawService.draw(this.gridData);
|
||||||
this.setData({ hasContent: true });
|
this.setData({ hasContent: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -129,7 +148,7 @@ createFocusPage({
|
|||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
const shapeIndex = i % availableShapes.length;
|
const shapeIndex = i % availableShapes.length;
|
||||||
const shape = availableShapes[shapeIndex];
|
const shape = availableShapes[shapeIndex];
|
||||||
const cells = generateCompletePattern(shape);
|
const cells = generateCompletePattern(shape, config);
|
||||||
|
|
||||||
// 生成图案签名
|
// 生成图案签名
|
||||||
const patternSignature = cells
|
const patternSignature = cells
|
||||||
@@ -152,7 +171,10 @@ createFocusPage({
|
|||||||
let found = false;
|
let found = false;
|
||||||
for (let j = 0; j < availableShapes.length; j++) {
|
for (let j = 0; j < availableShapes.length; j++) {
|
||||||
const nextShape = availableShapes[j];
|
const nextShape = availableShapes[j];
|
||||||
const nextCells = generateCompletePattern(nextShape);
|
const nextCells = generateCompletePattern(
|
||||||
|
nextShape,
|
||||||
|
config,
|
||||||
|
);
|
||||||
const nextSignature = nextCells
|
const nextSignature = nextCells
|
||||||
.map((c) => `${c.x},${c.y},${c.color}`)
|
.map((c) => `${c.x},${c.y},${c.color}`)
|
||||||
.sort()
|
.sort()
|
||||||
@@ -205,12 +227,12 @@ createFocusPage({
|
|||||||
allShapes = ALL_3X3_SHAPES;
|
allShapes = ALL_3X3_SHAPES;
|
||||||
config = { rows: 3, cols: 3 };
|
config = { rows: 3, cols: 3 };
|
||||||
groupsPerRow = 2; // 每行2组
|
groupsPerRow = 2; // 每行2组
|
||||||
totalRows = 3; // 总共3行
|
totalRows = 4; // 总共3行
|
||||||
} else if (mode === '5x5') {
|
} else if (mode === '5x5') {
|
||||||
allShapes = ALL_5X5_SHAPES;
|
allShapes = ALL_5X5_SHAPES;
|
||||||
config = { rows: 5, cols: 5 };
|
config = { rows: 5, cols: 5 };
|
||||||
groupsPerRow = 2;
|
groupsPerRow = 2;
|
||||||
totalRows = 2; // 5x5可以展示2行
|
totalRows = 4; // 5x5可以展示2行
|
||||||
} else {
|
} else {
|
||||||
// 7x7
|
// 7x7
|
||||||
allShapes = ALL_7X7_SHAPES;
|
allShapes = ALL_7X7_SHAPES;
|
||||||
@@ -240,10 +262,30 @@ createFocusPage({
|
|||||||
/** 选择类型 */
|
/** 选择类型 */
|
||||||
onSelectType(event: any) {
|
onSelectType(event: any) {
|
||||||
const { name, value } = event.detail;
|
const { name, value } = event.detail;
|
||||||
|
|
||||||
|
// 根据 mode 查找配置,获取 desc 作为 subTitle
|
||||||
|
const configItem = FOCUS_FUNCTION_TYPES.find(
|
||||||
|
(item) =>
|
||||||
|
item.mode === value && item.id?.startsWith('grid-drawing'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const pageTitle = `格子仿画 ${value}`;
|
||||||
|
const subTitle = configItem?.desc || '在网格中填充颜色,形成各种形状';
|
||||||
|
|
||||||
|
// 更新 pageTitle、currentMode、currentModeName 和 subTitle
|
||||||
this.setData({
|
this.setData({
|
||||||
|
pageTitle,
|
||||||
currentMode: value,
|
currentMode: value,
|
||||||
currentModeName: name,
|
currentModeName: name,
|
||||||
|
subTitle,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 更新绘制服务的 title 和 subTitle
|
||||||
|
if (this.drawService) {
|
||||||
|
this.drawService.options.title = pageTitle;
|
||||||
|
this.drawService.options.subTitle = subTitle;
|
||||||
|
}
|
||||||
|
|
||||||
// 重新生成数据
|
// 重新生成数据
|
||||||
this.onRandom();
|
this.onRandom();
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"navigationBarTitleText": "涂鸦丫-认识图形",
|
"navigationBarTitleText": "识别图形,涂一涂",
|
||||||
"navigationBarBackgroundColor": "#FFD719",
|
"navigationBarBackgroundColor": "#FFD719",
|
||||||
"homeButton": true,
|
"homeButton": true,
|
||||||
"backgroundColor": "#F6F6F6",
|
"backgroundColor": "#F6F6F6",
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<view class="page-container">
|
<view class="page-container">
|
||||||
<view class="wrapper">
|
<view class="wrapper">
|
||||||
<text class="wrapper-title">自定义涂鸦卡</text>
|
<text class="wrapper-title">识别图形,涂一涂</text>
|
||||||
<view class="btn-area">
|
<view class="btn-area">
|
||||||
<toy-button
|
<toy-button
|
||||||
type="green"
|
type="green"
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { createPage, PageCommonMethodsConfig } from '../../../base/pageMixin';
|
import { createPage, PageCommonMethodsConfig } from '../../../base/pageMixin';
|
||||||
|
import { FOCUS_FUNCTION_TYPES } from '../../../constants/focusFunctions';
|
||||||
/**
|
/**
|
||||||
* 专注力模块的函数类型定义
|
* 专注力模块的函数类型定义
|
||||||
*/
|
*/
|
||||||
@@ -14,24 +14,6 @@ export interface FocusFunctionType {
|
|||||||
desc: string;
|
desc: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 专注力模块的函数列表
|
|
||||||
* TODO: 根据实际需求补充完整的功能列表
|
|
||||||
*/
|
|
||||||
export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [
|
|
||||||
{
|
|
||||||
id: 'grid-drawing',
|
|
||||||
title: '格子仿画',
|
|
||||||
desc: '在格子中绘制颜色,形成各种形状',
|
|
||||||
},
|
|
||||||
// 可以在这里添加更多专注力相关的功能
|
|
||||||
// {
|
|
||||||
// id: 'pattern-memory',
|
|
||||||
// title: '图案记忆',
|
|
||||||
// desc: '记住并重现图案',
|
|
||||||
// },
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 专注力模块的分享配置
|
* 专注力模块的分享配置
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -84,29 +84,54 @@ class GridDraw extends BaseDrawService {
|
|||||||
canvasWidth: number;
|
canvasWidth: number;
|
||||||
startY: number;
|
startY: number;
|
||||||
}): Promise<void> {
|
}): Promise<void> {
|
||||||
const { ctx, gridData, canvasWidth, startY } = params;
|
const { ctx, gridData, canvasWidth } = params;
|
||||||
|
let { startY } = params;
|
||||||
const { config, groups, groupsPerRow, totalRows } = gridData;
|
const { config, groups, groupsPerRow, totalRows } = gridData;
|
||||||
const { rows, cols } = config;
|
const { rows, cols } = config;
|
||||||
|
|
||||||
|
startY = startY + 30;
|
||||||
|
|
||||||
// 计算网格尺寸
|
// 计算网格尺寸
|
||||||
const margin = 40; // 左右边距
|
const margin = 40; // 左右边距
|
||||||
const groupSpacing = 20; // 组之间的间距
|
const gridSpacing = 20; // 填充网格和空网格之间的间距
|
||||||
const rowSpacing = 30; // 行之间的间距
|
const groupSpacing = 40; // 两组之间的间距(一行中两组格子仿画中间)
|
||||||
const dividerWidth = 2; // 分割线宽度
|
const rowSpacing = 50; // 行之间的间距
|
||||||
|
const dividerWidth = 1; // 分割线宽度
|
||||||
|
|
||||||
// 计算每组网格的尺寸
|
// 计算每组网格的尺寸
|
||||||
const availableWidth = canvasWidth - margin * 2;
|
const availableWidth = canvasWidth - margin * 2;
|
||||||
const totalGroupsPerRow = groupsPerRow * 2; // 每组包含填充和空两个网格
|
const totalGridsPerRow = groupsPerRow * 2; // 每组包含填充和空两个网格
|
||||||
const groupWidth =
|
const gridWidth =
|
||||||
(availableWidth -
|
(availableWidth -
|
||||||
(groupsPerRow - 1) * dividerWidth -
|
(groupsPerRow - 1) * groupSpacing -
|
||||||
(totalGroupsPerRow - 1) * groupSpacing) /
|
(totalGridsPerRow - 1) * gridSpacing) /
|
||||||
totalGroupsPerRow;
|
totalGridsPerRow;
|
||||||
const cellSize = Math.floor(groupWidth / cols);
|
const cellSize = Math.floor(gridWidth / cols);
|
||||||
const gridWidth = cellSize * cols;
|
const actualGridWidth = cellSize * cols;
|
||||||
const gridHeight = cellSize * rows;
|
const gridHeight = cellSize * rows;
|
||||||
|
|
||||||
let currentY = startY + 30; // 顶部间距
|
const firstRowStartY = startY + 30; // 顶部间距
|
||||||
|
const lastRowEndY =
|
||||||
|
firstRowStartY +
|
||||||
|
totalRows * gridHeight +
|
||||||
|
(totalRows - 1) * rowSpacing;
|
||||||
|
|
||||||
|
// 计算第一行的起始X位置(居中)
|
||||||
|
const rowTotalWidth =
|
||||||
|
totalGridsPerRow * actualGridWidth +
|
||||||
|
(totalGridsPerRow - 1) * gridSpacing +
|
||||||
|
(groupsPerRow - 1) * groupSpacing;
|
||||||
|
const rowStartX = margin + (availableWidth - rowTotalWidth) / 2;
|
||||||
|
|
||||||
|
// 计算中间垂直分割线的X位置(两组之间的位置)
|
||||||
|
const middleDividerX =
|
||||||
|
groupsPerRow > 1
|
||||||
|
? rowStartX +
|
||||||
|
actualGridWidth +
|
||||||
|
gridSpacing +
|
||||||
|
actualGridWidth +
|
||||||
|
groupSpacing / 2
|
||||||
|
: null;
|
||||||
|
|
||||||
// 遍历每一行
|
// 遍历每一行
|
||||||
for (let rowIndex = 0; rowIndex < totalRows; rowIndex++) {
|
for (let rowIndex = 0; rowIndex < totalRows; rowIndex++) {
|
||||||
@@ -116,13 +141,8 @@ class GridDraw extends BaseDrawService {
|
|||||||
rowStartIndex + groupsPerRow,
|
rowStartIndex + groupsPerRow,
|
||||||
);
|
);
|
||||||
|
|
||||||
// 计算当前行的起始X位置(居中)
|
const currentY =
|
||||||
const rowTotalWidth =
|
firstRowStartY + rowIndex * (gridHeight + rowSpacing);
|
||||||
totalGroupsPerRow * gridWidth +
|
|
||||||
(totalGroupsPerRow - 1) * groupSpacing +
|
|
||||||
(groupsPerRow - 1) * dividerWidth;
|
|
||||||
const rowStartX = margin + (availableWidth - rowTotalWidth) / 2;
|
|
||||||
|
|
||||||
let currentX = rowStartX;
|
let currentX = rowStartX;
|
||||||
|
|
||||||
// 遍历当前行的每一组
|
// 遍历当前行的每一组
|
||||||
@@ -138,7 +158,7 @@ class GridDraw extends BaseDrawService {
|
|||||||
ctx,
|
ctx,
|
||||||
gridStartX: currentX,
|
gridStartX: currentX,
|
||||||
gridStartY: currentY,
|
gridStartY: currentY,
|
||||||
gridWidth,
|
gridWidth: actualGridWidth,
|
||||||
gridHeight,
|
gridHeight,
|
||||||
cellSize,
|
cellSize,
|
||||||
rows,
|
rows,
|
||||||
@@ -147,14 +167,14 @@ class GridDraw extends BaseDrawService {
|
|||||||
config,
|
config,
|
||||||
});
|
});
|
||||||
|
|
||||||
currentX += gridWidth + groupSpacing;
|
currentX += actualGridWidth + gridSpacing;
|
||||||
|
|
||||||
// 绘制空的网格(右侧)
|
// 绘制空的网格(右侧)
|
||||||
this.drawSingleGrid({
|
this.drawSingleGrid({
|
||||||
ctx,
|
ctx,
|
||||||
gridStartX: currentX,
|
gridStartX: currentX,
|
||||||
gridStartY: currentY,
|
gridStartY: currentY,
|
||||||
gridWidth,
|
gridWidth: actualGridWidth,
|
||||||
gridHeight,
|
gridHeight,
|
||||||
cellSize,
|
cellSize,
|
||||||
rows,
|
rows,
|
||||||
@@ -163,32 +183,39 @@ class GridDraw extends BaseDrawService {
|
|||||||
config,
|
config,
|
||||||
});
|
});
|
||||||
|
|
||||||
currentX += gridWidth;
|
currentX += actualGridWidth;
|
||||||
|
|
||||||
// 如果不是最后一组,绘制垂直分割线
|
// 如果不是最后一组,添加组间距
|
||||||
if (groupIndex < rowGroups.length - 1) {
|
if (groupIndex < rowGroups.length - 1) {
|
||||||
ctx.strokeStyle = '#000000';
|
currentX += groupSpacing;
|
||||||
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) {
|
if (rowIndex < totalRows - 1) {
|
||||||
ctx.strokeStyle = '#000000';
|
const lineY = currentY + gridHeight + rowSpacing / 2;
|
||||||
|
ctx.strokeStyle = '#999';
|
||||||
ctx.lineWidth = dividerWidth;
|
ctx.lineWidth = dividerWidth;
|
||||||
|
ctx.setLineDash([4, 4]); // 虚线
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(margin, currentY - rowSpacing / 2);
|
ctx.moveTo(margin, lineY);
|
||||||
ctx.lineTo(canvasWidth - margin, currentY - rowSpacing / 2);
|
ctx.lineTo(canvasWidth - margin, lineY);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]); // 重置为实线
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 绘制中间垂直分割线(贯穿所有行)
|
||||||
|
if (middleDividerX !== null && groupsPerRow > 1) {
|
||||||
|
ctx.strokeStyle = '#999';
|
||||||
|
ctx.lineWidth = dividerWidth;
|
||||||
|
ctx.setLineDash([4, 4]); // 虚线
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(middleDividerX, firstRowStartY);
|
||||||
|
ctx.lineTo(middleDividerX, lastRowEndY);
|
||||||
|
ctx.stroke();
|
||||||
|
ctx.setLineDash([]); // 重置为实线
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -220,7 +247,7 @@ class GridDraw extends BaseDrawService {
|
|||||||
} = params;
|
} = params;
|
||||||
|
|
||||||
// 绘制网格线
|
// 绘制网格线
|
||||||
ctx.strokeStyle = config.gridLineColor || '#000000';
|
ctx.strokeStyle = config.gridLineColor || '#999';
|
||||||
ctx.lineWidth = config.gridLineWidth || 1;
|
ctx.lineWidth = config.gridLineWidth || 1;
|
||||||
ctx.setLineDash([]); // 实线
|
ctx.setLineDash([]); // 实线
|
||||||
|
|
||||||
|
|||||||
@@ -3,109 +3,686 @@
|
|||||||
* 适用于入门级,低龄儿童
|
* 适用于入门级,低龄儿童
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { GridCell, ShapeTemplate } from '../types/gridTypes';
|
import { ShapeTemplate } from '../types/gridTypes';
|
||||||
|
|
||||||
// ==================== 3x3 形状模板 ====================
|
// ==================== 3x3 形状模板 ====================
|
||||||
|
|
||||||
/** 简单十字形 */
|
/** 所有 3x3 形状模板 总共39个形状模板 */
|
||||||
export const CROSS_3X3: ShapeTemplate = {
|
export const ALL_3X3_SHAPES: ShapeTemplate[] = [
|
||||||
|
/** 简单十字形 */
|
||||||
|
{
|
||||||
id: 'cross-3x3-001',
|
id: 'cross-3x3-001',
|
||||||
name: '十字形',
|
name: '十字形',
|
||||||
recommendedSize: { rows: 3, cols: 3 },
|
|
||||||
category: 'geometric',
|
category: 'geometric',
|
||||||
difficulty: 1,
|
difficulty: 1,
|
||||||
supportSymmetry: true,
|
supportSymmetry: true,
|
||||||
symmetryType: 'both',
|
symmetryType: 'both',
|
||||||
isComplete: true,
|
isComplete: true,
|
||||||
cells: [
|
cells: [
|
||||||
{ x: 1, y: 0, color: '#FFFF00' }, // 顶部
|
{ x: 1, y: 0, color: '#FFE176' }, // 顶部 - 黄色
|
||||||
{ x: 0, y: 1, color: '#FFFF00' }, // 左侧
|
{ x: 0, y: 1, color: '#F9A857' }, // 左侧 - 橙色
|
||||||
{ x: 1, y: 1, color: '#FFFF00' }, // 中心
|
{ x: 1, y: 1, color: '#ED6D50' }, // 中心 - 红色
|
||||||
{ x: 2, y: 1, color: '#FFFF00' }, // 右侧
|
{ x: 2, y: 1, color: '#F9A857' }, // 右侧 - 橙色
|
||||||
{ x: 1, y: 2, color: '#FFFF00' }, // 底部
|
{ x: 1, y: 2, color: '#FFE176' }, // 底部 - 黄色
|
||||||
],
|
],
|
||||||
};
|
},
|
||||||
|
/** L形 */
|
||||||
/** L形 */
|
{
|
||||||
export const L_SHAPE_3X3: ShapeTemplate = {
|
|
||||||
id: 'l-3x3-001',
|
id: 'l-3x3-001',
|
||||||
name: 'L形',
|
name: 'L形',
|
||||||
recommendedSize: { rows: 3, cols: 3 },
|
|
||||||
category: 'geometric',
|
category: 'geometric',
|
||||||
difficulty: 1,
|
difficulty: 1,
|
||||||
supportSymmetry: false,
|
supportSymmetry: false,
|
||||||
isComplete: true,
|
isComplete: true,
|
||||||
cells: [
|
cells: [
|
||||||
{ x: 0, y: 0, color: '#0000FF' },
|
{ x: 0, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
{ x: 0, y: 1, color: '#0000FF' },
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
{ x: 0, y: 2, color: '#0000FF' },
|
{ x: 0, y: 2, color: '#53D1B6' }, // 青色
|
||||||
{ x: 1, y: 2, color: '#0000FF' },
|
{ x: 1, y: 2, color: '#B2D94B' }, // 绿色
|
||||||
{ x: 2, y: 2, color: '#0000FF' },
|
{ x: 2, y: 2, color: '#FFE176' }, // 黄色
|
||||||
],
|
],
|
||||||
};
|
},
|
||||||
|
/** 对角线 */
|
||||||
/** 对角线 */
|
{
|
||||||
export const DIAGONAL_3X3: ShapeTemplate = {
|
|
||||||
id: 'diagonal-3x3-001',
|
id: 'diagonal-3x3-001',
|
||||||
name: '对角线',
|
name: '对角线',
|
||||||
recommendedSize: { rows: 3, cols: 3 },
|
|
||||||
category: 'geometric',
|
category: 'geometric',
|
||||||
difficulty: 1,
|
difficulty: 1,
|
||||||
supportSymmetry: true,
|
supportSymmetry: true,
|
||||||
symmetryType: 'both',
|
symmetryType: 'both',
|
||||||
isComplete: true,
|
isComplete: true,
|
||||||
cells: [
|
cells: [
|
||||||
{ x: 0, y: 0, color: '#FF0000' },
|
{ x: 0, y: 0, color: '#ED6D50' }, // 红色
|
||||||
{ x: 1, y: 1, color: '#FF0000' },
|
{ x: 1, y: 1, color: '#F9A857' }, // 橙色
|
||||||
{ x: 2, y: 2, color: '#FF0000' },
|
{ x: 2, y: 2, color: '#FFE176' }, // 黄色
|
||||||
],
|
],
|
||||||
};
|
},
|
||||||
|
|
||||||
/** 小房子 */
|
/** 反向对角线 */
|
||||||
export const HOUSE_3X3: ShapeTemplate = {
|
{
|
||||||
|
id: 'reverse-diagonal-3x3-001',
|
||||||
|
name: '反向对角线',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 2, color: '#F2A4C0' },
|
||||||
|
{ x: 1, y: 1, color: '#79A7ED' },
|
||||||
|
{ x: 2, y: 0, color: '#B2D94B' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 小房子 */
|
||||||
|
{
|
||||||
id: 'house-3x3-001',
|
id: 'house-3x3-001',
|
||||||
name: '小房子',
|
name: '小房子',
|
||||||
recommendedSize: { rows: 3, cols: 3 },
|
|
||||||
category: 'object',
|
category: 'object',
|
||||||
difficulty: 1,
|
difficulty: 1,
|
||||||
supportSymmetry: true,
|
supportSymmetry: true,
|
||||||
symmetryType: 'vertical',
|
symmetryType: 'vertical',
|
||||||
isComplete: true,
|
isComplete: true,
|
||||||
cells: [
|
cells: [
|
||||||
{ x: 1, y: 0, color: '#FF0000' }, // 屋顶
|
{ x: 1, y: 0, color: '#ED6D50' }, // 屋顶
|
||||||
{ x: 0, y: 1, color: '#FFFF00' }, // 左侧墙
|
{ x: 0, y: 1, color: '#FFE176' }, // 左侧墙
|
||||||
{ x: 1, y: 1, color: '#FFFF00' }, // 中间墙
|
{ x: 1, y: 1, color: '#FFE176' }, // 中间墙
|
||||||
{ x: 2, y: 1, color: '#FFFF00' }, // 右侧墙
|
{ x: 2, y: 1, color: '#FFE176' }, // 右侧墙
|
||||||
{ x: 1, y: 2, color: '#8B4513' }, // 门
|
{ x: 1, y: 2, color: '#BC8F71' }, // 门
|
||||||
],
|
],
|
||||||
};
|
},
|
||||||
|
|
||||||
/** 小星星 */
|
/** 小星星 */
|
||||||
export const STAR_3X3: ShapeTemplate = {
|
{
|
||||||
id: 'star-3x3-001',
|
id: 'star-3x3-001',
|
||||||
name: '小星星',
|
name: '小星星',
|
||||||
recommendedSize: { rows: 3, cols: 3 },
|
|
||||||
category: 'geometric',
|
category: 'geometric',
|
||||||
difficulty: 1,
|
difficulty: 1,
|
||||||
supportSymmetry: true,
|
supportSymmetry: true,
|
||||||
symmetryType: 'both',
|
symmetryType: 'both',
|
||||||
isComplete: true,
|
isComplete: true,
|
||||||
cells: [
|
cells: [
|
||||||
{ x: 1, y: 0, color: '#FFD700' }, // 顶部
|
{ x: 1, y: 0, color: '#FFE176' }, // 顶部 - 黄色
|
||||||
{ x: 0, y: 1, color: '#FFD700' },
|
{ x: 0, y: 1, color: '#F9A857' }, // 左侧 - 橙色
|
||||||
{ x: 1, y: 1, color: '#FFD700' }, // 中心
|
{ x: 1, y: 1, color: '#ED6D50' }, // 中心 - 红色
|
||||||
{ x: 2, y: 1, color: '#FFD700' },
|
{ x: 2, y: 1, color: '#F9A857' }, // 右侧 - 橙色
|
||||||
{ x: 1, y: 2, color: '#FFD700' }, // 底部
|
{ x: 1, y: 2, color: '#FFE176' }, // 底部 - 黄色
|
||||||
],
|
],
|
||||||
};
|
},
|
||||||
|
|
||||||
/** 所有 3x3 形状模板 */
|
/** T形 */
|
||||||
export const ALL_3X3_SHAPES: ShapeTemplate[] = [
|
{
|
||||||
CROSS_3X3,
|
id: 't-3x3-001',
|
||||||
L_SHAPE_3X3,
|
name: 'T形',
|
||||||
DIAGONAL_3X3,
|
category: 'geometric',
|
||||||
HOUSE_3X3,
|
difficulty: 1,
|
||||||
STAR_3X3,
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 1, y: 0, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 1, y: 1, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 倒T形 */
|
||||||
|
{
|
||||||
|
id: 'reverse-t-3x3-001',
|
||||||
|
name: '倒T形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 2, color: '#ED6D50' },
|
||||||
|
{ x: 1, y: 2, color: '#F9A857' },
|
||||||
|
{ x: 2, y: 2, color: '#FFE176' },
|
||||||
|
{ x: 1, y: 1, color: '#B2D94B' },
|
||||||
|
{ x: 1, y: 0, color: '#79A7ED' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 三角形 */
|
||||||
|
{
|
||||||
|
id: 'triangle-3x3-001',
|
||||||
|
name: '三角形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#FFE176' }, // 顶部 - 黄色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 左侧 - 橙色
|
||||||
|
{ x: 1, y: 1, color: '#ED6D50' }, // 中心 - 红色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 右侧 - 橙色
|
||||||
|
{ x: 0, y: 2, color: '#F2A4C0' }, // 左下 - 粉色
|
||||||
|
{ x: 1, y: 2, color: '#ED6D50' }, // 中下 - 红色
|
||||||
|
{ x: 2, y: 2, color: '#F2A4C0' }, // 右下 - 粉色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 正方形 */
|
||||||
|
{
|
||||||
|
id: 'square-3x3-001',
|
||||||
|
name: '正方形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#9C98DE' }, // 紫色
|
||||||
|
{ x: 1, y: 0, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 0, y: 1, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 1, y: 1, color: '#9C98DE' }, // 紫色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 向上箭头 */
|
||||||
|
{
|
||||||
|
id: 'arrow-up-3x3-001',
|
||||||
|
name: '向上箭头',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#6CD2EA' }, // 箭头顶部 - 浅蓝
|
||||||
|
{ x: 0, y: 1, color: '#53D1B6' }, // 左侧 - 青色
|
||||||
|
{ x: 1, y: 1, color: '#79A7ED' }, // 中心 - 蓝色
|
||||||
|
{ x: 2, y: 1, color: '#53D1B6' }, // 右侧 - 青色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 箭头杆 - 浅蓝
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字7 */
|
||||||
|
{
|
||||||
|
id: 'number-7-3x3-001',
|
||||||
|
name: '数字7',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#FC9B6C' }, // 橙色
|
||||||
|
{ x: 1, y: 0, color: '#F9A857' }, // 浅橙
|
||||||
|
{ x: 2, y: 0, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 浅橙
|
||||||
|
{ x: 1, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 2, y: 2, color: '#FC9B6C' }, // 橙色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 边框 */
|
||||||
|
{
|
||||||
|
id: 'frame-3x3-001',
|
||||||
|
name: '边框',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 1, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 0, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 0, y: 2, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 1, y: 2, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 2, color: '#B2D94B' }, // 绿色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 加号(大) */
|
||||||
|
{
|
||||||
|
id: 'plus-3x3-001',
|
||||||
|
name: '加号',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 0, y: 1, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 1, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 1, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 1, y: 2, color: '#F2A4C0' }, // 粉色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 点阵 */
|
||||||
|
{
|
||||||
|
id: 'dots-3x3-001',
|
||||||
|
name: '点阵',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 2, y: 0, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 1, y: 1, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 0, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 向下箭头 */
|
||||||
|
{
|
||||||
|
id: 'arrow-down-3x3-001',
|
||||||
|
name: '向下箭头',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#6CD2EA' }, // 箭头杆 - 浅蓝
|
||||||
|
{ x: 0, y: 1, color: '#53D1B6' }, // 左侧 - 青色
|
||||||
|
{ x: 1, y: 1, color: '#79A7ED' }, // 中心 - 蓝色
|
||||||
|
{ x: 2, y: 1, color: '#53D1B6' }, // 右侧 - 青色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 箭头底部 - 浅蓝
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 菱形 */
|
||||||
|
{
|
||||||
|
id: 'diamond-3x3-001',
|
||||||
|
name: '菱形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#FFE176' }, // 顶部 - 黄色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 左侧 - 橙色
|
||||||
|
{ x: 1, y: 1, color: '#ED6D50' }, // 中心 - 红色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 右侧 - 橙色
|
||||||
|
{ x: 1, y: 2, color: '#FFE176' }, // 底部 - 黄色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** U形 */
|
||||||
|
{
|
||||||
|
id: 'u-3x3-001',
|
||||||
|
name: 'U形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 0, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 2, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 2, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** C形 */
|
||||||
|
{
|
||||||
|
id: 'c-3x3-001',
|
||||||
|
name: 'C形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 1, y: 0, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 0, y: 1, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 0, y: 2, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 1, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 倒三角形 */
|
||||||
|
{
|
||||||
|
id: 'inverted-triangle-3x3-001',
|
||||||
|
name: '倒三角形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 1, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 0, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 1, y: 1, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 2, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 1, y: 2, color: '#53D1B6' }, // 底部 - 青色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字1 */
|
||||||
|
{
|
||||||
|
id: 'number-1-3x3-001',
|
||||||
|
name: '数字1',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#FC9B6C' }, // 橙色
|
||||||
|
{ x: 1, y: 1, color: '#F9A857' }, // 浅橙
|
||||||
|
{ x: 1, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字4 */
|
||||||
|
{
|
||||||
|
id: 'number-4-3x3-001',
|
||||||
|
name: '数字4',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 1, y: 0, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 1, y: 1, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 2, y: 1, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 2, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 圆形(3x3近似) */
|
||||||
|
{
|
||||||
|
id: 'circle-3x3-001',
|
||||||
|
name: '圆形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#9C98DE' }, // 紫色
|
||||||
|
{ x: 0, y: 1, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 2, y: 1, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 1, y: 2, color: '#9C98DE' }, // 紫色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字0 */
|
||||||
|
{
|
||||||
|
id: 'number-0-3x3-001',
|
||||||
|
name: '数字0',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 1, y: 0, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 0, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 0, y: 2, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 1, y: 2, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 2, color: '#FFE176' }, // 黄色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字8 */
|
||||||
|
{
|
||||||
|
id: 'number-8-3x3-001',
|
||||||
|
name: '数字8',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 0, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 0, y: 1, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 1, y: 1, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 2, y: 1, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 0, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 多色十字形 */
|
||||||
|
{
|
||||||
|
id: 'colorful-cross-3x3-001',
|
||||||
|
name: '多色十字形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#FFE176' }, // 顶部 - 黄色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 左侧 - 橙色
|
||||||
|
{ x: 1, y: 1, color: '#ED6D50' }, // 中心 - 红色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 右侧 - 橙色
|
||||||
|
{ x: 1, y: 2, color: '#FFE176' }, // 底部 - 黄色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 多色L形 */
|
||||||
|
{
|
||||||
|
id: 'colorful-l-3x3-001',
|
||||||
|
name: '多色L形',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 0, y: 2, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 1, y: 2, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 2, y: 2, color: '#FFE176' }, // 黄色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 多色星星 */
|
||||||
|
{
|
||||||
|
id: 'colorful-star-3x3-001',
|
||||||
|
name: '多色星星',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#FFE176' }, // 顶部 - 黄色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 左侧 - 橙色
|
||||||
|
{ x: 1, y: 1, color: '#ED6D50' }, // 中心 - 红色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 右侧 - 橙色
|
||||||
|
{ x: 1, y: 2, color: '#FFE176' }, // 底部 - 黄色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 多色小房子 */
|
||||||
|
{
|
||||||
|
id: 'colorful-house-3x3-001',
|
||||||
|
name: '多色小房子',
|
||||||
|
category: 'object',
|
||||||
|
difficulty: 1,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#ED6D50' }, // 屋顶 - 红色
|
||||||
|
{ x: 0, y: 1, color: '#FFE176' }, // 左侧墙 - 黄色
|
||||||
|
{ x: 1, y: 1, color: '#F9A857' }, // 中间墙 - 橙色
|
||||||
|
{ x: 2, y: 1, color: '#FFE176' }, // 右侧墙 - 黄色
|
||||||
|
{ x: 1, y: 2, color: '#BC8F71' }, // 门 - 棕色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字2 */
|
||||||
|
{
|
||||||
|
id: 'number-2-3x3-001',
|
||||||
|
name: '数字2',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 0, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 0, y: 2, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
/** 数字3 */
|
||||||
|
{
|
||||||
|
id: 'number-3-3x3-001',
|
||||||
|
name: '数字3',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 1, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 2, y: 1, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 0, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 2, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 2, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字5 */
|
||||||
|
{
|
||||||
|
id: 'number-5-3x3-001',
|
||||||
|
name: '数字5',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 1, y: 0, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 0, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 0, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 2, color: '#53D1B6' }, // 青色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字6 */
|
||||||
|
{
|
||||||
|
id: 'number-6-3x3-001',
|
||||||
|
name: '数字6',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#B2D94B' }, // 绿色
|
||||||
|
{ x: 1, y: 0, color: '#53D1B6' }, // 青色
|
||||||
|
{ x: 0, y: 1, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 0, y: 2, color: '#79A7ED' }, // 蓝色
|
||||||
|
{ x: 1, y: 2, color: '#6CD2EA' }, // 浅蓝
|
||||||
|
{ x: 2, y: 2, color: '#53D1B6' }, // 青色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 数字9 */
|
||||||
|
{
|
||||||
|
id: 'number-9-3x3-001',
|
||||||
|
name: '数字9',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: false,
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#F2A4C0' }, // 粉色
|
||||||
|
{ x: 1, y: 0, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 2, y: 0, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 0, y: 1, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 2, y: 1, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 1, y: 2, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
/** 字母A */
|
||||||
|
{
|
||||||
|
id: 'letter-a-3x3-001',
|
||||||
|
name: '字母A',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 1, y: 0, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 1, y: 1, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 0, y: 2, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 2, y: 2, color: '#FFE176' }, // 黄色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
/** 字母H */
|
||||||
|
{
|
||||||
|
id: 'letter-h-3x3-001',
|
||||||
|
name: '字母H',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'vertical',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 0, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 0, y: 1, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 1, y: 1, color: '#FFE176' }, // 黄色
|
||||||
|
{ x: 2, y: 1, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 0, y: 2, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 2, color: '#F9A857' }, // 橙色
|
||||||
|
],
|
||||||
|
},
|
||||||
|
/** 字母O */
|
||||||
|
{
|
||||||
|
id: 'letter-o-3x3-001',
|
||||||
|
name: '字母O',
|
||||||
|
category: 'geometric',
|
||||||
|
difficulty: 2,
|
||||||
|
supportSymmetry: true,
|
||||||
|
symmetryType: 'both',
|
||||||
|
isComplete: true,
|
||||||
|
cells: [
|
||||||
|
{ x: 0, y: 0, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 1, y: 0, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 0, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 0, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 1, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 0, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
{ x: 1, y: 2, color: '#F9A857' }, // 橙色
|
||||||
|
{ x: 2, y: 2, color: '#ED6D50' }, // 红色
|
||||||
|
],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -30,12 +30,8 @@ export interface ShapeTemplate {
|
|||||||
id: string;
|
id: string;
|
||||||
/** 形状名称 */
|
/** 形状名称 */
|
||||||
name: string;
|
name: string;
|
||||||
/** 推荐网格尺寸 */
|
|
||||||
recommendedSize: { rows: number; cols: number };
|
|
||||||
/** 形状数据(如果是对称形状,这里存储的是左半部分或上半部分) */
|
/** 形状数据(如果是对称形状,这里存储的是左半部分或上半部分) */
|
||||||
cells: GridCell[];
|
cells: GridCell[];
|
||||||
/** 颜色方案ID */
|
|
||||||
colorSchemeId?: string;
|
|
||||||
/** 分类 */
|
/** 分类 */
|
||||||
category: 'animal' | 'object' | 'geometric' | 'character' | 'nature';
|
category: 'animal' | 'object' | 'geometric' | 'character' | 'nature';
|
||||||
/** 难度等级 1-5 */
|
/** 难度等级 1-5 */
|
||||||
@@ -47,13 +43,3 @@ export interface ShapeTemplate {
|
|||||||
/** 是否已经是对称完整的图案(false表示只存储了半边) */
|
/** 是否已经是对称完整的图案(false表示只存储了半边) */
|
||||||
isComplete?: boolean;
|
isComplete?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 颜色方案 */
|
|
||||||
export const COLOR_SCHEMES: Record<string, string[]> = {
|
|
||||||
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'],
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -83,9 +83,13 @@ export function generateSymmetricalPattern(
|
|||||||
/**
|
/**
|
||||||
* 从形状模板生成完整的格子数据
|
* 从形状模板生成完整的格子数据
|
||||||
* @param template 形状模板
|
* @param template 形状模板
|
||||||
|
* @param config 网格配置(用于对称生成)
|
||||||
* @returns 完整的格子数据
|
* @returns 完整的格子数据
|
||||||
*/
|
*/
|
||||||
export function generateCompletePattern(template: ShapeTemplate): GridCell[] {
|
export function generateCompletePattern(
|
||||||
|
template: ShapeTemplate,
|
||||||
|
config: GridConfig,
|
||||||
|
): GridCell[] {
|
||||||
if (template.isComplete) {
|
if (template.isComplete) {
|
||||||
// 如果已经是完整图案,直接返回
|
// 如果已经是完整图案,直接返回
|
||||||
return [...template.cells];
|
return [...template.cells];
|
||||||
@@ -95,10 +99,7 @@ export function generateCompletePattern(template: ShapeTemplate): GridCell[] {
|
|||||||
// 使用对称生成完整图案
|
// 使用对称生成完整图案
|
||||||
return generateSymmetricalPattern(
|
return generateSymmetricalPattern(
|
||||||
template.cells,
|
template.cells,
|
||||||
{
|
config,
|
||||||
rows: template.recommendedSize.rows,
|
|
||||||
cols: template.recommendedSize.cols,
|
|
||||||
},
|
|
||||||
template.symmetryType,
|
template.symmetryType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getRandomNumberColor } from '../../constants/colors';
|
import { getRandomNumberColor } from '../../constants/mathFunctions';
|
||||||
import MissingNumberDraw from '../shared/service/missingNumberDraw';
|
import MissingNumberDraw from '../shared/service/missingNumberDraw';
|
||||||
import {
|
import {
|
||||||
createMathPage,
|
createMathPage,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getImage } from '../../../utils/index';
|
import { getImage } from '../../../utils/index';
|
||||||
import { getRandomNumberColor } from '../../../constants/colors';
|
import { getRandomNumberColor } from '../../../constants/mathFunctions';
|
||||||
|
|
||||||
interface DrawCountMatchContentParams {
|
interface DrawCountMatchContentParams {
|
||||||
canvas: WechatMiniprogram.Canvas;
|
canvas: WechatMiniprogram.Canvas;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getImage } from '../../../utils/index';
|
import { getImage } from '../../../utils/index';
|
||||||
import { getRandomNumberColor } from '../../../constants/colors';
|
import { getRandomNumberColor } from '../../../constants/mathFunctions';
|
||||||
|
|
||||||
interface DrawCountingSelectContentParams {
|
interface DrawCountingSelectContentParams {
|
||||||
canvas: WechatMiniprogram.Canvas;
|
canvas: WechatMiniprogram.Canvas;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { getNumberColors } from '../../../constants/colors';
|
import { getNumberColors } from '../../../constants/mathFunctions';
|
||||||
|
|
||||||
interface DrawNumberColorContentParams {
|
interface DrawNumberColorContentParams {
|
||||||
canvas: WechatMiniprogram.Canvas;
|
canvas: WechatMiniprogram.Canvas;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { getImage } from '../../../utils/index';
|
import { getImage } from '../../../utils/index';
|
||||||
import { getRandomNumberColor } from '../../../constants/colors';
|
import { getRandomNumberColor } from '../../../constants/mathFunctions';
|
||||||
|
|
||||||
interface DrawNumberDecomposeContentParams {
|
interface DrawNumberDecomposeContentParams {
|
||||||
canvas: WechatMiniprogram.Canvas;
|
canvas: WechatMiniprogram.Canvas;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { getImage } from '../../../utils/index';
|
import { getImage } from '../../../utils/index';
|
||||||
|
import { NUMBER_COLORS } from '../../../constants/mathFunctions';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数字到英文单词的映射
|
* 数字到英文单词的映射
|
||||||
@@ -16,19 +17,6 @@ const NUMBER_WORDS: Record<number, string> = {
|
|||||||
10: 'ten',
|
10: 'ten',
|
||||||
};
|
};
|
||||||
|
|
||||||
const NUMBER_COLORS: Record<number, string> = {
|
|
||||||
1: '#9FC558',
|
|
||||||
2: '#CDB984',
|
|
||||||
3: '#B393B8',
|
|
||||||
4: '#ED7E97',
|
|
||||||
5: '#53B5B9',
|
|
||||||
6: '#B3B3B3',
|
|
||||||
7: '#EE8B7A',
|
|
||||||
8: '#F6C644',
|
|
||||||
9: '#99C1F4',
|
|
||||||
10: '#F5D25C',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制预览区域的参数接口
|
* 绘制预览区域的参数接口
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"navigationBarTitleText": "涂鸦丫-专注力",
|
"navigationBarTitleText": "专注启蒙",
|
||||||
"navigationBarBackgroundColor": "#FFD719",
|
"navigationBarBackgroundColor": "#FFD719",
|
||||||
"homeButton": true,
|
"homeButton": true,
|
||||||
"backgroundColor": "#F6F6F6",
|
"backgroundColor": "#F6F6F6",
|
||||||
|
|||||||
@@ -24,8 +24,13 @@ Page({
|
|||||||
|
|
||||||
// 如果有page字段,跳转到对应页面
|
// 如果有page字段,跳转到对应页面
|
||||||
if (functionItem.page) {
|
if (functionItem.page) {
|
||||||
|
let url = `/focusPages/${functionItem.page}/${functionItem.page}?id=${functionId}`;
|
||||||
|
// 如果有 mode 参数,添加到 URL 中
|
||||||
|
if (functionItem.mode) {
|
||||||
|
url += `&mode=${functionItem.mode}`;
|
||||||
|
}
|
||||||
wx.navigateTo({
|
wx.navigateTo({
|
||||||
url: `/focusPages/${functionItem.page}/${functionItem.page}?id=${functionId}`,
|
url,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
wx.showToast({
|
wx.showToast({
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<view class="page-container">
|
<view class="page-container">
|
||||||
<!-- 页面标题和描述 -->
|
<!-- 页面标题和描述 -->
|
||||||
<view class="math-page-header">
|
<view class="math-page-header">
|
||||||
<view class="math-page-title">专注力训练</view>
|
<view class="math-page-title">专注启蒙</view>
|
||||||
<view class="math-page-subtitle">
|
<view class="math-page-subtitle">
|
||||||
选择功能,生成可打印的专注力训练涂鸦卡
|
选择功能,生成可打印的专注力、观察力启蒙涂鸦卡
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"navigationBarTitleText": "涂鸦丫-数学",
|
"navigationBarTitleText": "数感启蒙",
|
||||||
"navigationBarBackgroundColor": "#FFD719",
|
"navigationBarBackgroundColor": "#FFD719",
|
||||||
"homeButton": true,
|
"homeButton": true,
|
||||||
"backgroundColor": "#F6F6F6",
|
"backgroundColor": "#F6F6F6",
|
||||||
|
|||||||
@@ -86,4 +86,4 @@ this.shapeDrawService = new ShapeDrawService(canvas, ctx, options);
|
|||||||
|
|
||||||
## 示例
|
## 示例
|
||||||
|
|
||||||
参考 `miniprogram/pages/shape/index.ts` 中的实现,展示了如何在页面中使用 ShapeDrawService。
|
参考 `miniprogram/pages/shape/shape.ts` 中的实现,展示了如何在页面中使用 ShapeDrawService。
|
||||||
|
|||||||
@@ -123,8 +123,7 @@ class Tracker {
|
|||||||
try {
|
try {
|
||||||
const params = this.getCommonEventParams('share_click', pageName);
|
const params = this.getCommonEventParams('share_click', pageName);
|
||||||
|
|
||||||
this.printLog('分享事件', params);
|
this.sendEvent('share_click', params);
|
||||||
wx.reportEvent('share_click', params);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('上报分享事件失败:', error);
|
console.error('上报分享事件失败:', error);
|
||||||
}
|
}
|
||||||
@@ -141,12 +140,35 @@ class Tracker {
|
|||||||
...(mode && { mode }),
|
...(mode && { mode }),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.printLog('下载事件', params);
|
this.sendEvent('download', params);
|
||||||
wx.reportEvent('download', params);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('上报下载事件失败:', error);
|
console.error('上报下载事件失败:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送事件(仅在线上环境上报)
|
||||||
|
* @param eventName 事件名称
|
||||||
|
* @param params 事件参数
|
||||||
|
*/
|
||||||
|
sendEvent(eventName: string, params: Record<string, any>): void {
|
||||||
|
try {
|
||||||
|
// 获取当前环境,只在 release 环境下上报
|
||||||
|
const accountInfo = wx.getAccountInfoSync();
|
||||||
|
const env = accountInfo.miniProgram.envVersion || 'release';
|
||||||
|
|
||||||
|
if (env === 'release') {
|
||||||
|
this.printLog(`[${env}] 事件上报`, { eventName, params });
|
||||||
|
wx.reportEvent(eventName, params);
|
||||||
|
} else {
|
||||||
|
// 非线上环境,只打印日志,不上报
|
||||||
|
this.printLog(`[${env}] 事件上报已跳过`, { eventName, params });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取环境信息失败:', error);
|
||||||
|
// 如果获取环境信息失败,为了安全起见不上报
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出 Tracker 单例实例
|
// 导出 Tracker 单例实例
|
||||||
|
|||||||
@@ -23,6 +23,13 @@
|
|||||||
"condition": {
|
"condition": {
|
||||||
"miniprogram": {
|
"miniprogram": {
|
||||||
"list": [
|
"list": [
|
||||||
|
{
|
||||||
|
"name": "pages/focusIndex/focusIndex",
|
||||||
|
"pathName": "pages/focusIndex/focusIndex",
|
||||||
|
"query": "",
|
||||||
|
"launchMode": "default",
|
||||||
|
"scene": null
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "focusPages/gridDrawing/gridDrawing",
|
"name": "focusPages/gridDrawing/gridDrawing",
|
||||||
"pathName": "focusPages/gridDrawing/gridDrawing",
|
"pathName": "focusPages/gridDrawing/gridDrawing",
|
||||||
@@ -31,8 +38,8 @@
|
|||||||
"scene": null
|
"scene": null
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "pages/shape/index",
|
"name": "focusPages/shape/shape",
|
||||||
"pathName": "pages/shape/index",
|
"pathName": "focusPages/shape/shape",
|
||||||
"query": "",
|
"query": "",
|
||||||
"launchMode": "default",
|
"launchMode": "default",
|
||||||
"scene": null
|
"scene": null
|
||||||
@@ -113,13 +120,6 @@
|
|||||||
"query": "",
|
"query": "",
|
||||||
"launchMode": "default",
|
"launchMode": "default",
|
||||||
"scene": null
|
"scene": null
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pages/copyBook/copyBook",
|
|
||||||
"pathName": "pages/copyBook/copyBook",
|
|
||||||
"query": "",
|
|
||||||
"launchMode": "default",
|
|
||||||
"scene": null
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user