feat: 添加控笔页
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
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<string, boolean> {
|
||||
const map: Record<string, boolean> = {};
|
||||
for (const id of ids) map[id] = true;
|
||||
return map;
|
||||
}
|
||||
|
||||
type PageData = CanvasDataState & {
|
||||
worksheetId: string;
|
||||
selectedPatternIds: string[];
|
||||
selectedMap: Record<string, boolean>;
|
||||
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<string, boolean>,
|
||||
|
||||
data: {
|
||||
pageTitle: '控笔组合练习',
|
||||
functionId: PEN_CONTROL_WORKSHEET_ID,
|
||||
hasContent: false,
|
||||
showShareDialog: false,
|
||||
worksheetId: PEN_CONTROL_WORKSHEET_ID,
|
||||
selectedPatternIds: [] as string[],
|
||||
selectedMap: {} as Record<string, boolean>,
|
||||
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<string, unknown>,
|
||||
) => 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,
|
||||
},
|
||||
);
|
||||
Reference in New Issue
Block a user