☰
Two.js 快速上手:Renderer Agnostic 的二维绘图 API 使用与构建指南
2026/9/25 1:56:46 网站建设 项目流程
  • 图形学
  • 前端

【免费下载链接】two.js

A renderer agnostic two-dimensional drawing api for the web

项目地址:https://gitcode.com/gh_mirrors/tw/two.js
点击查看免费下载

导读

Two.js 是一套面向现代浏览器的二维绘图 API,其核心设计目标是renderer agnostic(渲染器无关)——开发者只需编写一套场景图(scenegraph)代码,即可让同一套 API 分别在 WebGL、Canvas 2D 与 SVG 三种上下文中渲染。本文以仓库根目录 README.md 为主线,结合 src/two.js 等源码实现,系统讲解 Two.js 的安装方式、基础场景搭建、动画循环、定制构建、ES6 模块导入、无头(服务端)渲染以及文档站构建方法。读完本文,你将能够:用几行代码在页面中渲染一个旋转的矩形;按需裁剪源码构建体积更小的 Two.js 发行包;在 React 等现代框架中以 ES6 import 方式接入;并在 Node.js 服务端借助 node-canvas 将场景渲染为 PNG 图片。

Two.js 是什么

Two.js(当前仓库版本为v0.8.24,见 package.json)是一个面向二维绘图的 JavaScript 库。它通过同一套 API 抽象出三种渲染后端,由 src/constants.js 中的Two.Types常量统一登记:

Types: { webgl: 'WebGLRenderer', svg: 'SVGRenderer', canvas: 'CanvasRenderer', }

构造实例时只需传入type参数选择渲染器,其余 API(如makeRectangle、makePath、bind('update'))完全一致,不依赖具体的渲染实现。三个渲染器分别位于 src/renderers/webgl.js、src/renderers/canvas.js 与 src/renderers/svg.js。

在 src/two.js 中,Two类是所有核心类(Path、Group、Vector、Text)、效果类(LinearGradient、RadialGradient、Sprite、ImageSequence)以及形状类(Rectangle、Circle、Polygon、Star等)的公共命名空间,同时Two.Utils聚合了read(SVG 解析)、xhr、getRatio、曲线与数学工具函数,详见 src/two.js#L59-L70。

快速开始:引入与第一个场景

通过<script>标签引入

下载构建好的压缩版two.min.js并放入 HTML 中:

<script src="js/two.min.js"></script>

通过 npm 安装

npm install --save two.js

安装后可以用require('two.js')(CommonJS)或 ES6 import 方式使用。此外,也可按下一节的方法自行构建所需版本。

绘制一个旋转的矩形

README 提供了一个完整的“旋转矩形”示例,也是理解 Two.js 工作方式的最小骨架:

<!doctype html> <html> <head> <meta charset="utf-8"> <script src="js/two.min.js"></script> </head> <body> <script> var two = new Two({ fullscreen: true, autostart: true }).appendTo(document.body); var rect = two.makeRectangle(two.width / 2, two.height / 2, 50 ,50); two.bind('update', function() { rect.rotation += 0.001; }); </script> </body> </html>

该示例演示了三个核心概念:

  1. 构造实例并挂载:new Two({ fullscreen, autostart })创建场景,appendTo(document.body)将渲染器的 DOM 元素(<svg>、<canvas>或 WebGL<canvas>)挂到页面上;
  2. 创建形状:makeRectangle(x, y, width, height)创建矩形并自动加入根场景(scene),从源码看该方法的实现是先new Rectangle(...)再this.scene.add(rect),见 src/two.js#L754-L759;
  3. 动画循环:autostart: true让实例自动进入requestAnimationFrame循环,随后每帧触发update事件,在事件回调中累加rect.rotation即可驱动旋转。

Two构造参数及其默认值定义在 src/two.js#L184-L191:

参数默认值说明
fullscreenfalse为true时画布自动适配document.body尺寸,并覆盖width/height
fittedfalse为true时画布自动适配父元素尺寸,同样覆盖width/height
width640画布初始宽度
height480画布初始高度
typeTwo.Types.svg渲染器类型,取webgl/canvas/svg之一
autostartfalse为true时自动调用play()进入动画循环
domElement无传入已有的 canvas/svg 元素直接绘制,会覆盖type推断

从源码看,fullscreen模式会同时修改document.body与渲染器 DOM 的样式(去掉 margin、固定定位)并绑定resize事件,见 src/two.js#L226-L249;fitted模式则监听父元素的尺寸变化,见 src/two.js#L1238-L1250。

动画循环与事件系统

