Two.js Registry 注册表深入解析:图像缓存、SVG defs 与 WebGL 纹理的底层字典实现
图形学前端【免费下载链接】two.jsA renderer agnostic two-dimensional drawing api for the web项目地址https://gitcode.com/gh_mirrors/tw/two.js点击查看免费下载Two.Registry 是 Two.js 中一个轻量级的通用目录管理类以字符串id为键维护一张键值映射表。它在 Two.js 内部主要承担纹理Texture缓存、SVGdefs解析缓存与 WebGL 纹理注册等关键职责。读完本文你将掌握Registry的完整 API、链式调用风格以及它在图像去重、SVG 资源复用与 GPU 纹理管理中的具体工作方式。一、什么是 Two.Registry从 源码定义 可以确认Two.Registry是一个极简的通用注册表容器官方描述为An arbitrary class to manage a directory of things. Mainly used for keeping tabs of textures in Two.js.即用于管理一组对象目录的任意类主要用于追踪 Two.js 中的纹理。它在内部用一个普通对象map存储数据通过唯一的字符串id完成增、删、查等操作。由于其目录语义与集合类Collection不同——Registry 更接近一个按需可寻址的字典dictionary而不是一个可迭代渲染的对象列表。从代码结构来看整个类非常精简只包含一个属性与四个方法属性map内部存储对象初始为空对象{}方法add、remove、get、contains。值得注意的是Registry本身与渲染无关、与图形绘制无关它不依赖 DOM、不依赖渲染器因此可以在 Node.js 无头headless环境下正常使用。二、如何获取 Two.Registry在 src/two.js 的类导出区域中Registry被挂载为Two的静态属性static Registry Registry; // src/two.js#L334因此在你引入 Two.js 后可以直接通过Two.Registry访问import Two from two.js; const registry new Two.Registry();同时Registry也作为独立模块存在于仓库中可以从 src/registry.js 直接导入其类型声明见 src/registry.d.tsdeclare module two.js/src/registry { export class Registry { map: {}; add(id: string, obj: any): Registry; remove(id: string): Registry; get(id: string): any | null; contains(id: string): boolean; } }从类型签名可以看出add与remove都会返回Registry自身这是刻意设计的**链式调用method chaining**接口。三、API 详解3.1 add(id, obj)注册任意值add(id, obj) { this.map[id] obj; return this; }参数类型说明idString唯一标识符objAny要注册进目录的任意类型变量add将任意类型的值写入目录并以id为键进行索引。赋值完成后返回this便于链式调用多个注册操作registry .add(logo, imageElement) .add(cursor, cursorElement);两点使用注意id是字符串键。如果传入非字符串例如数字JavaScript 会将其隐式转为字符串后存入map使用相同的id重复add会覆盖旧值不会报错也不会合并。因此若要保证不覆盖建议先调用contains判断。3.2 remove(id)按 id 移除remove(id) { delete this.map[id]; return this; }参数类型说明idString唯一标识符remove通过delete操作符从map中彻底删除该键。删除不存在的键也不会报错且同样返回this以支持链式调用。需要注意的是delete与将值置为undefined并不等价——前者会移除键本身因此后续调用contains会返回false而后者键仍然存在contains依然会返回true。这正是内部使用id in this.map而非this.map[id] ! undefined判断存在性的原因。3.3 get(id)按 id 取值get(id) { return this.map[id]; }参数类型说明idString唯一标识符get返回与id关联的值。如果该id从未注册过则返回undefined。官方文档明确注明返回值Object —— 关联的值若不可用则返回undefined。在 TypeScript 声明中该返回类型为any | null实际运行时体现为undefined。使用时建议配合contains或直接做空值判断const cached registry.get(bg-image); if (registry.contains(bg-image)) { // 缓存命中直接复用 }3.4 contains(id)存在性检查contains(id) { return id in this.map; }参数类型说明idString唯一标识符返回值Boolean。这是官方文档所述查看某个值是否已注册到某个id的便捷方法。它使用in运算符判断键是否存在语义上等价于map.hasOwnProperty(id)的一层简化且能正确处理值为undefined但键已存在的边界情况。该方法是 Two.js 内部所有缓存命中判断的基石。四、内部核心应用场景虽然Registry本身是通用容器但它在 Two.js 中承担着三个关键内部职责深入理解这些场景才能真正理解它的设计价值。4.1 场景一Two.Texture.ImageRegistry —— 图像会话级缓存这是 Registry 在 Two.js 中最核心的应用。在 src/effects/texture.js 中纹理类持有静态注册表static ImageRegistry new Registry();其用途正如源码注释所述一份用于单个 Two.js 会话中图像数据的权威清单canonical listing用于在不同纹理之间缓存图像数据。典型调用链如下Texture.getImage(src)先调用getAbsoluteURL将相对路径归一化为绝对 URL通过临时anchor元素解析然后判断缓存Texture.ImageRegistry.contains(absoluteSrc)命中则直接get返回缓存的HTMLImageElement未命中时创建新的img/video元素并在加载完成后执行Texture.ImageRegistry.add(texture.src, image)登记。对应源码见 src/effects/texture.js 与 src/effects/texture.js。这套缓存机制的价值在于多个Two.Texture若引用同一个图片 URL最终只会创建一份HTMLImageElement从而显著节省内存与网络请求。这种以规范化的绝对 URL 为键、以真实图片元素为值的缓存模式正是 Registry 键值语义的典型体现。4.2 场景二SVG 解析中的 defs 缓存在 Two.js 的 SVG 解释器中Registry用于缓存 SVGdefs段中的定义资源。见 src/utils/interpret-svg.jssvg: function (node) { const defs (read.defs.current new Registry()); ... }解析器遍历 SVG 文档中的defs元素将渐变gradient、裁剪路径等定义按id写入该 Registry供后续fill、stroke属性引用时快速查找。该缓存还会被导出为svg.defs供上层代码在解析完成后继续使用。4.3 场景三WebGL 渲染器的 TextureRegistry在 src/renderers/webgl.js 中WebGL 渲染器拥有一个独立的纹理注册表TextureRegistry: new Registry(),该注册表用于追踪已上传到 GPU 的纹理实现纹理对象的统一登记与复用是 WebGL 渲染器管理图形资源的一部分。这再次印证了 Registry 的通用性——同一容器被复用于浏览器图像缓存、SVG 定义缓存与 GPU 纹理管理三类差异巨大的场景。五、使用示例5.1 基本用法import Two from two.js; const registry new Two.Registry(); // 注册 registry.add(circle, { radius: 20 }); registry.add(rect, { width: 10, height: 5 }); // 查询 registry.contains(circle); // true registry.get(circle); // { radius: 20 } // 覆盖 registry.add(circle, { radius: 40 }); registry.get(circle); // { radius: 40 } // 移除 registry.remove(circle); registry.contains(circle); // false registry.get(circle); // undefined // 链式调用 registry.add(a, 1).add(b, 2).remove(a);5.2 复刻图像缓存模式可以仿照Texture.ImageRegistry的成熟模式用 Registry 为高频资源做缓存import Two from two.js; const cache new Two.Registry(); function getAsset(url) { if (cache.contains(url)) { return cache.get(url); // 命中缓存 } const asset loadAsset(url); // 昂贵的加载过程 cache.add(url, asset); return asset; }要点在于以可规范化的唯一标识URL/绝对路径为键命中即复用未命中则创建并登记。这既是 Two.js 自身的实践也是一个通用且健壮的内存缓存范式。六、源码速览与深入学习类实现src/registry.js完整实现仅约 57 行类型声明src/registry.d.ts挂载位置src/two.jsTwo.Registry静态属性图像缓存应用src/effects/texture.jsTexture.ImageRegistrySVG defs 缓存应用src/utils/interpret-svg.jsWebGL 纹理注册src/renderers/webgl.js七、小结Two.Registry用最小的实现一个map、四个方法为 Two.js 提供了统一的键值目录能力通用可注册任意类型的值不依赖 DOM 与渲染器无头环境下可用链式add/remove返回this支持流畅的连续操作明确语义contains基于in运算符判断键存在性与值为 undefined严格区分内部复用ImageRegistry图像缓存、SVG defs定义缓存、WebGL TextureRegistryGPU 纹理登记三处核心场景共享同一套机制。理解 Registry就理解了 Two.js 中以唯一标识索引共享资源的底层设计哲学。如果你正在为 Two.js 应用编写资源管理、缓存复用或插件化的扩展代码Two.Registry是一个开箱即用的可靠选择。赞分享图形学前端【免费下载链接】two.jsA renderer agnostic two-dimensional drawing api for the web项目地址https://gitcode.com/gh_mirrors/tw/two.js点击查看免费下载相关推荐CircleType.js实现原理揭秘从数学公式到网页文字弯曲效果CircleType.js实现原理揭秘从数学公式到网页文字弯曲效果 CircleType.js是一款让网页文字实现弯曲效果的JavaScript库它通过精妙前端Substrate 镜像缓存测试基石深入 go-containerregistry pkg/registry 内存 OCI Registry 实现Substrate 镜像缓存测试基石深入 go containerregistry pkg/registry 内存 OCI Registry 实现 导读 本文人工智能AI AgentAgent 沙箱云原生容器运行时零信任深度解析 Spring SimpleAliasRegistryBean 别名注册与解析的底层实现深度解析 Spring SimpleAliasRegistryBean 别名注册与解析的底层实现 导读 本文基于 docs/Spring/clazz/Spr文档教程知识库上一篇IPTVnator 跨平台嵌入式 MPVWindows x64 与 Linux x64 原生后端落地指南下一篇5分钟快速上手跨平台资源下载神器res-downloader完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Codex 实战 Skills:用 Skill 自动抓取 20 个 RSS 订阅,并用 AI 自动输出中文摘要(TaoToken 统一 Key 接入版)

