如何编写if else逻辑实现paper.js中数字连续0的路径合并处理
解决方案
- 首先放弃从路径反向推断是否为连续0的逻辑,改为先定位原始文本中连续0的位置,再对应处理对应字符的路径,准确率更高,逻辑也更清晰。
- 不要直接调用
font.getPath生成整串字符的合并路径,改为逐个字符生成路径,即可精准匹配每个字符对应的路径组,避免路径归属判断错误。
实现代码
paper.install(window); window.onload = () => { paper.setup("canvas"); opentype.load( "https://assets.codepen.io/1070/pphatton-ultralight-webfont.woff", (err, font) => { if (err) { console.log(err); return; } // 输入文本 const inputText = "1000"; // 第一步:标记需要做实心处理的0的索引位置 const needSolidZeroIndex = new Set(); for (let i = 0; i < inputText.length; i++) { if (inputText[i] === '0') { // 判断前后是否有相邻的0,只要有一个就算连续0 const hasPrevZero = i > 0 && inputText[i-1] === '0'; const hasNextZero = i < inputText.length -1 && inputText[i+1] === '0'; if (hasPrevZero || hasNextZero) { needSolidZeroIndex.add(i); } } } // 第二步:逐个字符生成路径,避免整串生成后归属混乱 let offsetX = 0; const fontSize = 100; const allPath = new paper.Group(); for (let i = 0; i < inputText.length; i++) { const char = inputText[i]; const charPath = font.getPath(char, offsetX, 100, fontSize); const paperPath = new paper.CompoundPath(charPath.toSVG()); offsetX += font.getAdvanceWidth(char, fontSize); // 第三步:如果是需要实心处理的0,合并内外路径 if (char === '0' && needSolidZeroIndex.has(i)) { // 找到0对应的外路径(19段)和内路径(18段)合并 let outerPath, innerPath; paperPath.children.forEach(child => { if (child.segments.length === 19) outerPath = child; if (child.segments.length === 18) innerPath = child; }); if (outerPath && innerPath) { const united = outerPath.unite(innerPath); united.fillColor = 'red'; allPath.addChild(united); } } else { paperPath.fillColor = 'red'; allPath.addChild(paperPath); } } project.activeLayer.fitBounds(view.bounds.scale(0.6)); view.draw(); } ); };
方案优势
- 完全避免了路径归属误判的问题,从原始文本就锁定了需要处理的0的位置,不会出现单0被误处理的情况
- 逻辑可复用性更高,后续如果修改连续数字的处理规则,只需要调整第一步的标记逻辑即可,不需要改路径处理部分
- 性能更优,不需要遍历所有路径做多余的条件判断,只处理标记过的目标字符即可
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

