Matter.js中无法加载SVG:类型错误问题求助
使用webpack+npm环境,复制官方示例代码加载SVG,已安装poly-decomp,但持续触发以下错误:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'numberOfItems')
加载SVG的代码片段如下:
// module aliases const Engine = Matter.Engine, Common = Matter.Common, Composite = Matter.Composite, Vertices = Matter.Vertices, Svg = Matter.Svg, Bodies = Matter.Bodies; // provide concave decomposition support library Common.setDecomp(require('poly-decomp')); const engine = Engine.create(), world = engine.world; if (typeof fetch !== 'undefined') { var select = function(root, selector) { return Array.prototype.slice.call(root.querySelectorAll(selector)); }; var loadSvg = function(url) { return fetch(url) .then(function(response) { return response.text(); }) .then(function(raw) { return (new window.DOMParser()).parseFromString(raw, 'image/svg+xml'); }); }; ([ './puzzle.svg' ]).forEach(function(path, i) { loadSvg(path).then(function(root) { // var color = Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1']); var vertexSets = select(root, 'path') .map(function(path) { return Vertices.scale(Svg.pathToVertices(path, 30), 0.4, 0.4); }); Composite.add(world, Bodies.fromVertices(0,i * -100, vertexSets, { isStatic: true }, true)); }); }); loadSvg('./svg/svg.svg').then(function(root) { // var color = Common.choose(['#f19648', '#f5d259', '#f55a3c', '#063e7b', '#ececd1']); var vertexSets = select(root, 'path') .map(function(path) { return Svg.pathToVertices(path, 30); }); Composite.add(world, Bodies.fromVertices(400, 80, vertexSets, { isStatic: true }, true)); }); } else { Common.warn('Fetch is not available. Could not load SVG.'); }
检查SVG加载有效性
错误源于Svg.pathToVertices处理的路径对象无效,优先验证SVG是否正确加载:在loadSvg的回调中打印调试信息,确认是否获取到了SVG的path元素:loadSvg(path).then(function(root) { console.log('SVG根节点:', root); console.log('提取的path元素:', select(root, 'path')); // 后续逻辑... });如果path数组为空,说明文件路径错误,或者SVG文件中没有使用path元素(比如用了rect、circle等其他形状)。
调整poly-decomp引入方式
webpack环境下直接require('poly-decomp')可能未正确导出核心对象,尝试改用ES模块导入:import decomp from 'poly-decomp'; Common.setDecomp(decomp);同时检查poly-decomp版本,确保与当前Matter.js版本兼容(部分旧版Matter.js依赖特定版本的poly-decomp)。
替换SVG解析方式
部分webpack环境中window.DOMParser存在兼容性问题,可改用第三方库解析SVG文本,比如svgson:import svgson from 'svgson'; var loadSvg = function(url) { return fetch(url) .then(res => res.text()) .then(raw => svgson.parse(raw)); };解析后从JSON结构中提取path的
d属性,再传入Svg.pathToVertices处理。验证Matter.js版本兼容性
确认当前Matter.js版本与官方示例一致,部分新版本可能调整了SVG加载的API逻辑,若版本不符,可尝试降级到示例对应的版本,或查阅官方文档更新代码。
内容的提问来源于stack exchange,提问作者Arthur