autostart: true等价于手动调用two.play()。Two.js 内部维护一个全局requestAnimationFrame循环(src/two.js#L1260-L1276),每帧遍历Two.Instances中所有处于playing状态的实例并调用其update();而update()会依次触发update事件、同步画布尺寸并调用render(),最终触发render事件,见 src/two.js#L570-L608。

事件系统由Two.Events提供(src/events.js),bind/on/addEventListener注册监听,unbind/off/removeEventListener移除监听,trigger/dispatchEvent触发事件。内置事件类型包括play、pause、update、render、resize、change、remove、insert、order、load,见 src/events.js#L174-L185。

Custom Build:按需定制自己的发行包

Two.js 使用 Node.js 完成源码构建。README 中的定制构建流程如下:

cd ~/path-to-repo/two.js npm install

npm install会安装构建所需的一系列开发依赖(esbuild、eslint、typescript、vuepress 等,详见 package.json 的devDependencies)。

实际构建入口是 utils/build.js。它使用esbuild将 src/two.js 打包成三种产物:

产物路径格式用途
build/two.jsIIFE(globalName: 'Two')浏览器全局变量、CommonJS 兼容
build/two.module.jsESM(format: 'esm',target: 'es6')ES6 import
build/two.min.js压缩 IIFE生产环境最小化引入

构建时还会将版本号与发布日期注入Two.Version/Two.PublishDate常量,并把体积统计写入 utils/file-sizes.json。直接运行:

node ./utils/build

得到的就是更新后的build/two.js与build/two.min.js。README 提示的“自定义裁剪”思路是:如果只使用SVGRenderer,可以修改构建脚本、只保留所需的渲染器文件,从而显著缩小包体。需要注意,构建产物目录build/由构建流程生成,仓库当前只托管源码与 src 目录下的 ESM 模块。

在 ES6 环境中使用(v0.7.5+)

从v0.7.5+开始,Two.js 原生支持 ES6 import,可配合 React、Angular 等框架以及 webpack、esbuild、gulp 等打包工具使用。README 给出了一个 React + TypeScript 风格的最小示例:

import React, { useEffect, useRef } from "react"; import Two from "two.js"; export default function App() { var domElement = useRef(); useEffect(setup, []); function setup() { var two = new Two({ fullscreen: true, autostart: true }).appendTo(domElement.current); var rect = two.makeRectangle(two.width / 2, two.height / 2, 50, 50); two.bind("update", update); return unmount; function unmount() { two.unbind("update"); two.pause(); domElement.current.removeChild(two.renderer.domElement); } function update() { rect.rotation += 0.001; } } return <div ref={domElement} />; }

注意 React 组件卸载时依次做了三件清理工作:解绑update事件、two.pause()停止动画循环、移除渲染器 DOM 元素,避免内存泄漏。

按需导入特定模块

发布的 npm 包中包含了完整的模块源码,因此可以只导入自己需要的子模块并自行打包压缩:

import { Vector } from 'two.js/src/vector.js'; // 在 TypeScript 环境下省略 ".js" 后缀: import { Vector } from 'two.js/src/vector';

例如本仓库的 src/vector.js、src/path.js、src/group.js 都支持这种直接导入方式。需要说明的是,README 明确提示:主入口import Two from 'two.js'会导入全部模块,因此目前 Two.js 尚未实现完善的 tree shaking(该功能在路线图上)。如果追求极致包体,优先考虑按子模块导入或定制构建。

在无头环境(服务端)中渲染

从v0.7.x开始,Two.js 可以在无浏览器环境中运行,即在 Node.js 服务端借助Node Canvas(canvas包)渲染场景并输出图片。Two.js 没有把canvas放进自身依赖,因为它对浏览器运行并非必需,但源码中预留了全部对接钩子。

安装依赖

按 node-canvas 官方文档完成系统级安装后,在项目中安装两个 npm 包:

npm install canvas npm install two.js

服务端渲染并保存 PNG

README 给出了一个完整的服务端示例:创建 800×600 的 node-canvas 画布、用Two.Utils.polyfill补齐 Two.js 所需的 DOM 接口、构建场景、渲染后写出 PNG 文件。

var { createCanvas, Image } = require('canvas'); var Two = require('two.js') var fs = require('fs'); var path = require('path'); var width = 800; var height = 600; var canvas = createCanvas(width, height); Two.Utils.polyfill(canvas, Image); var time = Date.now(); var two = new Two({ width: width, height: height, domElement: canvas }); var rect = two.makeRectangle(width / 2, height / 2, 50, 50); rect.fill = 'rgb(255, 100, 100)'; rect.noStroke(); two.render(); var settings = { compressionLevel: 3, filters: canvas.PNG_FILTER_NONE }; fs.writeFileSync(path.resolve(__dirname, './images/rectangle.png'), canvas.toBuffer('image/png', settings)); console.log('Finished rendering. Time took: ', Date.now() - time); process.exit();

polyfill 做了什么

关键的Two.Utils.polyfill实现在 src/utils/canvas-polyfill.js。它通过shim方法为 node-canvas 的Canvas对象补充tagName、nodeName、nodeType以及getAttribute/setAttribute方法,让 Two.js 能把它当作<canvas>DOM 元素使用;同时把 node-canvas 的Image构造函数注入CanvasPolyfill.Image,供加载位图素材时使用,并设置isHeadless = true标记无头模式,见 src/utils/canvas-polyfill.js#L19-L47。

这也解释了示例中构造参数domElement: canvas的作用:直接指定一个已有的绘制目标元素,它覆盖type参数的推断逻辑(见 src/two.js#L204-L215)。由于无头环境下不存在document,fullscreen/fitted模式不可用,应显式传入width与height;渲染使用一次性的two.render()而非动画循环,即可输出静态帧。若要输出图片序列做批处理,可循环创建画布、更新场景属性后逐帧render()并toBuffer()。

构建文档站(Two.js 网站)

Two.js 官方网站在仓库内自带构建工具链,基于Vuepress生成,文档内容来自wiki目录下众多的README.md。构建文档的命令如下:

npm run docs:generate // Generate README.md files for documentation from source code comments npm run docs:dev // Creates a local server to generate all documentation npm run docs:build // Builds out static site and associated files to wiki/.vuepress/dist

对应脚本定义在 package.json:

  • docs:generate→node ./utils/document:用jsdoc-api扫描源码注释(见 utils/document.js),自动生成各模块的 README 文档;
  • docs:dev→vuepress dev wiki:启动本地开发服务器实时预览;
  • docs:build→vuepress build wiki:构建静态站点;
  • docs:publish→./deploy.sh:发布部署。

文档工具链对 Node 版本有要求:需要 Node 24 LTS。仓库根目录的 .nvmrc 指定了v24.20.0,在使用 nvm 的环境下先执行nvm use即可自动切换到正确版本;未使用 nvm 的读者可手动安装.nvmrc中列出的 Node 版本。

深入:从 README 到源码的进阶路线

如果想进一步掌握 Two.js,建议沿着下列仓库路径深入:

  • 核心入口与便利方法:src/two.js 定义了makeRectangle、makeCircle、makePath、makeCurve、makeText、makeLinearGradient、makeSprite、makeImageSequence等全套“make”工厂方法(src/two.js#L653-L1152),它们统一完成“创建对象 → 加入根场景”的动作;
  • SVG 导入与解析:two.interpret(svgNode)与two.load(svgPathOrText)可将 SVG 文档转换为 Two.js 场景对象,底层解析器为 src/utils/interpret-svg.js,支持path、polygon、polyline、circle、ellipse、rect、g、defs、use等 SVG 标签以及viewBox、transform、渐变填充的还原;
  • 渲染器实现:三种渲染器分别位于 src/renderers/svg.js、src/renderers/canvas.js、src/renderers/webgl.js。以 SVG 渲染器为例,路径顶点会被编译为d属性字符串(src/renderers/svg.js#L68-L206),渐变效果写入<defs>,这与svg类型的默认构造行为一一对应;
  • 测试用例:仓库 tests/suite 下包含canvas.js、svg.js、webgl.js、svg-interpreter.js等测试模块,可作为各渲染器与 SVG 解析行为的可运行参考。

版本与变更记录

Two.js 自 2012 年开始发展,完整变更记录存放在 wiki/changelog。从最早的基于 Three.js 的 alpha 版本到当前版本,README 建议查阅该目录跟踪每一次演进细节。当前仓库版本号可在 package.json 中确认(v0.8.24),构建后的运行时版本号通过Two.Version常量访问。

总结

本文围绕仓库 README.md 完整梳理了 Two.js 的五大使用场景:以<script>或 npm 快速引入并搭建旋转矩形动画;通过utils/build.js定制发行包;在 ES6 / 框架环境下按需导入子模块;在 Node.js 无头环境中借助 node-canvas 输出 PNG;以及基于 Vuepress 的文档站构建流程。与此同时,我们从 src/two.js、src/constants.js、src/renderers、src/utils/canvas-polyfill.js 等源码中印证了构造参数默认值、动画循环机制、事件系统、渲染器类型表与无头渲染钩子等实现细节。对于需要“一套代码、多端渲染”的二维图形项目,Two.js 的 renderer agnostic 设计提供了一个简洁而完整的切入点。

  • 图形学
  • 前端

【免费下载链接】two.js

A renderer agnostic two-dimensional drawing api for the web

项目地址:https://gitcode.com/gh_mirrors/tw/two.js
点击查看免费下载
上一篇:Mastra 工作流重试机制与错误处理实战:retries 怎么配、不生效怎么查
下一篇:毫秒级视频优化终极指南:Sunshine核心技术完整解析

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询