import PenControlDrawService from './draw/penControlDrawService'; import { PEN_CONTROL_PATTERNS, pickRandomPatternIds, } from './data/penControlPatterns'; import { DEFAULT_PATTERN_COUNT, generatePenControlMix, MAX_PATTERNS, } from './generators/penControlGenerator'; import { getModeInfo, getPublishMetaByMode, isValidMode, PEN_CONTROL_WORKSHEET_ID, } from './penControlSheet.config'; import { createPage, type CanvasDataState } from '../../base/pageMixin'; import { defaultShareConfig } from '../../config/config'; import type { DebugPublishMeta } from '../../utils/debugPublish'; import { addFavorite, removeFavorite, batchCheckFavorited, } from '../../utils/favorites'; const pageInfoLookup = getModeInfo; function pickRandomPatternSet(count: number, current: string[]): string[] { const next = pickRandomPatternIds(count, current); if (next.length >= count) return next.slice(0, count); return pickRandomPatternIds(count); } function buildSelectedMap(ids: string[]): Record { const map: Record = {}; for (const id of ids) map[id] = true; return map; } type PageData = CanvasDataState & { worksheetId: string; selectedPatternIds: string[]; selectedMap: Record; patternList: typeof PEN_CONTROL_PATTERNS; isPreviewFavorite: boolean; isDevEnv: boolean; debugPublishVisible: boolean; debugPublishLoading: boolean; debugPublishMeta: DebugPublishMeta | null; }; createPage( { canvas: null as Canvas | null, ctx: null as RenderingContext | null, boxHeight: 0, boxWidth: 0, drawService: null as PenControlDrawService | null, _favoritedMap: {} as Record, data: { pageTitle: '控笔组合练习', functionId: PEN_CONTROL_WORKSHEET_ID, hasContent: false, showShareDialog: false, worksheetId: PEN_CONTROL_WORKSHEET_ID, selectedPatternIds: [] as string[], selectedMap: {} as Record, patternList: PEN_CONTROL_PATTERNS, isPreviewFavorite: false, isDevEnv: false, debugPublishVisible: false, debugPublishLoading: false, debugPublishMeta: null, } as unknown as PageData, onLoad(options: { id?: string }) { this.syncDebugPublishEnv(); console.log('PEN_CONTROL_PATTERNS', PEN_CONTROL_PATTERNS); const worksheetId = options.id && isValidMode(options.id) ? options.id : PEN_CONTROL_WORKSHEET_ID; const initialPatterns = PEN_CONTROL_PATTERNS.slice( 0, DEFAULT_PATTERN_COUNT, ).map((p) => p.id); console.log('initialPatterns', initialPatterns); this.setData({ worksheetId, functionId: worksheetId, selectedPatternIds: initialPatterns, selectedMap: buildSelectedMap(initialPatterns), }); this.initPageInfo(worksheetId, '控笔练习'); this.loadFavoritedMap(); }, onCanvasReady(e: WechatMiniprogram.CustomEvent) { this.initCanvasFromComponent(e.detail, { createDrawService: ( canvas: Canvas, ctx: RenderingContext, opts?: Record, ) => new PenControlDrawService(canvas, ctx, opts), drawServiceOptions: { title: this.data.pageTitle, }, onCanvasReady: () => { this.drawCanvas(); }, }); }, async drawCanvas() { if (!this.drawService) return; try { const layout = ( this.drawService as PenControlDrawService ).buildLayoutForGenerate(); const data = generatePenControlMix({ patternIds: this.data.selectedPatternIds, patternCount: this.data.selectedPatternIds.length, layout, }); const ids = data.blocks.map((b) => b.patternId); if (ids.join(',') !== this.data.selectedPatternIds.join(',')) { this.setData({ selectedPatternIds: ids, selectedMap: buildSelectedMap(ids), }); } await (this.drawService as PenControlDrawService).draw(data); this.setData({ hasContent: true }); } catch (e) { console.error('penControlSheet draw failed', e); this.setData({ hasContent: false }); } }, onTogglePattern(e: WechatMiniprogram.TouchEvent) { const id = e.currentTarget.dataset.id as string; if (!id) return; let ids = [...this.data.selectedPatternIds]; const idx = ids.indexOf(id); if (idx >= 0) { ids.splice(idx, 1); } else { if (ids.length >= MAX_PATTERNS) { wx.showToast({ title: `最多选择 ${MAX_PATTERNS} 个`, icon: 'none', }); return; } ids.push(id); } this.setData( { selectedPatternIds: ids, selectedMap: buildSelectedMap(ids), }, () => this.drawCanvas(), ); }, onPreviewRefresh() { const count = this.data.selectedPatternIds.length || DEFAULT_PATTERN_COUNT; const next = pickRandomPatternSet( count, this.data.selectedPatternIds, ); this.setData( { selectedPatternIds: next, selectedMap: buildSelectedMap(next), }, () => this.drawCanvas(), ); }, onShufflePatterns() { this.onPreviewRefresh(); }, async onPreviewFavorite() { const next = !this.data.isPreviewFavorite; this.setData({ isPreviewFavorite: next }); const id = this.data.worksheetId; if (id) { this._favoritedMap[id] = next; if (next) { addFavorite(id); } else { removeFavorite(id); } } wx.showToast({ title: next ? '收藏成功' : '已取消收藏', icon: 'none', }); }, async loadFavoritedMap() { const ids = [PEN_CONTROL_WORKSHEET_ID]; this._favoritedMap = await batchCheckFavorited(ids); if (this._favoritedMap[this.data.worksheetId]) { this.setData({ isPreviewFavorite: true }); } }, getPublishMeta(): DebugPublishMeta { const meta = getPublishMetaByMode(this.data.worksheetId); if (!meta) { throw new Error('当前题型配置不存在'); } return meta; }, }, { shareConfig: defaultShareConfig, pageInfoLookup, }, );