From 0ed04eb3ea57f6d2387eaed1baf3955670ddf5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=BF=9B?= Date: Fri, 24 Jul 2026 17:36:07 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E8=83=8C=E6=99=AF=E8=89=B2?= =?UTF-8?q?=E5=85=9C=E5=BA=95=E7=94=A8=20canvas=20=E8=83=8C=E6=99=AF?= =?UTF-8?q?=E8=89=B2=E6=9B=BF=E4=BB=A3=E7=A1=AC=E7=BC=96=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- convert-w2p.js | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/convert-w2p.js b/convert-w2p.js index 0db45dd..233b55f 100644 --- a/convert-w2p.js +++ b/convert-w2p.js @@ -468,7 +468,13 @@ function convert(input) { const g = parseInt(tc.slice(2,4), 16); const b = parseInt(tc.slice(4,6), 16); const lum = (r * 299 + g * 587 + b * 114) / 1000; - slideBg = lum > 128 ? { color: '1A1A1A' } : { color: 'FAFAFA' }; + // 浅色文字 → 深色背景(用 canvas 背景色),深色文字 → 浅色背景(取反) + if (lum > 128) { + const canvasBg = canvas.backgroundColor ? rgbaToHex(canvas.backgroundColor) : null; + slideBg = { color: canvasBg || '1A1A1A' }; + } else { + slideBg = { color: 'FAFAFA' }; + } } } } @@ -661,9 +667,16 @@ function convert(input) { if (n.styles.display === 'none' || n.styles.visibility === 'hidden') { continue; } let fillColor = null; + let fillTransparency = null; const bg = n.styles.backgroundColor; if (bg && bg !== 'rgba(0, 0, 0, 0)' && bg !== 'transparent') { fillColor = rgbaToHex(bg); + // 提取 alpha 通道作为 transparency + const alphaMatch = bg.match(/rgba?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*([\d.]+)\s*\)/); + if (alphaMatch) { + const alpha = parseFloat(alphaMatch[1]); + if (alpha < 1) fillTransparency = Math.round((1 - alpha) * 100); + } } if (!fillColor) { const bgImg = n.styles.backgroundImage; @@ -674,9 +687,12 @@ function convert(input) { } if (fillColor) { var shapeOpts = { x: opts.x, y: opts.y, w: opts.w, h: opts.h, fill: { color: fillColor } }; - // 透明度 + // 透明度(来自 alpha 通道) + if (fillTransparency) shapeOpts.fill.transparency = fillTransparency; + // 透明度(来自 CSS opacity) if (n.styles.opacity !== undefined && n.styles.opacity !== '' && parseFloat(n.styles.opacity) < 1) { - shapeOpts.transparency = Math.round((1 - parseFloat(n.styles.opacity)) * 100); + var opTrans = Math.round((1 - parseFloat(n.styles.opacity)) * 100); + shapeOpts.fill.transparency = Math.max(shapeOpts.fill.transparency || 0, opTrans); } // 圆角 @@ -883,13 +899,12 @@ if (require.main === module) { const st = { rect: 'rect', roundRect: 'roundRect', ellipse: 'ellipse' }[obj.shapeName] || 'rect'; const shapeOpts = { x: o.x, y: o.y, w: o.w, h: o.h, - fill: o.fill ? { color: o.fill.color } : undefined + fill: o.fill ? { color: o.fill.color, transparency: o.fill.transparency } : undefined }; if (o.line) shapeOpts.line = o.line; else shapeOpts.line = { type: 'none' }; // 去掉 pptxgenjs 默认边框 if (o.shadow) shapeOpts.shadow = o.shadow; if (o.rectRadius) shapeOpts.rectRadius = o.rectRadius; - if (o.transparency !== undefined) shapeOpts.transparency = o.transparency; slide.addShape(pres.ShapeType[st] || pres.ShapeType.rect, shapeOpts); } else if (obj.type === 'image') { slide.addImage({