diff --git a/convert-w2p.js b/convert-w2p.js index fa081db..5cf769c 100644 --- a/convert-w2p.js +++ b/convert-w2p.js @@ -316,11 +316,11 @@ function convert(input) { return results; } - // 找到所有 slide 容器 + // 找到所有 slide 容器(name 为 slide-N 或 page 的节点) function findSlides(node) { if (!node || !node.name) return []; const results = []; - if (/^slide-\d+$/.test(node.name)) { + if (/^slide-\d+$/.test(node.name) || node.name === 'page') { results.push(node); } if (node.children && Array.isArray(node.children)) { @@ -368,7 +368,7 @@ function convert(input) { } if (node.children) for (const c of node.children) { // 跳过 slide 容器的子树(它们已经被 collectSlideChildren 处理了) - if (c.name?.startsWith('slide-')) continue; + if (c.name?.startsWith('slide-') || c.name === 'page') continue; results.push(...collectOrphans(c)); } return results; @@ -418,6 +418,13 @@ function convert(input) { console.log('处理 ' + sg.name + ': ' + sg.children.length + ' 个节点'); + // 排序:FRAME 类型的排在前面(作为背景),TEXT 排在后面(作为前景文字) + sg.children.sort(function(a, b) { + if (a.type === 'TEXT' && b.type !== 'TEXT') return 1; + if (a.type !== 'TEXT' && b.type === 'TEXT') return -1; + return 0; + }); + for (const n of sg.children) { // 跳过 raster 底图(保留 IMAGE 类型) if (n.type === 'RECTANGLE') { continue; } @@ -445,9 +452,8 @@ function convert(input) { if (st.fontStyle === 'italic') opts.italic = true; if (st.textAlign && st.textAlign !== 'start') opts.align = st.textAlign; - // 宽度优先用父容器,否则用文字自身宽度,再加 20% 余量防止换行 - var baseW = (n.parentW || r.w); - opts.w = Math.round(baseW * 1.2 / 72 * 1000) / 1000; + // 宽度优先用父容器宽度,确保不换行 + opts.w = Math.round((n.parentW || r.w) / 72 * 1000) / 1000; objects.push({ type: 'text',