纯前端静态网页实现:输入蓝图(Base64 或 .msch 文件)→ 浏览器内解析 →
canvas 渲染(多层贴图、描边、电力激光、桥连接、原版背景全部保留)→
点击处理器弹代码、悬停提示、图例、导出 PNG。
- 无需构建步骤、无需后端,vanilla JS + ES modules。
- 可直接挂到 GitHub Pages,也可用
python3 -m http.server本地打开。 - 所有资源均为相对路径,部署在子路径(如
https://用户名.github.io/仓库名/)也能正常工作。
声明:本项目由 AI 生成(AI 辅助设计与编写),仅供学习与个人使用。 许可:本仓库代码为 GPL-3.0-or-later(详见根目录 LICENSE,正文取自 FSF 官方发行)。Mindustry 的原版贴图与图标字体(GPL-3.0)不随本仓库分发, 均由页面在运行时从官方仓库
Anuken/Mindustry拉取(镜像/CDN);可选的assets/sprites/自托管贴图由使用者自行提供。
index.html 页面入口
css/style.css 深色中文界面样式(含 MindustryIcons @font-face)
js/data.js 常量与中文映射(TILE/LAYERS/BLOCK_CN/CONTENT_CN/…)
js/cn_data.js 全量官方中文名(由 bundle_zh_CN.properties 生成)
js/inflate.js zlib 解压封装(DecompressionStream)
js/parser.js 容器解析 + TypeIO + contentMap + 处理器逻辑提取
js/render.js 渲染器(画布缓冲渲染)
js/blending.js 邻居拼接 Autotiler(纯函数)
js/vanilla_blocks.js 官方方块类型/属性表
js/vanilla_turrets.js 官方炮塔部件表
js/icons.js PUA 内容图标解析 + richText 富文本
js/icons_data.js PUA 码点表(由 icons.properties 生成)
js/prefetch.js 输入哈希 + 预加载管理器
js/cache.js Cache Storage 持久化缓存(v2 + 规范化键 + SWR/TTL)
js/sources.js Mindustry 镜像源(手动选择 + 超时 + 自动切换)
js/zip.js 纯 JS zip 读取器
js/mod.js 模组 zip 解析
js/names.js 方块显示名
js/history.js 本地历史记录(纯函数)
js/requirements.js 蓝图总耗材计算
js/requirements_data.js 方块耗材表 BLOCK_REQUIREMENTS + 物品中文名 ITEM_CN
js/main.js 入口 UI 逻辑(入口带 ?v=<VER> 查询做缓存穿透)
sprite_index.json 贴图名 → 相对路径索引(blocks/items/aux/all)
package.json {"type":"module"}
本仓库根目录就是站点内容(index.html、css/、js/、sprite_index.json 等),
无需任何构建步骤,直接按下面的步骤挂到 GitHub Pages 即可。
- Fork 或克隆本仓库:在 GitHub 上 Fork
colorgarden/schemascope; 或克隆到本地后推送到自己的仓库(换成自己的地址):git clone https://github.com/colorgarden/schemascope.git cd schemascope git remote set-url origin https://github.com/你的用户名/你的仓库.git git push -u origin main - 开启 Pages:仓库 Settings → Pages。
- Source 选 Deploy from a branch;
- Branch 选
main,目录选/ (root),Save。
- 等待约 1 分钟,访问
https://你的用户名.github.io/你的仓库/即可。
提示:如果入口页面无法访问,确认仓库根目录存在
index.html(本工具不需要任何构建/工作流)。发布须知:GitHub Pages/中间代理默认
cache-control: max-age=600,用户可能看到旧缓存。 每次发布请把版本号 VER 在这些地方同步递增:
index.html顶部注释(VER: <VER>);- 入口
js/main.js?v=<VER>与css/style.css?v=<VER>;js/main.js内的APP_VERSION(页脚版本由 JS 注入,能显示即证明新脚本已加载);js/*.js内部所有相对 import 的?v=<VER>,一条命令:sed -i 's|\.js?v=[0-9a-z]*"|.js?v=<VER>"|g' js/*.js(保证入口与各模块同版本,避免「新入口 + 旧缓存模块」混用导致整个应用报错);- 若用户仍看到旧版本或异常,请其清理浏览器缓存(或换浏览器/无痕模式)后重试。
默认情况下,贴图会先尝试 assets/sprites/<名称>.png,找不到再按「镜像源」列表自动切换拉取
(见「镜像源」小节,默认首选 https://gh-proxy.com/https://raw.githubusercontent.com/Anuken/Mindustry/master/)。
要完全离线(首次加载更快、无网络也能用),把贴图缓存目录一并上传:
- 在仓库根目录新建
assets/sprites/。 - 把贴图 PNG(或从 Mindustry 仓库下载,
文件名必须是方块/贴图名 +
.png,例如mass-driver.png、laser.png、schematic-background.png)全部放入assets/sprites/。 - 重新 push。页面会自动优先使用本地贴图。
schematic-background.png(原版蓝图卡片背景)也放在assets/sprites/下。
- 指向别的 CDN / 镜像:编辑
js/sources.js的SOURCES(按优先级排列), 或删除不需要的源;运行时会自动切换并记住最近可用源。 - 改单个贴图路径:编辑
sprite_index.json(或js/data.js的AUX_PATHS)。 索引结构为:{ "sprites_base": "core/assets-raw/", "blocks": { "mass-driver": "sprites/blocks/distribution/mass-driver.png" }, "items": { "item-copper": "sprites/items/item-copper.png" }, "aux": { "laser": "sprites/effects/laser.png" }, "all": { "gamma": "sprites/units/gamma.png" } }blocks/items/aux:渲染与贴图加载使用(保持不变)。all:sprites/**/*.png的「文件名(去扩展名) → 相对路径」全量索引, 供 PUA 内容图标解析使用;重名取第一个。schematic-background比较特殊,位于core/assets/(非 assets-raw), 已在AUX_PATHS中用[base, path]形式配置。
- 重新生成
sprite_index.json:可从 Mindustry 仓库的贴图目录(tree.json)重新扫描后覆盖本文件。
游戏的消息 / 标签文本里会出现私用区字符(U+E000–U+F8FF),分两类:
- 内容图标:物品 / 液体 / 方块 / 单位等,由
icons/icons.properties(格式十进制码点=名称|图集区域名)定义,游戏启动时把区域注册为字体字形。 前端不依赖静态字体,而是查贴图后用<img class="msch-icon">呈现:- 数据来源:
icons.properties→js/icons_data.js(ICON_BY_CODE,626 条)。 - 解析:
js/icons.js的resolveIcon(code);区域名去掉结尾-ui得 base, 依次尝试base及其去前缀(block-/unit-/item-/status-/team-)形式, 在sprite_index.json的all/blocks/items中查路径。 - 例:
63528→water/liquid-water→sprites/items/liquid-water.png。
- 数据来源:
- UI emoji(fontgen 那批,如左右箭头):在官方图标字体
icon.ttf(U+E800–U+F308)里。字体不随本仓库分发(GPL 资源):页面启动时经镜像从官方 仓库拉取core/assets/fonts/icon.ttf,用FontFace注册为MindustryIcons并挂在正文/代码等 font-family 回退链末尾;拉取失败自动降级。
展示游戏原文的 HTML 上下文(信息板弹窗、信息板 tooltip、处理器代码弹窗、
蓝图标签 tags.labels)统一经 richText() 渲染;<img> 加载失败会回退。
原生 title 等纯文本上下文用 plainTextWithIcons():内容图标 → [官方中文名],
UI emoji → 去掉。
素材均来自 Mindustry 官方仓库(Anuken/Mindustry,GPL-3.0):
icons.properties仅以内联数据形式使用(js/icons_data.js),贴图与字体均在运行时拉取, 不随本仓库分发。
- 全量官方中文名
js/cn_data.js:由官方bundle_zh_CN.properties生成 (CN_BLOCKS412 条 /CN_ITEMS22 条 /CN_LIQUIDS11 条)。js/data.js的BLOCK_CN/CONTENT_CN以之为准(旧手写小表仅用于补缺,不覆盖官方名),因此overflow-gate→溢流门、underflow-gate→反向溢流门、duct等均有正确中文名。 - 运行时图标:内容图标的贴图由
resolveIcon解析后直接使用官方原贴图 URL (本地assets/sprites/自托管优先,否则 CDN 镜像);js/icons_data.js的ICON_BY_CODE(626 条)为纯数据表。不再随仓库导出/分发图标 PNG(原导出自 GPL 资源,一律运行时从官方仓库拉取)。 - 耗材
js/requirements_data.js:BLOCK_REQUIREMENTS(231 个方块)来自 MindustryBlocks.java的requirements(...),与游戏Schematic.requirements()一致 (把每个方块的 requirements 直接累加,无倍率);ITEM_CN为官方中文名。 渲染完成后,js/requirements.js的computeRequirements()/requirementsList()累加并在页面显示「耗材」面板(物品图标 + 中文名 + ×数量,按数量降序)。 - 配置影响贴图(v159.7 源码行为):
js/data.js用CONFIG_UNDERLAY/CONFIG_OVERLAY描述配置对贴图的影响,render.js在 sprite 层前后绘制:sorter/inverted-sorter/item-source(underlay):配置为空 → 画cross-full(原色); 有内容 → 整格TILE×TILE填充内容色(CONTENT_COLORS)。unloader/duct-unloader(overlay):有内容 → 画<block>-center(unloader-center/duct-unloader-center)并乘内容色;为空不画。liquid-source(overlay):source-bottom→ 空则cross、有液体则用fluid.png铺满整格并以液体色着色 → 重画一次该方块 sprite(最上层)。CONTENT_COLORS按官方Items.java/Liquids.java(v159.7)补全物品与液体颜色;opts.config_icons=false时上述配置贴图全部跳过。
- 多层贴图
LAYERS(base → …,普通中心叠加、无 tint):覆盖钻头类(-rotator/-top, 碎石机含-rotator-bottom)、生产/电力/防御/单位工厂/载荷/管道等双层建筑([base, base-top]), 以及thruster、wave/tsunami/sublimate、liquid-overflow-gate等。sorter/inverted-sorter/liquid-source不含source-bottom(v159.7 中该层并不存在;liquid-source的source-bottom由配置覆盖层在 sprite 之后绘制),否则不透明灰层会盖住配置色。 - 原版顶盖(已恢复):
kiln/silicon-smelter/silicon-crucible/surge-smelter、plastanium-compressor、slag-incinerator、combustion/steam/differential/rtg-generator、thorium-reactor、mender、mend-projector、overdrive-projector、overdrive-dome按用户要求 恢复为[base, base-top]常驻绘制(这些静态顶盖 region 与模组drawer判定相互独立)。vent-condenser层序为 bottom→rotator→mid→base。
支持载入 Mindustry 模组 zip(.zip / .jar 同格式)来渲染模组建筑并统计模组耗材。
- 载入方式:输入区下方「模组」小节,多选或拖拽
.zip/.jar;显示名称/内部名 + 方块数 + 贴图数;可单个移除或清除全部。 - 持久化:zip 存入 Cache Storage(缓存名
msch-mods-v1,key/__mods__/<文件名>), 下次打开自动重新加载;移除/清除时同步删除。 - 解析(
js/mod.js+js/zip.js,纯 JS、无第三方库):mod.json的name为内部模组名,方块内部名 =<name>-<文件名去.json>。- 宽松 JSON:支持
//、/* */注释、尾随逗号、缺失逗号(部分模组 JSON 不规范)。 requirements同时支持"item/amount"与{item,amount}。bundles/bundle_zh_CN.properties/bundle.properties提供方块与物品中文名。
- 贴图懒解压(大模组关键优化):解析时只登记 zip 中央目录条目(
sprites/**与sprites-override/**的 basename → 条目),不解压字节;首次真正用到某张贴图时才 解压该条目并缓存为 Blob(会话内)。mod.sprites.size为条目数,mod.spritesOverride.size为 override 条目数;UI 显示「贴图 N(按需加载)」。sprites-override仍覆盖sprites。 - 桥 / 质驱按 JSON
type判定(不硬编码名字):- 桥:
type以Bridge结尾(ItemBridge/LiquidBridge/BufferedItemBridge/DirectionalBridge等), 采集<block>-bridge/<block>-arrow贴图并画连接线与箭头;配对范围取模组range(否则 vanilla 值,再否则 4);桥带宽度统一与原版一致(不按模组bridgeWidth放大)。 - 质量驱动器:
type === "MassDriver"(或以之结尾),按 vanilla 规则套用描边;outlineIcon===false不描边,颜色取outlineColor(支持#rrggbb/rrggbb)否则#404049,半径取outlineRadius否则 4。 - 电力节点:
type以PowerNode结尾(PowerNode/LongPowerNode等)→ 渲染电线(光束)。单节点参数:scale = laserScale ?? 0.25;width = round(POWER_LASER_WIDTH * scale / 0.25)(如laserScale 0.4→ 10px); 端帽按scale;颜色lerp(laserColor1 ?? 白, laserColor2 ?? d9f7b2, 0.1)(十六进制带/不带#均可)。 - 电力目标:vanilla POWER_BLOCKS ∪ 模组
hasPower===true/consumes.power方块 ∪ 模组质驱 ∪ 模组电力节点, 均可被电力节点连线(模组节点之间也能互连)。
- 桥:
- 方块显示名优先级:模组语言文件
block.<内部名>.name(带<mod>-前缀时也尝试block.<base>.name)→ 模组 JSON 的name字段 → 内置BLOCK_CN→ 内部名。 图例、热区提示、处理器按钮等均使用该显示名(js/names.js的blockDisplayName)。 - 不针对任何具体模组:桥/质驱/电力节点全部按 JSON
type字段(*Bridge/MassDriver/*PowerNode)+ 运行时注册判定,代码中不含任何模组名(测试所用真实模组仅作 fixture);通用性由合成模组测试固定(任意名字 + 类型即可正确分类/注册/渲染)。 - 渲染集成:贴图查找顺序为 内存 → 模组
sprites-override→ 本地assets/sprites→ 镜像源(超时/自动切换)→ 模组sprites→ 占位;模组方块缺失贴图但 JSON 有size时按该尺寸占位。 - 模组多层 = 按 JSON
drawer绘制栈解析(js/mod.js的drawerStaticLayers): 仅保留DrawDefault(本体)与DrawRegion(base+suffix,支持x/y偏移 ×4、rotation角度;suffix支持中文如-顶/-底/-转;类型比较大小写不敏感,DrawMulti.drawers递归); 火焰/发光/工作态(DrawFlame/DrawGlowRegion/DrawCultivator/DrawWarmupRegion/DrawFade/…)一律跳过。 无 drawer 时按该type原版默认:Drill/SolidPump→[base,-rotator,-top]、UnitFactory→[base,-top]、其它 →[base]。不再使用-top自动启发式。 - 传送带/管道/导管邻居拼接(Autotiler):
js/blending.js逐条移植官方Autotiler.buildBlending/transformCase/blends与 Conveyor/Duct/Conduit(含装甲变体)的blends重写;邻居仅在蓝图内查找。每个 tile 算出blendbits(0..4)后取<名>-<blendbits>-0(传送带)或<名>-top-<blendbits>(导管/管道,底图*-bottom-<bits>), 再按xscl/yscl(−1 = 翻转)与rot×90绘制。sliced()的 bit4 边缘装饰块暂未画(TODO)。 - 炮塔部件(DrawTurret / RegionPart):
js/vanilla_turrets.js记录 basePrefix 与每个 RegionPart 的静态几何;渲染 = base(不旋转)→ 本体<名>(rotation−90)→-top→ 部件(under=true在本体前,mirror 用<名>-r/<名>-l镜像)。heat/glow/ShapePart/HaloPart/ setAmmoParts 与 recoil/warmup 进度动画忽略(静止态)。 - 原版顶盖:
LAYERS中 kiln/silicon-smelter/…/overdrive-dome 等 15 项[base, base-top]为常驻顶层 region,照旧绘制;只有钻石类-rotator、工作态火焰/发光层按上方规则区分。 - 耗材集成:总耗材表 = vanilla
BLOCK_REQUIREMENTS+ 所有模组方块(内部名与 base 都注册); 物品名优先取模组 bundleitem.<内部名>.name,物品图标优先模组贴图,候选顺序为item-<ref>→<ref>→<ref>1→item-<ref>1(后两个为序号帧贴图兜底, 如裂位能1.png、二级协议1.png);模组方块贴图候选同样在最后追加<name>1。 - 限制:JSON / 混合模组可完整支持建筑与耗材;纯 dex 模组(无 JSON 方块定义) 只能按文件名使用其贴图,无法获取建筑尺寸与耗材。
- 「贴图缺失」只在必需贴图缺失时提示:可选层(炮塔
-base/-top、工厂-top、 桥-bridge/-arrow等不存在的层)缺失属正常,不再误报(selectMissingSprites)。 同时收集贴图时对 vanilla 只请求sprite_index.json中确实存在的可选层,避免无谓的 CDN 404;规范底座缺失时按spriteVariantCandidates(如传送带<名>-0-0、墙壁<名>1) 解析。全量原版方块保证「无必需贴图缺失 / 无未识别方块 / 无可选层空请求」 (环境/旧版方块除外)。另修复constructor等方块名撞上Object.prototype同名属性导致的层名错乱。 - 模组变化后会清空内存贴图缓存并自动重渲染当前蓝图;未识别方块会在状态栏提示可能缺少的模组。
- v1:
msch+ version + zlib;tile config 走TypeIO.readObject(当前主格式)。 - v0 旧格式:tile config 为裸 int + 按方块类型映射(
mapConfig)—— Sorter/Unloader/ItemSource → 物品 id 名(Items.java 声明序);LiquidSource → 液体 id 名; MassDriver/ItemBridge → 打包 Point2 相对位置;LightBlock(illuminator) → 原样 int;其它 → null。 每块恒 4 字节 config + 1 字节 rotation。 - 版本校验:
version > 1抛错「蓝图来自更新版本的游戏(vN),当前最高支持 v1」。 - 旧方块名回退:按官方
SaveFileReader.fallback(51 项)映射后用于贴图/显示 (如turbine-generator→steam-generator、mass-conveyor→payload-conveyor、block-forge→constructor)。 - LegacyBlock 跳过:
legacy-mech-pad/legacy-unit-factory(-air/-ground)/legacy-command-center解析后剔除,不渲染。 - contentMap:优先
JSON.parse(官方{"0":{"copper":1}}),失败回退旧正则 ({0:{surge-alloy:12}})。
- 在文本框
input、文件选择change、拖拽drop三处加了 350ms 防抖自动解析: 停止输入后立即在后台解析并预加载贴图,状态栏显示「已解析:N 个方块,预加载贴图 done/total…」。 - 预加载由
js/prefetch.js的createPrefetchManager管理:按输入哈希复用已解析结果, 并带竞态保护(输入变化时丢弃旧任务结果)。点击「解析并渲染」时若哈希命中, 直接复用并await未完成的加载,通常近乎瞬时完成。 - 贴图并发批量加载为 16。
- 打开页面时输入框为空(不再自动缓存/回填蓝图本体;旧键
msch-last-input会在启动时清理)。 输入、选择文件、拖拽、点击历史条目均会触发预加载。
- 选择 / 拖入
.txt/.msch后,输入框会填入文件内容本身(而非文件名占位文本):- 文本型(解码后全为 Base64/空白且以
bXNja开头)→ 直接填入原文(trim); - 二进制
.msch→ 用bytesToBase64()转成 Base64 文本填入。
- 文本型(解码后全为 Base64/空白且以
- 状态栏显示「已读取文件:<文件名>(N 字节)」;随后自动解析渲染。
- 输入区下方会出现来源标签
#input-source:文件加载时显示文件:<名>(N 字节); 手动编辑/粘贴 textarea、点击历史条目或清空输入时自动隐藏。 - 由于输入框此时就是可再次解析的字符串,「解析并渲染」可重复点击,且文件加载同样会写入 历史记录(不再出现「选文件后无历史」的问题)。
- 解析+渲染成功后写入
localStorage.msch-history(JSON 数组,新→旧),条目:{ hash, name, w, h, tiles, time, input }(hash为输入哈希,input为原始文本)。 - 同
hash去重并置顶(刷新时间);点击历史项 = 填入输入框并重新解析渲染。 - 容量策略(
js/history.js纯函数):单条input > 1MB不记录;总条数 ≤ 16; 总字节(按input.length)≤ 2MB,超限从最旧淘汰;写入失败(配额)→ 淘汰一半重试一次, 仍失败静默放弃。 - UI:「输入蓝图」正下方的「历史记录」小节(PC 左栏同序:输入 → 历史 → 模组 → 渲染选项),列表项显示
名称 · 宽×高 · 方块数 · 相对时间,右侧×删除,标题旁「清空」; 小节始终显示,空列表时为弱化提示「暂无历史记录,解析蓝图后自动保存到本地」。
js/cache.js用caches.open("msch-cache-v2")缓存贴图与sprite_index.json:- 命中 → 立即用缓存 Response(blob→
createImageBitmap),页面刷新后无需重新联网; - stale-while-revalidate:缓存条目超过 TTL 7 天时,先返回缓存、后台 fetch 刷新;
- 未命中 → 走超时/镜像链路 fetch → 成功才
cache.put;失败/超时绝不写缓存。
- 命中 → 立即用缓存 Response(blob→
- 缓存键规范化:Mindustry 素材统一记为
location.origin + "/__sprites__/" + relPath(与镜像源无关),换镜像后缓存依然命中,避免重复下载。 - 时间戳记录在
localStorage.msch-cache-meta。 - 不可用时(非 https、无
cachesAPI、隐私模式、localStorage被禁)自动回退到普通fetch+ 会话内内存缓存,不报错。 - 状态栏会显示「(缓存命中 X 张)」。
- 页脚「清除缓存」:删除全部
msch-*Cache Storage 持久缓存(贴图、模组 zip、含历史版本) 与时间戳记录,随后带?fresh=参数强制刷新页面(location.replace,不污染历史栈), 以绕过浏览器/代理的 HTTP 缓存取回最新 HTML 与版本化脚本。 不会清除历史记录、透明度、镜像源偏好(这些有各自入口:历史「清空」、滑杆、贴图源下拉)。
「渲染选项」区可选择贴图源(默认「自动(推荐)」,选择持久化在 localStorage.msch-source-choice),
也可点「检测镜像」并行探测全部源:结果显示为可点击徽章(名称 320ms ✓ / 名称 超时 ✗),
点击即选用该源并自动重新加载贴图重渲染;下拉旁小字显示当前源。
已实测源顺序(可靠的国内镜像最前):
| key | 显示名 | 前缀 |
|---|---|---|
gh-proxy |
gh-proxy.com(国内镜像) | https://gh-proxy.com/https://raw.githubusercontent.com/Anuken/Mindustry/master/ |
ghproxy-net |
ghproxy.net(国内镜像) | https://ghproxy.net/https://raw.githubusercontent.com/Anuken/Mindustry/master/ |
gcore |
jsDelivr Gcore | https://gcore.jsdelivr.net/gh/Anuken/Mindustry@master/ |
testingcf |
jsDelivr TestingCF | https://testingcf.jsdelivr.net/gh/Anuken/Mindustry@master/ |
cdn |
jsDelivr 官方(cdn) | https://cdn.jsdelivr.net/gh/Anuken/Mindustry@master/ |
fastly |
jsDelivr Fastly | https://fastly.jsdelivr.net/gh/Anuken/Mindustry@master/ |
raw |
GitHub Raw(直连) | https://raw.githubusercontent.com/Anuken/Mindustry/master/ |
- 为何 gh-proxy / gcore 优先:gh-proxy / ghproxy 直接代理 raw,实测 200、0.6–2s、CORS
*; jsDelivr Gcore 即使是冷文件也 200。jsDelivr 的cdn/fastly对冷文件会301 → raw.githubusercontent(易被墙卡住),故排在其后;raw直连虽 200 但常 12s+ 抖动,作最后兜底。 - 顺序逻辑:
getSourceOrder()—— 手动选择时 =[所选源, ...其余按默认顺序]; 自动时 =[上次可用源(若有), ...默认顺序去重]。每次请求AbortController8 秒超时, 失败/超时自动切下一个源;成功的源写入localStorage.msch-source。 - 无 last-good 且未手动选择时先用小文件(
core/assets-raw/sprites/effects/error.png,3 秒超时) 探测一次,避免前 16 个并发全部各等 8 秒。 - 发生切换时状态栏提示「下载超时,已切换镜像:」。
- 耗材面板中未命中模组的原版物品图标也使用当前可用源。
- 缓存键为规范化相对路径(
/__sprites__/…),切换源后命中缓存的部分无需重下。
- 放大倍数、背景(原版蓝图背景 / 透明)、显示网格:变更后立即重渲染。
- 电线透明度(默认 100%)与桥透明度(默认 50%)两条滑杆:
input250ms 防抖 实时重渲染;只影响绘制,不影响贴图缓存/镜像选择;「导出 PNG」使用当前滑杆值。 选择持久化在localStorage.msch-laser-alpha/msch-bridge-opacity(0–100 整数), 初始化时回填并在首次渲染应用。渲染层对应renderSchematic的opts.laserAlpha与opts.bridgeOpacity(缺省沿用原常量,行为不变)。
python3 -m http.server 8000
# 浏览器打开 http://localhost:8000/直接双击 index.html(file://)也能打开界面,但浏览器会因同源策略拦截
本地文件读取;请务必用上面的 http.server 方式预览。
依赖原生 DecompressionStream('deflate') 解压蓝图,需较新版本的
Chrome / Edge / Safari / Firefox。若浏览器过旧,页面会给出明确中文提示。
GNU General Public License v3.0 or later(GPL-3.0-or-later),详见根目录 LICENSE 文件 (GPLv3 正文取自 FSF 官方 GNU 发行包,未从任何第三方仓库复制)。
本项目由 AI 生成:可自由使用、修改与分发;分发衍生作品时须同样以 GPL-3.0 开源并保留版权声明。