目录摘要1. 引言 - 为什么需要 Canvas1.1 Canvas 的价值1.2 Canvas 架构1.3 Canvas 能力概览2. Canvas 基础操作2.1 展示界面 (present)2.2 导航页面 (navigate)2.3 执行脚本 (eval)2.4 截图 (snapshot)3. 展示 HTML 内容3.1 基本用法3.2 带样式的界面3.3 响应式设计4. 展示外部网页4.1 基本用法4.2 设置尺寸4.3 嵌入文档5. 实战案例一数据仪表盘5.1 场景描述5.2 实现代码6. 实战案例二交互式表单6.1 场景描述6.2 实现代码7. 实战案例三报告展示7.1 场景描述7.2 实现代码8. 高级功能8.1 执行 JavaScript8.2 获取截图8.3 A2UI 交互9. 最佳实践9.1 设计原则9.2 常见问题10. 总结10.1 核心要点10.2 下一步参考资料摘要本文介绍 OpenClaw 框架中的 Canvas 可视化界面功能。从 Canvas 基本概念、核心操作、界面展示到实际应用全面解析如何通过 AI Agent 创建和管理可视化界面。通过实际案例演示网页嵌入、自定义界面、交互式应用等场景帮助开发者构建具有可视化能力的智能应用。1. 引言 - 为什么需要 Canvas1.1 Canvas 的价值场景说明示例可视化展示展示图表、报告数据仪表盘交互界面提供用户交互配置面板网页嵌入嵌入外部网页文档、工具实时预览实时展示结果代码预览1.2 Canvas 架构OpenClaw CanvasAI AgentCanvas Tool操作类型present - 展示界面navigate - 导航URLeval - 执行JSsnapshot - 截图渲染界面获取截图1.3 Canvas 能力概览能力说明Action展示界面展示 HTML/URLpresent导航页面加载指定 URLnavigate执行脚本运行 JavaScripteval截图捕获界面图像snapshotA2UI交互式界面a2ui_push2. Canvas 基础操作2.1 展示界面 (present)canvas(actionpresent,urlhttps://example.com# 或使用 html 参数)2.2 导航页面 (navigate)canvas(actionnavigate,urlhttps://example.com)2.3 执行脚本 (eval)canvas(actioneval,javaScriptdocument.title)2.4 截图 (snapshot)canvas(actionsnapshot,outputFormatpng# 或 jpg)3. 展示 HTML 内容3.1 基本用法canvas(actionpresent,html !DOCTYPE html html head titleHello Canvas/title /head body h1Hello, OpenClaw Canvas!/h1 p这是一个简单的 HTML 页面/p /body /html )3.2 带样式的界面canvas(actionpresent,html !DOCTYPE html html head style body { font-family: Arial, sans-serif; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; } .card { background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px; backdrop-filter: blur(10px); } h1 { margin: 0; } /style /head body div classcard h1 数据仪表盘/h1 p实时数据展示/p /div /body /html )3.3 响应式设计canvas(actionpresent,html !DOCTYPE html html head meta nameviewport contentwidthdevice-width, initial-scale1.0 style .container { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; padding: 20px; } .item { background: #f5f5f5; padding: 20px; border-radius: 8px; text-align: center; } /style /head body div classcontainer div classitem项目 1/div div classitem项目 2/div div classitem项目 3/div div classitem项目 4/div /div /body /html )4. 展示外部网页4.1 基本用法canvas(actionpresent,urlhttps://docs.openclaw.ai)4.2 设置尺寸canvas(actionpresent,urlhttps://example.com,width800,height600)4.3 嵌入文档defshow_documentation():展示 OpenClaw 文档canvas(actionpresent,urlhttps://docs.openclaw.ai,width1000,height700)5. 实战案例一数据仪表盘5.1 场景描述创建一个实时数据展示仪表盘。5.2 实现代码defshow_dashboard(data):展示数据仪表盘htmlf !DOCTYPE html html head title数据仪表盘/title script srchttps://cdn.jsdelivr.net/npm/chart.js/script style body {{ font-family: Segoe UI, Arial, sans-serif; background: #1a1a2e; color: white; padding: 20px; margin: 0; }} .header {{ text-align: center; margin-bottom: 30px; }} .stats {{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-bottom: 30px; }} .stat-card {{ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; text-align: center; }} .stat-value {{ font-size: 2em; font-weight: bold; }} .stat-label {{ opacity: 0.8; }} .chart-container {{ background: #16213e; padding: 20px; border-radius: 10px; }} /style /head body div classheader h1 实时数据仪表盘/h1 p数据更新时间:{datetime.now().strftime(%Y-%m-%d %H:%M:%S)}/p /div div classstats div classstat-card div classstat-value{data[total_users]}/div div classstat-label总用户数/div /div div classstat-card div classstat-value{data[active_users]}/div div classstat-label活跃用户/div /div div classstat-card div classstat-value{data[requests]}/div div classstat-label请求数/div /div div classstat-card div classstat-value{data[success_rate]}%/div div classstat-label成功率/div /div /div div classchart-container canvas idchart/canvas /div script const ctx document.getElementById(chart).getContext(2d); new Chart(ctx, {{ type: line, data: {{ labels:{data[labels]}, datasets: [{{ label: 请求数, data:{data[values]}, borderColor: #667eea, backgroundColor: rgba(102, 126, 234, 0.1), fill: true }}] }}, options: {{ responsive: true, plugins: {{ legend: {{ labels: {{ color: white }} }} }}, scales: {{ y: {{ ticks: {{ color: white }}, grid: {{ color: rgba(255,255,255,0.1) }} }}, x: {{ ticks: {{ color: white }}, grid: {{ color: rgba(255,255,255,0.1) }} }} }} }} }}); /script /body /html canvas(actionpresent,htmlhtml)6. 实战案例二交互式表单6.1 场景描述创建一个可交互的配置表单。6.2 实现代码defshow_config_form():展示配置表单html !DOCTYPE html html head title配置面板/title style body { font-family: Arial, sans-serif; background: #f5f5f5; padding: 20px; } .form-container { max-width: 500px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } h2 { margin-top: 0; color: #333; } .form-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; font-weight: bold; color: #555; } input, select { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; box-sizing: border-box; } .btn { background: #667eea; color: white; border: none; padding: 12px 24px; border-radius: 5px; cursor: pointer; font-size: 16px; } .btn:hover { background: #5a6fd6; } /style /head body div classform-container h2⚙️ 配置面板/h2 div classform-group label模型选择/label select idmodel option valuegpt-4GPT-4/option option valuegpt-3.5-turboGPT-3.5 Turbo/option option valueclaude-3Claude 3/option /select /div div classform-group label温度参数/label input typenumber idtemperature value0.7 min0 max2 step0.1 /div div classform-group label最大Token数/label input typenumber idmax_tokens value2000 min100 max8000 /div button classbtn onclicksubmitConfig()保存配置/button /div script function submitConfig() { const config { model: document.getElementById(model).value, temperature: parseFloat(document.getElementById(temperature).value), max_tokens: parseInt(document.getElementById(max_tokens).value) }; console.log(配置已保存:, config); alert(配置已保存!); } /script /body /html canvas(actionpresent,htmlhtml)7. 实战案例三报告展示7.1 场景描述展示格式化的报告内容。7.2 实现代码defshow_report(title,content,stats):展示报告htmlf !DOCTYPE html html head title{title}/title style body {{ font-family: Georgia, serif; max-width: 800px; margin: 0 auto; padding: 40px; background: #fafafa; }} .report {{ background: white; padding: 40px; border-radius: 10px; box-shadow: 0 2px 20px rgba(0,0,0,0.1); }} h1 {{ color: #333; border-bottom: 3px solid #667eea; padding-bottom: 10px; }} .meta {{ color: #888; font-size: 0.9em; margin-bottom: 30px; }} .content {{ line-height: 1.8; color: #444; }} .stats-box {{ background: #f8f9fa; padding: 20px; border-radius: 8px; margin: 20px 0; }} .stats-box h3 {{ margin-top: 0; color: #667eea; }} .stat-item {{ display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #eee; }} /style /head body div classreport h1{title}/h1 div classmeta 生成时间:{datetime.now().strftime(%Y-%m-%d %H:%M:%S)}/div div classcontent{content}/div div classstats-box h3 统计数据/h3 div classstat-item span总字数/span span{stats[words]}/span /div div classstat-item span段落数/span span{stats[paragraphs]}/span /div div classstat-item span预计阅读时间/span span{stats[read_time]}分钟/span /div /div /div /body /html canvas(actionpresent,htmlhtml)8. 高级功能8.1 执行 JavaScriptdefupdate_canvas_data(data):更新 Canvas 中的数据canvas(actioneval,javaScriptf document.getElementById(data-display).textContent {data}; )8.2 获取截图defcapture_canvas():截取 Canvas 内容screenshotcanvas(actionsnapshot,outputFormatpng)returnscreenshot8.3 A2UI 交互defpush_interactive_ui():推送交互式界面canvas(actiona2ui_push,jsonl {type: text, content: Hello} {type: button, label: Click me, action: click} )9. 最佳实践9.1 设计原则原则说明简洁清晰界面简洁信息清晰响应式适配不同尺寸性能优化避免过多资源用户体验良好的交互反馈9.2 常见问题问题解决方案加载慢减少外部资源样式错乱使用内联样式交互失效检查JS代码截图空白等待加载完成10. 总结10.1 核心要点要点说明HTML展示使用 present html 参数URL展示使用 present url 参数脚本执行使用 eval 执行 JS截图获取使用 snapshot 获取图像10.2 下一步第52篇OpenClaw Canvas 导航URL 加载与控制第53篇OpenClaw Canvas 执行JavaScript 注入实战参考资料OpenClaw 官方文档HTML/CSS 基础Chart.js 文档