前言
Meta2d.js 是一个国产开源的 2D 可视化引擎,用来快速搭建 Web 组态、SCADA、监控大屏、流程图、中控可视化以及图形编辑与交互等应用 —— 接入实时数据,设置动画和条件,画面实时自动更新,还支持绘制、编辑、交互。Meta2d.js以「数据驱动显示」的理念服务了大量工业与物联网项目,1.0 的性能表现已经足够能打。而今历时一年自我革命,全新重构重写 —— 渲染管线、事件拾取、动画系统、数据通信,每一层都推倒重来,只为让性能更上一层楼、让多人协作从无到有。
一、Meta2d.js是什么
Meta2d.js 是一个开源的2D 可视化引擎,核心是「数据驱动显示 + 动态交互」:
- 数据变化,驱动画面实时变化
- 条件、交互、消息、事件的即时响应
典型使用场景
- 工业组态 / SCADA:电力、水务、能源、工厂产线监控,设备点位、管线、告警联动;
- 监控大屏 / 中控可视化:智慧楼宇、机房动环、交通调度,动图与实时数据同屏;
- 流程图 / 架构图编辑器:拓扑图、ER 图、组织架构,自带编辑交互开箱即用;
- 报表 / 数据可视化:实时数据驱动的大屏报表;
- 可视化产品底座:MIT 协议,基于它二次开发自己的设计器 / 编辑器。
二、AI 时代的可视化底座
Meta2d.js 2.0 不内置 AI 模型,却天然对 AI 友好:
- 数据驱动,输出即渲染 引擎的核心是「数据 + 算法 + 风格 = 栩栩如生」,本质上就是一份结构化 JSON。AI生成可视化数据后,引擎即刻显示 —— 实现「AI 生成 → 可视化」即时呈现。
- 支持生成式、渐进式体验 可以很方便的支持 AI 生成式、渐进式的数据可视化展示。
- 性能扎实,支持海量图元 AI 一次性生成10万、100万+节点都能即时显示、流畅运行。
- 人机同屏协作,改动可追溯 多人协作不止于人 —— AI Agent 也可以作为协作者实时增删改画布。差量 patch 让每一次 AI 改动都可同步、可回放、可追溯;五通道实时数据管道 + 数据点绑定,让 AI 推理结果、设备数据直接驱动画面联动。
一句话:AI 负责 "生成",Meta2d 负责 "渲染、交互、协作" —— 这就是 AI 时代可视化底座该有的样子。
三、性能强劲,百万图元依旧实时联动
性能基准测试: 基于官方压力与性能基准测试(examples/benchmark)
测试环境: 8核 3.8GHz CPU,32GB 内存
注:200 图片、2000 数据点、400 动画 都一样,没有再额外设置
10万图元,缩放网页以便容纳所有图元,画布不缩放
10万图元,不缩放网页,缩放画布
100万图元,不缩放网页,缩放画布
性能优化小过程:原计划2026年9月25号中秋节前发版2.0。我们测试大概10万图元是流畅的,真实生产案例中足以满足的。但是我们开发是基于“架构 -> 设计实现”的模式编写,性能优化原计划在发布后。恰逢 claude 5.5 和 gpt 6 发布,我们决定抱着尝试的态度让AI帮我们做深度性能优化,此前都是我们工程师凭着过去5年累积的经验去设计新的架构,有点担心AI“改乱”我们的代码。我们惊喜的是AI的评估和我们大致一致,并且优化改动的代码我们可接受。于是我们决定让AI帮我们做深度性能优化后发布,因为又需要大量的审核和测试,导致发布的延后,但优化后的性能确实超出我们预期。
AI分析:
meta2d 每个动画图元各自算脏区 → 各自 postMessage → 渲染 worker 各自 clip+clear+重绘;hover worker 还各自全屏清空重绘 N(动画图元数)× 2
meta2d 的单个原语实现(脏矩形、空间网格、Worker 分线程、样式 diff)都是对的,但帧内没有聚合层,所以复杂度是 O(动画图元数) 次独立重绘管线,而不是 O(1) 次。2 万图元时哪怕只有 200 个在动,也是每帧 400 次消息 + 400 次 clip/clear/draw + 400 次全屏 overlay 重绘。
四、与 Konva.js、Fabric.js、PixiJS 等绘图库的不同
都是优秀的 Canvas 技术栈,但定位完全不同:Konva / Fabric / Pixi 是 "画布基础能力" 提供者,Meta2d 是 "业务开箱即用" 的可视化引擎。
怎么选型:
- 想要高性能渲染 → Meta2d.js / PixiJS;
- 想要通用绘图交互 → Meta2d.js / Konva / Fabric;
- 想要工业可视化业务开箱即用(组态、SCADA、大屏、流程图 + 实时数据 + 协作)→ Meta2d.js。
一句话:不用自己接 MQTT/WebSocket、不用自己写拾取和局部渲染优化、不用自己搭编辑器交互、不用自己实现多人协作 —— 选 Meta2d.js 2.0
五、Meta2d.js 2.0 关键设计
5.1 多线程架构
2.0 把整个引擎拆成 1 个主线程 + 4 个 Web Worker(packages/core/src/workers/):
- 渲染线程 持有OffscreenCanvas,绘制指令不再经过主线程。拖拽、缩放、动画播放时主线程保持「零占用」;
- 计算线程 负责拾取、视口裁剪、包围盒与脏区计算 —— 这些是编辑场景里每帧都会发生的重活;
- 交互线程 负责图元动态交互下的状态管理和交互响应;
- 工具线程 承载所有协议连接(MQTT/WebSocket/HTTP/SSE/SQL)和图片 / GIF 解析,握手、心跳、断线重连不影响界面;
5.2 局部重绘
1.x 采用整幅画布 clear + 全量重绘,逻辑简单稳定;2.0 在此基础上进一步升级为按包围盒的局部重绘。2.0 为每个图元维护包围盒(boundary) ,并预先计算其影响范围内的所有图元(penBoundarys),渲染线程只对脏区域执行 clearRect + clip:
// workers/render/worker.ts(关键逻辑)
if (boundary && boundary.width > 0 && pens === patchPens) {
// 计算屏幕像素对齐的脏区
ctx.clearRect(x, y, width, height);
// 设置局部重绘区域
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.clip();
}
几个典型的增量场景:
- 拖拽移动:先擦除并重绘「老位置」区域,再绘制「新位置」区域,两处脏区之外分毫不动:
// 1. 先擦除并重绘老位置区域
if (e.data.oldBoundary) {
boundary = e.data.oldBoundary;
renderPens(ctx, patchPens, true);
}
// 2. 重绘新位置区域
boundary = e.data.newBoundary;
renderPens(ctx, patchPens, true);
2. 悬停 / 选中:记录上一帧绘制过的图元集合(lastHoverPens / lastInActivePens),状态切换时只清除并重绘这些图元;
- 动画刷新:每一帧动画只重绘动画图元所在包围盒内的图元;
- 文字溢出感知:文字溢出 pen 范围时,textBox 会同步进拾取范围(textOutsides 回传 calc 线程),保证重绘完整覆盖。
5.3 空间网格拾取:从「全部遍历」到「只查一格」
拾取(pick)是编辑器的命门。1.x 采用线性遍历拾取,在万级图元下仍有明显优化空间;2.0 引入自适应空间网格索引(workers/calc/pick.ts),把拾取成本进一步大幅压低:
// 图元少于 2000 个时,整幅画布一个格
if (penMap.size < 2000) {
cols = 1; rows = 1;
cellSize = Math.max(width, height);
} else {
// 动态计算网格行列数
const size = Math.ceil(penMap.size / 1000);
...
}
拾取时先根据鼠标坐标定位到所在 cell,只遍历该格内的候选图元(grid[cell]),候选集合从「全部 N 个」降到「本格 ≤1000 个」。配合几个细节优化:
- 连线外扩 5px:expandRect(pen, 5),避免细线难命中;
- 曲线采样点缓存:linePoints Map 缓存贝塞尔曲线分段采样点,拾取曲线时不用每帧重算;
- 旋转坐标反变换:pick 时把鼠标坐标变换到图元本地坐标系,旋转图元也能精确命中;
- 文字溢出区域参与命中:textBoxs 纳入网格检测,点文字溢出部分也能选中。
5.4 原生解析 GIF / APNG,实现动图自由
工业大屏里 GIF 动图的播放一直受制于浏览器 的能力:无法控制帧率与暂停,频繁解码还会阻塞主线程。2.0 在工具线程里做了帧级原生解析:
- 支持 GIF 与 APNG 两种动图格式,统一输出 { imageBitmap, duration } 帧序列;
- 渲染线程内置 GIF 播放器(gifPlayers),按每帧 duration 推进帧索引,配合局部重绘只刷新动图所在区域:
- 解析结果分批回传(每 50ms 或全部完成时批量 postMessage),ImageBitmap 直接转移所有权,不复制内存。
5.5 动画引擎优化
2.0 的动画播放器(workers/calc/animate.ts)整体搬进 calc 线程:关键帧插值在 Worker 内完成,每帧只把变化属性(changedProperties)发给渲染线程做局部重绘。1000+ 动画同屏播放时,主线程与渲染线程既不干扰,性能也大大幅度提升。
5.6 在线多人协作
这是社区期待已久的能力,也是 2.0 全新设计的patch特性考虑特性之一。设计要点:
- 差量同步:与引擎补丁机制完全同的构协作消息结构,天然支持增量与协作渲染 —— 远端收到 patch 只做一次对应的局部重绘;
- 历史回放:新成员进入房间,服务端回放历史差量,即完成协作统一;
- 房间机制:通过 accessToken 作为房间号,同一房间共享同一份协作数据;
- 可编程事件:协作数据通过 collaborate 事件对外广播,业务层可自行处理光标、通知、权限等扩展;
六、(几行代码)快速上手
npm install @meta2d/core @meta2d/<extension> --save
<le5le-meta2d />
import { createMeta2d, Mode } from '@meta2d/core';
createMeta2d();
const meta2d = document.querySelector('le5le-meta2d');
// 加载数据
fetch('data.json').then((res) => res.json()).then((data) => meta2d.open(data));
// 设置编辑模式。默认为运行模式
meta2d.setMode(Mode.Edit);
结语
本着给用户带来更友好的体验,Meta2d.js 2.0 不惜全新重构,把「渲染、拾取、通信」重写架构设计,用空间索引 + 局部重绘把每一帧的无效计算压到最低,再用差量 patch 打通多人协作。对于组态、SCADA、大屏这类「图元多、数据实时、要交互编辑」的场景,带来更好体验和能力跃迁。
资源链接:
- GitHub:github.com/le5le-com/m…
- 在线体验:v.le5le.com
- 相关文档:doc.le5le.com
本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。
Foreword
Meta2d.js is an open-source 2D visual engine for fast-track construction of web-formats, SCADA, monitoring screens, flowcharts, medium-controlled visualization, and graphic editing and interaction applications - access to real-time data, animation and conditions, real-time automatic updates of images, and support for drawing, editing and interaction. Meta2d.js serves a large number of industrial and material networking projects with a "data-driven display" concept, and the performance of 1.0 is already adequate. And one year of self-revolution, a whole new rewriting -- the rendering of pipes, event pick-up, animation systems, data communication -- each level is pushed back, just to make the performance go one step further and multiple people work together.
I. What's Meta2d.js?
Meta2d.js is an open source 2D visualizing engine with the core "DataDrive + Dynamic Interaction":
- Data change, drive change in real time
- Conditions, interactions, news, events. Response
Typical use of scenes
- Industrial grouping / SCADA: electricity, water, energy, plant line monitoring, equipment points, pipelines, alarms;
- Monitoring of large / medium-controlled visualization: smart buildings, engine rings, traffic movements, motion maps and real-time data;
- Flowchart / Schema Editor: Topographic, ER Chart, Organizational Structure, to be used in the interactive box with the editor;
- Report / Data Visualization: a large screen statement driven by real-time data;
- Visualized product base: MIT protocol based on its secondary development of its designer/ editor.
II. AI Age Visualized Grounds
Meta2d.js 2.0 does not have an AI model, but is natural to AI:
- Data driven, output is retrofitting, and the core of the engine is "Data + Algorithm + Style = Lifelike", which is essentially a structured JSON. After AI generates visual data, the engine is displayed immediately - to make "AI generation visualization" instantaneous.
- Supporting generation, incremental experience can easily support AI generation, progressive visualization of data.
- The performance is solid, and supports the mass chart AI, which produces 100,000, 1 million plus nodes at a single time.
- The human machine works with the screen and changes can be traced back to more than one person - AI Agent can add and delete the canvas in real time as a collaborator. The difference Patch allows each AI change to be synchronized, removable, traceable; five-channel real-time data conduit + data points bound, allowing AI reasoning results, device data to drive direct image connection.
One sentence: AI is responsible for generation, Meta2d is responsible for rendering, interacting, collaborating -- this is what the AI era looks like.
III. Strong performance, and millions of graphs still moving in real time
Performance benchmark test: based on official pressure and performance baseline test (examples/benchmark)
Test Environment: 8 core 3.8 GHz CPU, 32GB RAM
Note: 200 images, 2000 data points, 400 animations are all the same, no additional settings
100,000 graphs, zoom in on the web page to accommodate all graphs. Fire!
100,000 graphs, no web pages, canvas
$1 million, no web page, canvas.
Performance optimization small process: version 2.0 planned for mid-Autumn on 25 September 2026. We've tested around 100,000 graphs to be fluid and sufficient in real production cases. But we're developing a model based on architecture-design realization, which optimizes performance after publish. At the time of claude 5.5 and gpt 6 publish, we decided to try and get AI to help us do deep performance optimization, which was preceded by our engineers designing a new architecture based on experience over the past five years, with a little concern about AI changing our code. We're surprised that AI's assessment and we're broadly consistent and that we can optimize the code of change. So we decided to get AI to help us do publish after we optimized the depth performance, because it required a lot of clearance and testing, which led to the delay of publish, but the optimization did exceed our expectations.
AI analysis:
Each animated object calculates the dirty area each postmessage and replay the worker each clip+clar+ repainting; cover worker also clears the entire repainting N (animation) x 2
The individual original language of meta2d (dirty rectangle, spatial grid, Worker branch, style diff) is correct, but there is no polymer layer in the frame, so the complexity is O (animated number of characters) to reset the tube line several times, not O (1). If only 200 graphs were moving, it was 400 messages per frame + 400 crip/clar/draw + 400 full-screen overlay redraws.
IV. Distincts from drawing libraries such as Konva.js, Fabric.js, PixiJS
They're excellent Canvas technology stores, but their location is completely different: Konva / Fabric / Pixi is a "matrix basics" provider, Meta2d is a "business open and use" visual engine.
How?
- Want high-performance rendering
- Want to interact with general drawings → Meta2d.js / Konva / Fabric;
- To open the industrial visualization business using Meta2d.js (organization, SCADA, screen, flowchart + real time data + collaboration).
One sentence: do not pick up MQTT/WebSocket, do not write pick-up and local rendering, do not interact with the editor and do not work with multiple people - choose Meta2d.js 2.0
V. Meta2d.js 2.0 Key Design
5.1 Multi-range architecture
2.0 Split the entire engine into 1 main route + 4 Webworker (packages/core/src/workers/):
- Rendering thread holds Offscreen Canvas, drawing instructions no longer through the main thread. The main line is "zero occupancy" when dragging, scaling and animations are played.
- Calculating the threads, collecting, visual cutting, encircling boxes and dirty areas -- these are the heavy work that happens at every frame of the editing scene;
- Interactive threads. Responsible for state management and interactive response under the dynamic graph;
- Tool threads Carry all protocol connections (MQTT/WebSocket/HTTP/SSE/SQL) and photo/GIF resolution without affecting interfaces by handshakes, heartbeats, breakwires;
5.2 Local redrawing
1.x Using a whole canvas full-scale redraw, logic is simple and stable; 2.0 on this basis is further upgraded to a partial redraw by the encirclement box. 2.0 Maintenance of the box (bundary) for each graph and precalculation of all graphs (penBundarys) within its sphere of influence. ClearRect + crip:
// Workers/render/worker.ts (key logic)
if (boundary && boundary.width > 0 && pens === patchPens) {
// Calculating the dirty areas of the screen pixels
ctx.clearRect(x, y, width, height);
/ / Set a local redraw area
ctx.beginPath();
ctx.rect(x, y, width, height);
ctx.clip();
}
Some typical incremental scenarios:
- Drag-and-move: First remove and redraw the "old position" area, then draw the "new position" area, with no movement outside the two dirty areas:
// 1. Erase and redraw the old position area first
if (e.data.oldBoundary) {
boundary = e.data.oldBoundary;
renderPens(ctx, patchPens, true);
}
/ 2. Redraw new location areas
boundary = e.data.newBoundary;
renderPens(ctx, patchPens, true);
Suspend / Selection: Record the collection of drawings (lastHoverPens / lastInactivePens) drawn in the previous frame, and only remove and redraw those drawings when the state switch;
- Animated painting: each frame only redraws the drawings in the box in which the animation is located;
- Spill text: when text spills out of the pen range, textBox synchronizes with the pick-up range (textOutsides returns the calc thread) to ensure that it is repainted.
5.3 Space grid pick-up: from "all through" to "just one".
Picking is the editor's dead end. 1.x Adopt linear round-takes and there is still a marked optimization of space under all-scale diagrams; 2.0 Introduce self-adapted spatial grid index (workers/calc/pick.ts) to further reduce the pick-up costs:
// When the figure is less than 2000, the entire canvas is in one cell
if (penMap.size < 2000) {
cols = 1; rows = 1;
cellSize = Math.max(width, height);
} else {
/ / Dynamic calculation grid rows
const size = Math.ceil(penMap.size / 1000);
...
}
At the time of the pick-up, you can position the cell according to the mouse coordinates. You can only run through the gred [cell] in the cell. The pool of candidates has been reduced from "all Ns" to "Bengue Z10000". Optimizing several details:
- 5px:expandRect (pen, 5) to avoid the loss of a line;
- Curve sampling point cache: linePoints Map cache Bézier curve sampling point, not to be recalculated per frame for pick-up curves;
- Rotation coordinates inverted: the mouse coordinates are converted to the local coordinate system of the graphs, which can also be precisely hit;
- The text spill area is involved in the hit: textBoxs is included in the grid test and the text spill is also selected.
5.4 Natural resolution GIF / APNG, free of animation
The display of GIF animations on industrial screens has been subject to browsers' ability to control frame rates and pauses, and frequent decodes can block the main route. 2.0 The frame primary resolution was made in the tool thread:
- Supports the GIF and APNG animation formats and harmonizes output {imageBitmap, duration} frame sequences;
- Rendering thread internal GIF Players (gifPlayers), indexing the frame by each frame, with local redrawing only the area in which the new action map is being painted:
- Parsing results by batch (postMesseage per 50 ms or all completed), ImageBitmap directly transfers ownership and does not copy memory.
5.5 Optimization of animation engines
Animated players (workers/calc/animate.ts) for 2.0 move to the calc circuit in its entirety: key frame plugs are completed in the worker, and change properties are only sent to the retrofitting circuit. When 1,000+ animations are shown on the same screen, the main thread and the rendering thread are not interfered with, and performance is significantly increased.
5.6 Online multi-person collaboration
This is the long-awaited capability of the community, and it's one of the features of a brand-new patch design. Design elements:
- Gap Synchronization: a collaborative message structure fully aligned with the engine patch, natural support increments and collaborative renderings - a remote feed received only once for local redrawing;
- History replay: new members enter the room and the service end reverses the historical deviation, i.e., the harmonization of collaboration;
- Room mechanism: sharing of the same collaborating data in the same room through access Token as the room number;
- Programmable events: collaborating data are broadcast externally through the collaborate event, and the operational level can handle the extension of the cursor, notification, permission, etc.;
VI. Quick start
npm install @meta2d/core @meta2d/<extension> --save
<le5le-meta2d />
import { createMeta2d, Mode } from '@meta2d/core';
createMeta2d();
const meta2d = document.querySelector('le5le-meta2d');
// Loading data
fetch('data.json').then((res) => res.json()).then((data) => meta2d.open(data));
/ Set edit mode. Default as run mode
meta2d.setMode(Mode.Edit);
Concluding remarks
With a more user-friendly experience, Meta2d.js 2.0 recasts the "reduce, pick and communicate" architecture, puts the ineffectual calculation of each frame to a minimum with spatial index + local redrawing, and uses a differential patch to connect multiple people. This has brought about a better experience and a shift in capacity for events like grouping, SCADA, screens, "Mixed, data in real time, interactive editing".
Resource links:
- GitHub:github.com/le5le-com/m…
- Online experience: v.le5le.com
- Relevant documents: doc.le5le.com
Auto-fetched and translated by AI Atlas. All rights belong to the original author.