refactor: 使用flutter对原先的web项目重构,正在进行中

This commit is contained in:
cancerai committed 2026-10-25 00:06:51 +08:00
1 parent 273224f5cf
commit 18017f819a
205 files changed
+13563

No files matched your search

+97
View File
@@ -0,0 +1,97 @@
// 编辑器所见即所得测试:刺以三角形绘制 + 每种方块都能正常渲染
const noop = () => { };
const els = new Map();
// 记录关键绘制调用的计数器(证明刺用三角形图元、方块用真实纹理)
const C = { lineTo: 0, fillRect: 0, beginPath: 0, moveTo: 0, arc: 0 };
const ctx2d = new Proxy({
canvas: { width: 800, height: 608 },
measureText: () => ({ width: 12 }),
createLinearGradient: () => ({ addColorStop: noop }),
createRadialGradient: () => ({ addColorStop: noop }),
getImageData: () => ({ data: [] }),
}, {
get(t, k) { return k in t ? t[k] : noop; },
set(t, k, v) { t[k] = v; return true; },
});
// 装上计数器
ctx2d.lineTo = () => C.lineTo++;
ctx2d.fillRect = () => C.fillRect++;
ctx2d.beginPath = () => C.beginPath++;
ctx2d.moveTo = () => C.moveTo++;
ctx2d.arc = () => C.arc++;
function mkEl(id = '') {
return {
id, tagName: 'DIV', value: '', textContent: '', innerHTML: '',
style: {}, dataset: {}, children: [], width: 800, height: 608,
classList: { add: noop, remove: noop, toggle: noop, contains: () => false },
addEventListener: noop, removeEventListener: noop, appendChild: noop,
querySelector: () => mkEl(), querySelectorAll: () => [],
getBoundingClientRect: () => ({ left: 0, top: 0, width: 800, height: 608 }),
getContext: () => ctx2d, focus: noop, click: noop,
};
}
const handlers = {};
const addL = (t, fn) => { (handlers[t] = handlers[t] || []).push(fn); };
globalThis.location = { search: '', href: 'http://localhost/', pathname: '/', reload: noop };
Object.defineProperty(globalThis, 'navigator', { value: { maxTouchPoints: 0, userAgent: 'node' }, configurable: true });
globalThis.matchMedia = q => ({ matches: false, media: q, addEventListener: noop, removeEventListener: noop });
globalThis.window = {
addEventListener: addL, removeEventListener: noop, AudioContext: null, webkitAudioContext: null,
innerWidth: 1280, innerHeight: 800, location: globalThis.location, navigator: globalThis.navigator, matchMedia: globalThis.matchMedia,
};
globalThis.addEventListener = addL;
globalThis.removeEventListener = noop;
globalThis.confirm = () => true;
globalThis.alert = noop;
globalThis.localStorage = { _d: {}, getItem(k) { return this._d[k] ?? null; }, setItem(k, v) { this._d[k] = String(v); }, removeItem(k) { delete this._d[k]; } };
globalThis.document = {
getElementById(id) { if (!els.has(id)) els.set(id, mkEl(id)); return els.get(id); },
querySelector(s) { return mkEl(s); },
querySelectorAll() { return []; },
createElement(t) { const e = mkEl(); e.tagName = t.toUpperCase(); return e; },
addEventListener: addL, body: mkEl('body'),
};
let fail = 0;
const ok = (c, m) => { console.log((c ? ' ✔ ' : ' ✗ ') + m); if (!c) fail++; };
const resetC = () => { for (const k in C) C[k] = 0; };
const { Editor } = await import('../js/editor.js');
const { PALETTE } = await import('../js/editor.js');
console.log('=== 编辑器初始化(会经 buildPalette 渲染全部调色板方块)===');
try {
Editor.init({ startLevel: noop });
ok(true, 'Editor.init 成功(所有调色板方块缩略图渲染无异常)');
} catch (e) { ok(false, 'Editor.init 失败: ' + e.message); console.log(e.stack.split('\n').slice(0, 4).join('\n')); }
console.log('=== 打开空白地图并绘制 ===');
Editor.open();
const f = Editor.curFace();
ok(f && f.w > 0 && f.h > 0, 'open 生成可编辑面(' + f.w + '×' + f.h + ')');
console.log('=== 刺在编辑器里以三角形绘制 ===');
f.grid[1][1] = '^';
resetC();
Editor.draw();
ok(C.lineTo > 0 && C.beginPath > 0, '刺:用三角形图元绘制(lineTo=' + C.lineTo + ', beginPath=' + C.beginPath + ')');
console.log('=== 方块在编辑器里以真实纹理绘制 ===');
f.grid[1][1] = '#';
resetC();
Editor.draw();
ok(C.fillRect > 0, '方块:实心纹理绘制(fillRect=' + C.fillRect + ')');
console.log('=== 每种方块类型在编辑器画布都能正常绘制不抛异常 ===');
let bad = 0;
for (const [ch] of PALETTE) {
if (ch === '.') continue;
try { f.grid[2][2] = ch; Editor.draw(); }
catch (e) { console.log(' ✗ ' + ch + ': ' + e.message); bad++; }
}
ok(bad === 0, '全部 ' + PALETTE.filter(p => p[0] !== '.').length + ' 种方块绘制无异常');
console.log(fail === 0 ? '\n✅ 编辑器所见即所得 全部断言通过' : `\n❌ 失败 ${fail} 项`);
process.exit(fail === 0 ? 0 : 1);