Codex 实战 Skills:用 Skill 自动抓取 20 个 RSS 订阅,并用 AI 自动输出中文摘要(TaoToken 统一 Key 接入版)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:05:36 阅读更多 →
昇腾Atlas 300V部署YOLOv5实战:模型转换与推理优化

昇腾Atlas 300V部署YOLOv5实战:模型转换与推理优化

1. Atlas到底是什么?先别急着把它当“显卡”我第一次接触Atlas 300V 24G时,第一反应也是打开它的规格表,试图跟手里的NVIDIA显卡做一一对应。核心数、频率、显存带宽、功耗……对着对着就发现不对劲,这东西压根不是按“显卡”的逻…

2026/9/25 13:04:35 阅读更多 →
实时无梯度手部重定向 SBR 算法详解|Smooth Operator 灵巧手遥操作复现指南(TaoToken 配置骨架)

实时无梯度手部重定向 SBR 算法详解|Smooth Operator 灵巧手遥操作复现指南(TaoToken 配置骨架)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:04:35 阅读更多 →

最新新闻

智能体记忆架构:从草稿笔记到组织级知识

智能体记忆架构:从草稿笔记到组织级知识

智能体记忆架构:从草稿笔记到组织级知识 原文来源:AIForBusiness | 人工智能 | 技术流程 作者:塞巴斯蒂安谢达尔(Sebastian Chedal) 文章目录智能体记忆架构:从草稿笔记到组织级知识为什么AI智能体不能只依…

