feat:优化练字贴

This commit is contained in:
R524809
2026-01-21 09:07:57 +08:00
parent 9c13b44806
commit 943250b34a
6 changed files with 490 additions and 341 deletions
+1 -1
View File
@@ -14,7 +14,7 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-success:before {
.toy-icon-success:before {
content: "\e650";
}
+5 -2
View File
@@ -42,13 +42,16 @@ page {
.word-input-box {
display: flex;
flex-direction: row;
justify-content: space-between;
justify-content: flex-start;
margin-bottom: 24rpx;
}
.operation-box {
.action-buttons-box {
display: flex;
flex-direction: row;
justify-content: space-between;
gap: 20rpx;
margin-bottom: 24rpx;
}
}
+124 -34
View File
@@ -17,8 +17,14 @@ Page({
maxCol: 0 as number,
data: {
// 选中的汉字列表
// 最终的汉字列表(合并输入和选择的汉字)
words: [] as string[],
// 来自文本框输入的汉字(每次输入替换)
inputWords: [] as string[],
// 来自弹窗选择的汉字(追加)
selectedWords: [] as string[],
// 输入框的值(用于清空)
inputValue: '',
showSelectWordPopup: false,
showColorPopup: false,
currentKey: 0,
@@ -33,9 +39,12 @@ Page({
const hasShowPracticeDemo =
wx.getStorageSync('hasShowPracticeDemo') || false;
if (!hasShowPracticeDemo) {
const demoWords = ['好', '好', '学', '习', '天', '天', '向', '上'];
this.setData(
{
words: ['好', '好', '学', '习', '天', '天', '向', '上'],
words: demoWords,
inputWords: demoWords,
selectedWords: [],
},
() => {
wx.setStorageSync('hasShowPracticeDemo', true);
@@ -86,47 +95,68 @@ Page({
}
},
// 输入组件回调
// 输入组件回调(所见即所得:替换文本框输入的汉字)
onConfirmInput(e: any) {
const value: string = (e && e.detail && e.detail.value) || '';
const text = (value || '').trim();
if (!text) return;
// 如果文本框为空,清空输入汉字
if (!text) {
const { selectedWords } = this.data as any;
const updatedWords = [...selectedWords];
this.setData(
{
inputWords: [],
words: updatedWords,
},
() => {
this.renderPracticeContent().catch(console.error);
},
);
return;
}
if (!this.isChineseText(text)) {
wx.showToast({ title: '请输入汉字', icon: 'none' });
return;
}
const { words } = this.data as any;
// 1. 解析新输入的汉字
const newChars = this.splitToSingleChars(text);
if (newChars.length === 0) {
// 1. 解析输入的汉字
const newInputChars = this.splitToSingleChars(text);
if (newInputChars.length === 0) {
wx.showToast({ title: '请输入有效汉字', icon: 'none' });
return;
}
// 2. 检查是否超过限制
if (words.length + newChars.length > 11) {
const { selectedWords } = this.data as any;
// 2. 检查是否超过限制(输入汉字 + 已选择的汉字)
if (newInputChars.length + selectedWords.length > 11) {
wx.showToast({
title: `最多只能添加 11 个字,当前已 ${words.length} 个,输入了 ${newChars.length}`,
title: `最多只能添加 11 个字,当前已选择 ${selectedWords.length} 个,输入了 ${newInputChars.length}`,
icon: 'none',
duration: 3000,
});
return;
}
// 3. 直接追加新汉字
const updatedWords = [...words, ...newChars];
// 3. 替换输入汉字(不是追加),合并已选择的汉字
const updatedWords = [...newInputChars, ...selectedWords];
// 4. 更新数据并提示
this.setData({ words: updatedWords }, () => {
this.renderPracticeContent().catch(console.error);
});
this.setData(
{
inputWords: newInputChars,
words: updatedWords,
},
() => {
this.renderPracticeContent().catch(console.error);
},
);
// 5. 显示添加结果提示
wx.showToast({
title: `成功添加 ${newChars.length}汉字`,
title: `已更新输入汉字(${newInputChars.length}`,
icon: 'none',
duration: 2000,
});
@@ -140,30 +170,90 @@ Page({
this.setData({ showSelectWordPopup: false });
},
onChangeWord(e: any) {
const selectedWords = e.detail.selectedWords as string[];
const newWords = [...this.data.words, ...selectedWords];
this.setData({ words: newWords, showSelectWordPopup: false }, () => {
if (newWords && newWords.length > 0) {
this.renderPracticeContent().catch(console.error);
}
});
const newSelectedWords = e.detail.selectedWords as string[];
const { inputWords } = this.data as any;
// 检查是否超过限制
if (inputWords.length + newSelectedWords.length > 11) {
wx.showToast({
title: `最多只能添加 11 个字,当前输入 ${inputWords.length} 个,选择了 ${newSelectedWords.length}`,
icon: 'none',
duration: 3000,
});
return;
}
// 合并输入汉字和选择的汉字(求并集)
const updatedWords = [...inputWords, ...newSelectedWords];
this.setData(
{
selectedWords: newSelectedWords,
words: updatedWords,
showSelectWordPopup: false,
},
() => {
if (updatedWords && updatedWords.length > 0) {
this.renderPracticeContent().catch(console.error);
}
},
);
},
// 删除
// 删除(需要判断删除的是输入汉字还是选择的汉字)
deleteWordCard(e: any) {
const { key } = e.detail;
const { words } = this.data as any;
const next = words.filter((_: string, index: number) => index !== key);
this.setData({ words: next }, () =>
this.renderPracticeContent().catch(console.error),
);
const { inputWords, selectedWords } = this.data as any;
// 判断删除的是输入汉字还是选择的汉字
if (key < inputWords.length) {
// 删除的是输入汉字
const nextInputWords = inputWords.filter(
(_: string, index: number) => index !== key,
);
const nextWords = [...nextInputWords, ...selectedWords];
this.setData(
{
inputWords: nextInputWords,
words: nextWords,
},
() => this.renderPracticeContent().catch(console.error),
);
} else {
// 删除的是选择的汉字
const selectedIndex = key - inputWords.length;
const nextSelectedWords = selectedWords.filter(
(_: string, index: number) => index !== selectedIndex,
);
const nextWords = [...inputWords, ...nextSelectedWords];
this.setData(
{
selectedWords: nextSelectedWords,
words: nextWords,
},
() => this.renderPracticeContent().catch(console.error),
);
}
},
// 清空
// 清空(清空所有来源的汉字:文本框、预览、弹窗选择)
clearWords() {
this.setData({ words: [] }, () =>
this.renderPracticeContent().catch(console.error),
// 清空所有汉字数据
this.setData(
{
words: [],
inputWords: [],
selectedWords: [],
inputValue: '', // 清空输入框
},
() => {
this.renderPracticeContent().catch(console.error);
},
);
// 关闭弹窗(如果打开)
if (this.data.showSelectWordPopup) {
this.setData({ showSelectWordPopup: false });
}
},
// 随机生成(取基础分类,过滤为可用SVG字,最多11个)
+20 -23
View File
@@ -2,13 +2,29 @@
<view class="wrapper">
<text class="wrapper-title">自定义练字贴</text>
<view class="word-input-box">
<word-input bind:onConfirm="onConfirmInput" width="410rpx" />
<word-input bind:onConfirm="onConfirmInput" style="width: 100%;"/>
</view>
<view class="action-buttons-box">
<toy-button
type="green"
bind:click="openSelectWordPopup"
width="200rpx">
height="80rpx"
width="410rpx"
icon="success"
icon-class-prefix="van-icon">
选择文字
</toy-button>
<toy-button
disabled="{{words.length <= 0}}"
type="white"
bind:click="clearWords"
width="220rpx"
height="80rpx"
icon="clear"
icon-class-prefix="toy-icon">
清空
</toy-button>
</view>
<view class="word-card-box">
@@ -27,28 +43,9 @@
<empty-state
wx:if="{{!words.length}}"
title="还没有添加文字"
desc="请在上方输入文字或点击选择文字按钮,开始创建你的练字田字格吧!"
desc='请在上方输入文字或点击"选择文字"按钮,开始创建你的练字田字格吧!'
hint="提示:最多可以同时添加 11 个文字" />
</view>
<view class="operation-box">
<toy-button
type="primary"
bind:click="refreshWords"
width="410rpx"
icon="refresh"
icon-class-prefix="toy-icon">
随机生成
</toy-button>
<toy-button
disabled="{{words.length <= 0}}"
type="white"
bind:click="clearWords"
width="200rpx"
icon="clear"
icon-class-prefix="toy-icon">
清空
</toy-button>
</view>
</view>
<view id="previewWrapper" class="wrapper">
@@ -88,7 +85,7 @@
</view>
<word-picker
show="{{showSelectWordPopup}}"
selectedWords="{{words}}"
selectedWords="{{selectedWords}}"
max="11"
bind:onClose="closeSelectWordPopup"
bind:onChange="onChangeWord" />
+84 -32
View File
@@ -21,13 +21,21 @@ function drawSvgPathCommands({
}: DrawSvgPathCommandsParams) {
// console.log('drawSvgPathCommands 参数:', { pathD, offsetX, offsetY, scale });
// 精度处理函数:避免浮点数精度问题
const roundToPrecision = (num: number, precision: number = 2): number => {
// 精度处理函数:避免浮点数精度问题(提高到6位小数精度,确保高精度)
const roundToPrecision = (num: number, precision: number = 6): number => {
return (
Math.round(num * Math.pow(10, precision)) / Math.pow(10, precision)
);
};
// 像素对齐函数:优化对齐策略,提升平滑度
// 对于Fill+Stroke模式,使用更精细的对齐策略,避免过度对齐导致的锯齿
// 对齐到0.5像素可以获得更好的平滑效果
const alignToPixel = (num: number): number => {
// 对齐到0.5像素,而不是整数像素,可以获得更平滑的线条
return Math.round(num * 2) / 2;
};
// 新的解析方法:按命令片段解析
// 使用正则表达式匹配从字母开头到下一个字母(或结尾)的片段
const commandRegex = /([MLZ])([^MLZ]*?)(?=[MLZ]|$)/g;
@@ -60,9 +68,14 @@ function drawSvgPathCommands({
const y = parseFloat(coordParts[1]);
if (!isNaN(x) && !isNaN(y) && isFinite(x) && isFinite(y)) {
// 计算最终坐标并处理精度
const finalX = roundToPrecision(offsetX + x * scale);
const finalY = roundToPrecision(offsetY + y * scale);
// 计算最终坐标:先进行高精度计算,再对齐到整数像素
// 使用高精度计算确保路径的准确性,然后对齐到像素避免亚像素渲染
const calculatedX = offsetX + x * scale;
const calculatedY = offsetY + y * scale;
const preciseX = roundToPrecision(calculatedX);
const preciseY = roundToPrecision(calculatedY);
const finalX = alignToPixel(preciseX);
const finalY = alignToPixel(preciseY);
// console.log(`${cmd}: 绘制到 (${finalX}, ${finalY}) [原始: (${x}, ${y})]`);
drawFunction(finalX, finalY);
@@ -85,8 +98,8 @@ function drawSvgPathCommands({
L: (coords) =>
parseAndDrawCoords(coords, 'L', (x, y) => ctx.lineTo(x, y)),
Z: () => {
// console.log('Z: 闭合路径');
// 注意:不要在这里调用 closePath(),因为 drawStrokes 中会统一处理
// 关键修复:处理Z命令,闭合路径
ctx.closePath();
},
};
@@ -124,21 +137,40 @@ function drawStrokes({
offsetY,
size,
uptoInclusive,
fillStyle,
strokeStyle,
lineWidth,
fillStyle, // 填充颜色,用于 Fill + Stroke 模式
strokeStyle, // 描边颜色,用于绘制笔画
lineWidth, // 线条宽度,控制笔画粗细
}: DrawStrokesParams) {
// 设置 Canvas 绘制质量(关键优化:提升线条流畅度)
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high'; // 高质量平滑
// 设置路径绘制属性(关键:这些设置直接影响笔画粗细和流畅度)
// 注意:不使用 save/restore,与测试页面保持一致,避免状态管理问题
ctx.lineCap = 'round'; // 圆角端点,使笔画末端更自然
ctx.lineJoin = 'round'; // 圆角连接,使转折处更平滑
ctx.miterLimit = 10; // 斜接限制
// 优化渲染策略:使用 Fill + Stroke 模式
// 先 fill 填充内部,再 stroke 描边,stroke 宽度略小,避免双重渲染导致的毛糙
// 这样可以获得自然的笔画粗细,同时保持流畅度
// 模板中使用 54x54 的视窗尺寸
const viewBoxSize = 54;
// 添加内边距:在田字格四周预留空间,避免笔画贴边
const padding = size * 0.1; // 内边距为田字格大小的10%
const contentSize = size - padding * 2; // 实际绘制区域大小
const contentScale = contentSize / viewBoxSize; // 调整后的缩放比例
// 优化缩放比例:使用更精确的缩放,不进行四舍五入,保持原始精度
const contentScale = contentSize / viewBoxSize;
// 计算内容区域的起始位置(居中)
const contentOffsetX = offsetX + padding;
const contentOffsetY = offsetY + padding;
// 计算内容区域的起始位置(居中),优化对齐策略提升平滑度
const rawOffsetX = offsetX + padding;
const rawOffsetY = offsetY + padding;
// 对齐到0.5像素,而不是整数像素,可以获得更平滑的渲染效果
const contentOffsetX = Math.round(rawOffsetX * 2) / 2;
const contentOffsetY = Math.round(rawOffsetY * 2) / 2;
// console.log('drawStrokes 参数:', {
// strokesCount: strokes.length,
@@ -160,6 +192,10 @@ function drawStrokes({
for (let s = 0; s <= uptoInclusive && s < strokes.length; s++) {
// console.log(`绘制第 ${s} 个笔画:`, strokes[s]);
ctx.beginPath();
// 记录路径是否包含Z命令(已闭合)
const hasClosePath = strokes[s].includes('Z');
drawSvgPathCommands({
ctx,
pathD: strokes[s],
@@ -167,13 +203,27 @@ function drawStrokes({
offsetY: contentOffsetY,
scale: contentScale,
});
// 优化渲染策略:使用 Fill + Stroke 模式
// 先 fill 填充内部,再 stroke 描边,stroke 宽度略小,避免双重渲染导致的毛糙
// 如果路径没有Z命令,手动闭合(fill需要闭合路径)
if (!hasClosePath) {
ctx.closePath();
}
// 1. 先填充内部
ctx.fillStyle = fillStyle;
ctx.strokeStyle = strokeStyle;
ctx.lineWidth = lineWidth;
ctx.fill();
// 2. 再描边(stroke宽度设为fill视觉宽度的70%,避免明显的双重渲染)
// 与测试页面保持一致:使用相同的stroke宽度计算方式
ctx.strokeStyle = strokeStyle;
const strokeWidth = Math.max(1.5, lineWidth * 0.7);
ctx.lineWidth = strokeWidth;
ctx.stroke();
ctx.closePath();
}
// 注意:不使用 restore,与测试页面保持一致
}
interface DrawTianZiGridParams {
@@ -190,15 +240,15 @@ function drawTianZiGrid({
x,
y,
size,
lineColor = '#e0e0e0',
boldColor = '#cccccc',
lineColor = '#a8d5a8', // 浅绿色(中线)
boldColor = '#7fb069', // 中等绿色(外框)
}: DrawTianZiGridParams) {
// 外框(逻辑像素)
// 外框(逻辑像素)- 使用中等绿色,清晰可见
ctx.strokeStyle = boldColor;
ctx.lineWidth = 1; // 2/3≈1,逻辑像素
ctx.strokeRect(x - size / 2, y - size / 2, size, size);
// 中线(逻辑像素)
// 中线(逻辑像素)- 使用浅绿色,柔和护眼
ctx.strokeStyle = lineColor;
ctx.lineWidth = 1; // 逻辑像素
ctx.beginPath();
@@ -211,8 +261,8 @@ function drawTianZiGrid({
ctx.stroke();
ctx.closePath();
// 对角线(淡,逻辑像素)
ctx.strokeStyle = '#eeeeee';
// 对角线(淡绿色,逻辑像素)- 使用很淡的绿色,提供辅助参考线
ctx.strokeStyle = '#d4f0d4'; // 很淡的绿色
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(x - size / 2, y - size / 2);
@@ -519,7 +569,8 @@ class WordDrawService extends BaseDrawService {
// console.log(`预览格 [${rowIndex}, ${columnIndex}] 坐标: (${x}, ${y}), 笔画数: ${strokes.length}`);
// 绘制完整汉字(黑色,较粗
// 绘制完整汉字(深灰色,Fill + Stroke模式
// 参考一般练字贴:预览字使用深灰色,不是纯黑色,更柔和护眼
drawStrokes({
ctx,
strokes,
@@ -527,9 +578,9 @@ class WordDrawService extends BaseDrawService {
offsetY: y,
size: cellSize,
uptoInclusive: strokes.length - 1,
fillStyle: 'rgb(0,0,0)', // 色填充
strokeStyle: 'rgb(0,0,0)', // 色描边
lineWidth: 1, // 较粗的线条(4/3≈1逻辑像素)
fillStyle: 'rgb(85,85,85)', // 深灰色填充#555555),比#666666更深一点
strokeStyle: 'rgb(85,85,85)', // 深灰色描边
lineWidth: 0.6, // Fill + Stroke 模式,线条宽度调小一点(逻辑像素)
});
}
@@ -564,7 +615,8 @@ class WordDrawService extends BaseDrawService {
// console.log(`练习格 [${rowIndex}, ${columnIndex}] 坐标: (${x}, ${y}), 笔画: ${strokeIndex + 1}/${strokes.length}`);
// 绘制到指定笔画的汉字(灰色,中等粗细
// 绘制到指定笔画的汉字(灰色,Fill + Stroke模式
// 参考一般练字贴:练习字使用浅灰色,便于临摹
drawStrokes({
ctx,
strokes,
@@ -572,14 +624,14 @@ class WordDrawService extends BaseDrawService {
offsetY: y,
size: cellSize,
uptoInclusive: strokeIndex,
fillStyle: '#ccc',
strokeStyle: '#ccc',
lineWidth: 1, // 中等粗细(3/3=1逻辑像素)
fillStyle: 'rgb(170,170,170)', // 浅灰色填充(#aaaaaa),参考练字贴颜色
strokeStyle: 'rgb(170,170,170)', // 浅灰色描边
lineWidth: 0.6, // Fill + Stroke 模式,线条宽度调小一点(逻辑像素)
});
}
// drawDivider 已在基类中实现,此方法保留以保持兼容
drawDivider(linY?: number) {
drawDivider() {
super.drawDivider();
}
}
+256 -249
View File
@@ -1,253 +1,260 @@
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "doodle-mini",
"setting": {
"compileHotReLoad": false,
"urlCheck": true,
"coverView": false,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": true,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": true,
"useApiHostProcess": true,
"showShadowRootInWxmlPanel": false,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true,
"bigPackageSizeSupport": false
},
"libVersion": "3.7.12",
"condition": {
"miniprogram": {
"list": [
{
"name": "mathPages/multiplicationTable/multiplicationTable",
"pathName": "mathPages/multiplicationTable/multiplicationTable",
"query": "id=multiplication-table",
"scene": null,
"launchMode": "default"
},
{
"name": "mathPages/calculationPractice/calculationPractice",
"pathName": "mathPages/calculationPractice/calculationPractice",
"query": "id=practice-addition",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/oneDigitAddition/oneDigitAddition",
"pathName": "mathPages/oneDigitAddition/oneDigitAddition",
"query": "id=one-digit-addition",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/borrowTen/borrowTen",
"pathName": "mathPages/borrowTen/borrowTen",
"query": "id=borrow-ten",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/flatTen/flatTen",
"pathName": "mathPages/flatTen/flatTen",
"query": "id=flat-ten",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/breakTen/breakTen",
"pathName": "mathPages/breakTen/breakTen",
"query": "id=break-ten",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/makeTen/makeTen",
"pathName": "mathPages/makeTen/makeTen",
"query": "id=make-ten",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/dotConnect/dotConnect",
"pathName": "focusPages/dotConnect/dotConnect",
"query": "id=dot-connect",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberObjectMatch/numberObjectMatch",
"pathName": "mathPages/numberObjectMatch/numberObjectMatch",
"query": "id=number-object-match",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/colorShapeMatch/colorShapeMatch",
"pathName": "focusPages/colorShapeMatch/colorShapeMatch",
"query": "id=color-shape-match",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberSort/numberSort",
"pathName": "mathPages/numberSort/numberSort",
"query": "id=number-sort",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/codeConnect/codeConnect",
"pathName": "focusPages/codeConnect/codeConnect",
"query": "id=code-connect",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/gridReasoning/gridReasoning",
"pathName": "focusPages/gridReasoning/gridReasoning",
"query": "id=grid-reasoning",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/lineRecognition/lineRecognition",
"pathName": "focusPages/lineRecognition/lineRecognition",
"query": "id=line-recognition",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/matchConnect/matchConnect",
"pathName": "focusPages/matchConnect/matchConnect",
"query": "id=match-connect",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/colorPattern/colorPattern",
"pathName": "focusPages/colorPattern/colorPattern",
"query": "id=color-pattern",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/shapeSymbol/shapeSymbol",
"pathName": "focusPages/shapeSymbol/shapeSymbol",
"query": "id=shape-symbol",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/positionColoring/positionColoring",
"pathName": "focusPages/positionColoring/positionColoring",
"query": "id=position-coloring",
"launchMode": "default",
"scene": null
},
{
"name": "pages/focusIndex/focusIndex",
"pathName": "pages/focusIndex/focusIndex",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/gridDrawing/gridDrawing",
"pathName": "focusPages/gridDrawing/gridDrawing",
"query": "id=grid-drawing",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/shape/shape",
"pathName": "focusPages/shape/shape",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "pages/index/index",
"pathName": "pages/index/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberDecompose/numberDecompose",
"pathName": "mathPages/numberDecompose/numberDecompose",
"query": "id=number-decompose&mode=with-image",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/countingSelect/countingSelect",
"pathName": "mathPages/countingSelect/countingSelect",
"query": "id=counting-fill",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/compare/compare",
"pathName": "mathPages/compare/compare",
"query": "id=compare",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/missingNumber/missingNumber",
"pathName": "mathPages/missingNumber/missingNumber",
"query": "id=missing-number",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/addition/addition",
"pathName": "mathPages/addition/addition",
"query": "id=addition-5",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/countMatch/countMatch",
"pathName": "mathPages/countMatch/countMatch",
"query": "id=number-coloring",
"launchMode": "default",
"scene": null
},
{
"name": "pages/mathIndex/mathIndex",
"pathName": "pages/mathIndex/mathIndex",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/countMatch/countMatch",
"pathName": "mathPages/countMatch/countMatch",
"query": "id=counting-matching",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberFind/numberFind",
"pathName": "mathPages/numberFind/numberFind",
"query": "id=number-write",
"launchMode": "default",
"scene": null
},
{
"name": "pages/mathIndex/mathIndex",
"pathName": "pages/mathIndex/mathIndex",
"query": "",
"launchMode": "default",
"scene": null
}
]
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "doodle-mini",
"setting": {
"compileHotReLoad": false,
"urlCheck": true,
"coverView": false,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": true,
"preloadBackgroundData": false,
"autoAudits": false,
"useApiHook": true,
"useApiHostProcess": true,
"showShadowRootInWxmlPanel": false,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true,
"bigPackageSizeSupport": false
},
"libVersion": "3.7.12",
"condition": {
"miniprogram": {
"list": [
{
"name": "pages/copyBook/copyBook",
"pathName": "pages/copyBook/copyBook",
"query": "",
"scene": null,
"launchMode": "default"
},
{
"name": "mathPages/multiplicationTable/multiplicationTable",
"pathName": "mathPages/multiplicationTable/multiplicationTable",
"query": "id=multiplication-table",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/calculationPractice/calculationPractice",
"pathName": "mathPages/calculationPractice/calculationPractice",
"query": "id=practice-addition",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/oneDigitAddition/oneDigitAddition",
"pathName": "mathPages/oneDigitAddition/oneDigitAddition",
"query": "id=one-digit-addition",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/borrowTen/borrowTen",
"pathName": "mathPages/borrowTen/borrowTen",
"query": "id=borrow-ten",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/flatTen/flatTen",
"pathName": "mathPages/flatTen/flatTen",
"query": "id=flat-ten",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/breakTen/breakTen",
"pathName": "mathPages/breakTen/breakTen",
"query": "id=break-ten",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/makeTen/makeTen",
"pathName": "mathPages/makeTen/makeTen",
"query": "id=make-ten",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/dotConnect/dotConnect",
"pathName": "focusPages/dotConnect/dotConnect",
"query": "id=dot-connect",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberObjectMatch/numberObjectMatch",
"pathName": "mathPages/numberObjectMatch/numberObjectMatch",
"query": "id=number-object-match",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/colorShapeMatch/colorShapeMatch",
"pathName": "focusPages/colorShapeMatch/colorShapeMatch",
"query": "id=color-shape-match",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberSort/numberSort",
"pathName": "mathPages/numberSort/numberSort",
"query": "id=number-sort",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/codeConnect/codeConnect",
"pathName": "focusPages/codeConnect/codeConnect",
"query": "id=code-connect",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/gridReasoning/gridReasoning",
"pathName": "focusPages/gridReasoning/gridReasoning",
"query": "id=grid-reasoning",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/lineRecognition/lineRecognition",
"pathName": "focusPages/lineRecognition/lineRecognition",
"query": "id=line-recognition",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/matchConnect/matchConnect",
"pathName": "focusPages/matchConnect/matchConnect",
"query": "id=match-connect",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/colorPattern/colorPattern",
"pathName": "focusPages/colorPattern/colorPattern",
"query": "id=color-pattern",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/shapeSymbol/shapeSymbol",
"pathName": "focusPages/shapeSymbol/shapeSymbol",
"query": "id=shape-symbol",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/positionColoring/positionColoring",
"pathName": "focusPages/positionColoring/positionColoring",
"query": "id=position-coloring",
"launchMode": "default",
"scene": null
},
{
"name": "pages/focusIndex/focusIndex",
"pathName": "pages/focusIndex/focusIndex",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/gridDrawing/gridDrawing",
"pathName": "focusPages/gridDrawing/gridDrawing",
"query": "id=grid-drawing",
"launchMode": "default",
"scene": null
},
{
"name": "focusPages/shape/shape",
"pathName": "focusPages/shape/shape",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "pages/index/index",
"pathName": "pages/index/index",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberDecompose/numberDecompose",
"pathName": "mathPages/numberDecompose/numberDecompose",
"query": "id=number-decompose&mode=with-image",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/countingSelect/countingSelect",
"pathName": "mathPages/countingSelect/countingSelect",
"query": "id=counting-fill",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/compare/compare",
"pathName": "mathPages/compare/compare",
"query": "id=compare",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/missingNumber/missingNumber",
"pathName": "mathPages/missingNumber/missingNumber",
"query": "id=missing-number",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/addition/addition",
"pathName": "mathPages/addition/addition",
"query": "id=addition-5",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/countMatch/countMatch",
"pathName": "mathPages/countMatch/countMatch",
"query": "id=number-coloring",
"launchMode": "default",
"scene": null
},
{
"name": "pages/mathIndex/mathIndex",
"pathName": "pages/mathIndex/mathIndex",
"query": "",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/countMatch/countMatch",
"pathName": "mathPages/countMatch/countMatch",
"query": "id=counting-matching",
"launchMode": "default",
"scene": null
},
{
"name": "mathPages/numberFind/numberFind",
"pathName": "mathPages/numberFind/numberFind",
"query": "id=number-write",
"launchMode": "default",
"scene": null
},
{
"name": "pages/mathIndex/mathIndex",
"pathName": "pages/mathIndex/mathIndex",
"query": "",
"launchMode": "default",
"scene": null
}
]
}
}
}