You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pywebview+Paper.js绘制Path不显示,如何解决?

解决PyWebView中Paper.js Path无法渲染的问题

出现这个问题的核心原因有两个:

  1. 设置HTML后立即执行JS代码时,Paper.js脚本可能还未加载完成,导致Paper.js的API无法正常调用
  2. 绘制完成后立即获取Canvas数据,此时Paper.js的渲染操作可能还未完成,Canvas仍为空白

以下是修复后的代码:

import io
from PIL import Image
import base64
import webview


def extract_image(width, height, path=[(100, 100)]):
    color = 'red'

    def callback(window):
        # 编写完整的HTML页面,将JS代码放在DOM加载完成的回调中
        window.html = f"""
        <script type="text/javascript" src="js/paper.js"></script>
        <canvas id="myCanvas" width="{width}" height="{height}"></canvas>
        <script>
            window.onload = function() {{
                var canvas = document.getElementById("myCanvas");
                paper.setup(canvas);
                var start = new paper.Point({path[0][0]}, {path[0][1]});
                var end = new paper.Point({path[0][0] + 1}, {path[0][1]});
                var path = new paper.Path({{
                    segments: [start, end],
                    strokeColor: '{color}',
                    strokeCap: 'round',
                    strokeJoin: 'round',
                    strokeWidth: 10
                }});
                path.add(new paper.Point(200, 200));
                paper.view.draw();
                // 标记绘制完成
                window.drawComplete = true;
            }}
        </script>
        """
        
        # 等待绘制完成
        def wait_for_draw():
            if window.evaluate_js("window.drawComplete === true"):
                # 获取Canvas数据
                data_url = window.evaluate_js("canvas.toDataURL()")
                base64_data = data_url.split(",")[1]
                image_data = io.BytesIO(base64.b64decode(base64_data))
                image = Image.open(image_data)
                image.show()
                window.destroy()
            else:
                # 延迟100ms再次检查
                webview.timer(100, wait_for_draw)
        
        # 启动等待检查
        wait_for_draw()
        
    return callback


def extract_canvas_to_image():
    return webview.create_window('Hello world', frameless=True, hidden=True)


if __name__ == '__main__':
    window = extract_canvas_to_image()
    webview.start(extract_image(400, 400), window)

关键修改说明:

  • 将绘制逻辑放在window.onload事件中,确保Paper.js脚本和Canvas元素都已加载完成后再执行绘制
  • 通过window.drawComplete标记绘制状态,使用定时器等待绘制完成后再获取Canvas数据,避免渲染未完成就截图
  • 移除了原代码中直接同步执行JS的逻辑,改为在HTML中内嵌脚本,保证执行时机正确

额外注意事项:

  • 确认js/paper.js文件路径正确,保证PyWebView能加载到该脚本
  • 若使用新版本PyWebView,也可通过window.loaded事件触发后续操作,进一步保证窗口初始化完成

内容的提问来源于stack exchange,提问作者Avi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:53:15