8.3 KiB
8.3 KiB
name, description
| name | description |
|---|---|
| create-draw-page | 基于现有 draw 页面模板创建新的绘制页(worksheet page)。 当用户说「基于现有的draw页面来开发新页面」「基于draw页面开发新页面」 「新建绘制页」「创建一个新的draw页面」「新增一个worksheet页」时触发。 |
创建新的绘制页(Draw Page)
基于 englishPages/letterTracing 模板,快速搭建一个新的 Canvas 绘制页。
模板参考
以 miniprogram/englishPages/letterTracing 为标准模板,新页面的文件结构与代码风格应与之对齐。创建前先阅读模板页的以下文件:
letterTracing.ts— 页面逻辑letterTracing.wxml— 页面模板letterTracing.less— 页面样式letterTracing.json— 组件注册letterTracing.config.ts— worksheet 元数据配置
新页面必备文件
假设新页面名为 newPage,需要创建以下文件:
newPage/
├── newPage.ts # 页面逻辑(使用 createPage)
├── newPage.wxml # 页面模板
├── newPage.less # 页面样式
├── newPage.json # 组件注册
├── newPage.config.ts # worksheet 元数据
└── draw/ # 绘制服务
└── newPageDraw.ts # 继承 BaseDrawService
必备要求
1. xxx.config.ts — worksheet 元数据配置
每个绘制页必须有对应的 xxx.config.ts 文件。参考 letterTracing.config.ts 的结构,至少包含:
worksheet 定义数组(核心):
interface XxxWorksheetDefinition {
id: string; // 唯一标识,格式:{pageName}-{variant}
icon: string; // 图标名(使用 toy-icon 支持的图标)
title: string; // 标题(简短,4-6 字)
subtitle: string; // 副标题(描述该模式的特点)
ageMin: number; // 最小适用年龄
ageMax: number; // 最大适用年龄
difficulty: 1 | 2 | 3 | 4; // 难度等级
tags: string[]; // 标签数组
sortOrder: number; // 排序权重
}
export const XXX_WORKSHEET_DEFINITIONS = [
{
id: 'xxx-default',
icon: 'icon-name',
title: '默认模式',
subtitle: '模式描述',
ageMin: 4,
ageMax: 7,
difficulty: 1,
tags: ['标签1', '标签2'],
sortOrder: 50,
},
// ... 更多模式
] as const satisfies ReadonlyArray<XxxWorksheetDefinition>;
必须导出的辅助函数(参照 letterTracing.config.ts):
getModeInfo(id)— 返回{ title, desc }用于pageInfoLookupisValidMode(id)— 校验 id 是否合法getPublishMetaByMode(id)— 生成DebugPublishMeta,使用inferGradeFromAge推断年级- 模式选项常量(如
XXX_MODE_OPTIONS)
getPublishMetaByMode 中的 category 和 subcategory 需根据页面所属学科正确设置:
category:math|puzzle|pinyin|chinese|english|craftsubcategory:页面功能简称,如letter-tracing、word-coloring
2. 必须使用的组件
每个绘制页必须在 .json 和 .wxml 中注册并使用以下组件:
{
"usingComponents": {
"nav-bar": "../../components3.0/nav-bar/nav-bar",
"preview-card": "../../components3.0/preview-card/preview-card",
"preview-footer-actions": "../../components3.0/preview-footer-actions/preview-footer-actions",
"debug-publish-tools": "../../components3.0/debug-publish-tools/debug-publish-tools",
"share-guide-popup": "../../components/share-guide-popup/share-guide-popup",
"toy-icon": "../../toy/icon/icon"
}
}
路径中的
../../需根据新页面实际所在目录调整层级。
wxml 中的基本布局结构:
<nav-bar title="页面标题" />
<view class="page-wrapper">
<view class="page-main">
<preview-card
id="previewCard"
showRefresh="{{false}}"
showFavorite="{{true}}"
favorited="{{isPreviewFavorite}}"
bind:canvas-ready="onCanvasReady"
bind:favorite="onPreviewFavorite" />
<!-- 页面特有的交互区域放这里 -->
</view>
</view>
<preview-footer-actions
disabled="{{!hasContent}}"
bind:primary="exportToPrint"
bind:secondary="onShare" />
<debug-publish-tools
wx:if="{{isDevEnv && hasContent}}"
id="debugPublishTools"
visible="{{debugPublishVisible}}"
loading="{{debugPublishLoading}}"
meta="{{debugPublishMeta}}"
bind:open="onOpenDebugPublish"
bind:close="onCloseDebugPublish"
bind:confirm="onConfirmDebugPublish" />
<share-guide-popup
show="{{showShareDialog}}"
bind:onClose="onCloseShareDialog"
bind:onShareSuccess="onShareSuccess" />
3. 图标使用
图标优先使用 toy-icon 组件(路径 ../../toy/icon/icon):
<toy-icon name="refresh" size="40rpx" color="#605b50" />
如果 toy-icon 没有所需图标,可直接引入 iconfont:
@import '../../assets/fonts/iconfont.less';
4. 使用 createPage 创建页面
页面必须使用 base/pageMixin.ts 中的 createPage 函数创建,不能直接调用 Page()。
import { createPage, type CanvasDataState } from '../../base/pageMixin';
createPage(
{
canvas: null as Canvas | null,
ctx: null as RenderingContext | null,
boxHeight: 0,
boxWidth: 0,
drawService: null as XxxDraw | null,
data: {
pageTitle: '页面标题',
functionId: '',
hasContent: false,
showShareDialog: false,
// ... 页面特有数据
isPreviewFavorite: false,
isDevEnv: false,
debugPublishVisible: false,
debugPublishLoading: false,
debugPublishMeta: null,
} as unknown as PageData,
onLoad(options: { id?: string }) {
// 1. syncDebugPublishEnv()
// 2. 解析路由参数、应用默认模式
// 3. 加载收藏状态
},
onCanvasReady(e: WechatMiniprogram.CustomEvent) {
this.initCanvasFromComponent(e.detail, {
createDrawService: (canvas, ctx, opts) =>
new XxxDraw(canvas, ctx, opts),
onCanvasReady: () => this.drawCanvas(),
});
},
async drawCanvas() {
// 生成数据 → 调用 drawService 渲染
},
getPublishMeta() {
// 调用 config 中的 getPublishMetaByMode
},
},
{
shareConfig: defaultShareConfig,
pageInfoLookup,
},
);
createPage 自动混入的公共方法包括:
initCanvas/initCanvasFromComponent— Canvas 初始化exportToPrint— 导出打印onShareAppMessage/onShareTimeline— 分享onCloseShareDialog/onShareSuccess— 分享弹窗syncDebugPublishEnv/onOpenDebugPublish/onCloseDebugPublish/onConfirmDebugPublish— 调试发布initPageInfo— 页面标题初始化getShareOptions— 分享路径
不要重复实现这些方法,直接使用即可。
5. 主题色与设计风格
保持与模板页一致的暖色调主题,除非用户另行指定 UI 稿:
@import '../../style/theme.less';
page {
background-color: @bg-page;
}
关键设计 token(来自 theme.less):
- 页面背景:
@bg-page - 卡片背景:
@bg-card - 品牌色/选中态:
@brand - 主标题色:
#6d3b00 - 正文色:
@text-secondary - 选中文字色:
@text-selected-btn - 页面左右内边距:
@page-padding-x - 底部安全区留白:
calc(200rpx + env(safe-area-inset-bottom)) - 圆角:
24rpx(卡片)/32rpx(按钮/chip)
开发检查清单
创建完成后逐项确认:
- 有
xxx.config.ts,包含 worksheet 定义数组和辅助函数 .json中注册了全部 5 个必备组件 +toy-icon.wxml中包含nav-bar、preview-card、preview-footer-actions、debug-publish-tools、share-guide-popup.ts中使用createPage()创建页面.less中引入theme.less并使用主题变量- 有
draw/目录放置绘制服务 onLoad中调用了syncDebugPublishEnv()- 实现了
getPublishMeta()方法 - 在
app.json中注册了新页面路径