import WordDrawService from '../../service/wordDrawService'; import { checkAndSaveImage } from '../../utils/saveImage'; import { PAPER_SIZE } from '../../constants/colors'; Page({ canvas: null as Canvas | null, ctx: null as RenderingContext | null, wordDrawService: null as WordDrawService | null, svgWords: {} as Record, data: { // 选中的汉字列表 words: ['赢', '张', '政'] as string[], showSelectWordPopup: false, showColorPopup: false, currentKey: 0, currentColor: '', // 田字格配置 // rows: 10, // cols: 12, // rowsArray: [] as number[], // colsArray: [] as number[], boxWidth: 0, boxHeight: 0, }, onLoad() { // this.initGrid(); this.loadSvgWords(); }, onReady() { this.setCanvasBoxSize(); }, loadSvgWords() { const fs = wx.getFileSystemManager(); fs.readFile({ filePath: 'constants/svgWords.json', // JSON文件路径,相对于项目根目录 encoding: 'utf8', // 重要:指定编码为utf8以读取文本内容 success: (res) => { try { wx.showToast({ title: '加载中...', icon: 'loading' }); const parsedData = JSON.parse(res.data as string); this.svgWords = parsedData; console.log('this.svgWords.length----:', Object.keys(this.svgWords).length) wx.hideToast(); console.log('SVG words loaded successfully'); const { words } = this.data as any; if (words && words.length > 0) { this.drawPracticeSheet().catch(console.error); } } catch (e) { console.error('解析JSON失败', e); } }, fail: (err) => { console.error('读取文件失败', err); wx.hideToast(); } }); }, // 输入组件回调 onConfirmInput(e: any) { const value: string = (e && e.detail && e.detail.value) || ''; const text = (value || '').trim(); if (!text) return; if (!this.isChineseText(text)) { wx.showToast({ title: '请输入汉字', icon: 'none' }); return; } const chars = this.splitToSingleChars(text); const { words } = this.data as any; const exists = new Set(words); const newWords = [...words]; chars.forEach((ch) => { if (!exists.has(ch)) { newWords.push(ch); } }); this.setData({ words: newWords }, () => this.drawPracticeSheet().catch(console.error)); }, // 选择面板 openSelectWordPopup() { this.setData({ showSelectWordPopup: true }); }, closeSelectWordPopup() { 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 }, () => this.drawPracticeSheet().catch(console.error)); }, // 删除与颜色 deleteWordCard(e: any) { const { word } = e.detail; const { words } = this.data as any; const next = words.filter((w: string) => w !== word); this.setData({ words: next }, () => this.drawPracticeSheet().catch(console.error)); }, // 校验 & 分割 isChineseText(text: string): boolean { const chineseRegex = /^[\u4e00-\u9fff]+$/; return chineseRegex.test(text); }, splitToSingleChars(text: string): string[] { const chineseRegex = /[\u4e00-\u9fff]/g; const matches = text.match(chineseRegex); return matches || []; }, // 田字格 /* initGrid() { const { rows, cols } = this.data as any; const rowsArray = Array.from({ length: rows }, (_, i) => i); const colsArray = Array.from({ length: cols }, (_, i) => i); console.log('rowsArray----:', rowsArray) console.log('colsArray----:', colsArray) this.setData({ rowsArray, colsArray }); }, */ setCanvasBoxSize() { const query = wx.createSelectorQuery(); query .select('#canvasWrapper') .boundingClientRect((rect) => { if (rect) { const { width, height } = PAPER_SIZE['A4']; const boxWidth = rect.width; const boxHeight = boxWidth / (width / height); this.setData({ boxWidth, boxHeight }); } }) .exec(); }, initCanvas() { // 然后初始化canvas wx.createSelectorQuery() .select('#canvasContent') .fields({ node: true, size: true, }) .exec((res) => { if (res[0] && res[0].node) { const canvas = res[0].node; const ctx = canvas.getContext('2d'); if (ctx) { this.canvas = canvas; this.ctx = ctx; this.wordDrawService = new WordDrawService(canvas, ctx, { appName: '涂鸦丫小程序', appHint: '练字|识字|打印', title: '田字格 练 字 贴', subTitle: '按笔画临摹练习' }); this.drawPracticeSheet().catch(console.error); } } }); }, // 绘制练字贴 async drawPracticeSheet() { if (!this.canvas || !this.wordDrawService) { this.initCanvas(); } const { words } = this.data as any; if (!words || words.length === 0) { return; } // 构建汉字笔画数据 const wordsMap: Record = {}; console.log('this.svgWords----:', this.svgWords) words.forEach((word: string) => { if (this.svgWords[word]) { wordsMap[word] = this.svgWords[word]; } }); if (Object.keys(wordsMap).length === 0) { wx.showToast({ title: '暂不支持这些汉字', icon: 'none' }); return; } await this.wordDrawService?.draw(wordsMap); }, // 下载打印练字贴 exportToPrint() { const { words } = this.data as any; if (!this.canvas || words.length <= 0) { wx.showToast({ title: '请先生成练字贴', icon: 'none' }); return; } checkAndSaveImage(this.canvas); }, // 分享功能 onShareAppMessage() { return { title: '涂鸦丫-练字|识字|打印', path: '/pages/copyBook/index', }; }, onShareTimeline() { return { title: '涂鸦丫-练字|识字|打印', query: '/pages/copyBook/index', }; }, });