首页 / 资讯中心 / 文章详情

把一张穿孔卡做成可导出的 SVG

把一张穿孔卡做成可导出的 SVG ★ FEATURED ARTICLE
复古界面最容易做出“像真的”也最容易顺手写下“仿真”。一张浅黄色卡片配上等距孔位就有了老机器的气息但它并没有因此成为历史设备的编码器。这个小工具只做一件事把一段短 ASCII 文本转换为八位二进制再画成 SVG 孔位。每个字符占一行最高位在左1 画深色孔0 画浅色格。这里采用的是为了阅读而设计的八列排布不是 Hollerith 卡片的列码也不承诺能被任何实体读卡器识别。先约定编码再画纸张例如H的码值是 72对应01001000。如果只从第二、第五格打孔读者就能手工检查这一行。中文字符则不在本例的范围内不要悄悄取 UTF-16 低八位那会产生可画却不可解释的结果。SVG 可以把几何与导出内容放在同一份文本里。SVG 2 的路径规范明确区分位置、线段和曲线命令这个卡片甚至用不到复杂路径圆角矩形就足够。图形简单错误也更容易看见。下面代码在 Node.js 中直接运行会生成一份card.svg。标签经过 XML 转义输入限制为最多 24 个可打印 ASCII 字符。导出的是矢量文档尺寸可以缩放字体外观仍取决于打开它的环境。若做浏览器下载需要额外处理 Blob URL 的释放和用户触发不是把文件扩展名改成 SVG 就算完成。复古质感别抢走信息纸边噪点、折痕和编号可以后加但不能覆盖孔位。可访问版本还应保留原文本和二进制字符串让不方便读图的人也能拿到同样的信息。例子在desc中放入了原文并在每行右侧写出位串。本地检查验证了H的位串、孔数量、XML 特殊字符转义和非 ASCII 拒绝没有对实体打印、读卡器、浏览器字体做兼容测试。它适合做一张程序员节纪念卡。只要把装饰规则说清楚玩具也可以很认真。可独立运行的核心例子const fs require(node:fs); const xml s s.replace(/[]/g, c ({:amp;,:lt;,:gt;,:quot;,:apos;}[c])); function bits(text) { if (!text.length || text.length24 || /[^\x20-\x7E]/.test(text)) throw Error(只接受1到24个可打印ASCII字符); return [...text].map(c c.charCodeAt(0).toString(2).padStart(8,0)); } function card(text) { const rowsbits(text), h80rows.length*28; const cellsrows.flatMap((row,y) [...row].map((b,x) rect x${28x*22} y${48y*28} width14 height18 rx3 fill${b1?#453f4d:#e3d7c4}/)); const labelsrows.map((row,y) text x220 y${62y*28} font-size12${row}/text); return svg xmlnshttp://www.w3.org/2000/svg viewBox0 0 340 ${h} descASCII八位装饰卡${xml(text)}/desc rect width340 height${h} rx12 fill#f6ead6/ text x28 y28DECORATIVE ASCII CARD/text ${cells.join()}${labels.join()}/svg; } if(bits(H)[0]!01001000) throw Error(编码错误); if((bits(H)[0].match(/1/g)||[]).length!2) throw Error(孔数错误); if(!card().includes(lt;amp;)) throw Error(转义错误); let rejectedfalse;try{bits(秋);}catch{rejectedtrue;} if(!rejected) throw Error(非ASCII不应静默截断); fs.writeFileSync(card.svg,card(HELLO 1024)); console.log(已生成 card.svg装饰编码不用于实体检票或读卡);
阅读完成 · 觉得有帮助?
咨询建站