2026/9/25 13:45:08 阅读更多 →
Atlas 300V 24G推理加速卡部署YOLOv5实战指南

Atlas 300V 24G推理加速卡部署YOLOv5实战指南

最近不少朋友私信问我:Atlas 300V 24G是不是运算加速卡?能不能拿来跑YOLO?这问题其实问得很实在,因为很多做安防、智慧交通、工业质检的团队,手里项目用到目标检测,又听说华为Atlas平台功耗低、成本划算&am…

2026/9/25 13:45:08 阅读更多 →
wp-calypso Dashboard 测试策略指南:E2E、nock 网络拦截与单元测试实战

wp-calypso Dashboard 测试策略指南:E2E、nock 网络拦截与单元测试实战

前端CMS 【免费下载链接】wp-calypso The JavaScript and API powered WordPress.com 项目地址: https://gitcode.com/gh_mirrors/wp/wp-calypso 点击查看 免费下载 wp-calypso 的 dashboard(新多站点托管控制台,即 my.wordpress.com&#x…

2026/9/25 13:45:08 阅读更多 →
广义估计方程GEE实战:重复测量数据建模、相关结构选型与R/Python实现

广义估计方程GEE实战:重复测量数据建模、相关结构选型与R/Python实现

1. 什么时候该选GEE:重复测量数据的一个现实决策做纵向数据分析的朋友大概率都遇到过这个场景:手里是一份随访数据,每个受试者有好几条记录,组内显然不独立,直接塞进普通回归模型怕犯错误。教科书这时候会给你两个方向…

2026/9/25 13:45:08 阅读更多 →
等保三级整改实战:3人小队用Cursor一周搞定数十个系统的敏感数据加密

等保三级整改实战:3人小队用Cursor一周搞定数十个系统的敏感数据加密

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 13:45:08 阅读更多 →
MikroORM 日志与调试完全指南:debug 模式、Logger Namespaces、自定义 Logger 与语法高亮

MikroORM 日志与调试完全指南:debug 模式、Logger Namespaces、自定义 Logger 与语法高亮

后端 【免费下载链接】mikro-orm TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases. 项目地址: https://gitcode.com/gh_mir…

2026/9/25 13:44:07 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →