Annotorious Selector Pack插件圆形/椭圆形标注报错:n.reduce is not a function
Annotorious Selector Pack插件圆形/椭圆形标注报错:n.reduce is not a function
嘿,这个问题我之前踩过坑!本质原因是你用的ShapeLabelsFormatter没有适配圆形(Circle)和椭圆形(Ellipse)这两类特殊选择器,导致内部处理几何数据时出错了。
错误原因分析
从报错栈能看到,selector.js里的_e函数调用了n.reduce,但n不是数组——这是因为ShapeLabelsFormatter默认只处理矩形、多边形、点这类基于points数组的选择器,而圆形/椭圆形的坐标存储逻辑完全不同:
- 矩形/多边形:用
points数组存储顶点坐标 - 圆形:用
cx(圆心X)、cy(圆心Y)、r(半径)来定义 - 椭圆形:用
cx、cy、rx(X轴半径)、ry(Y轴半径)来定义
Formatter内部代码会尝试读取选择器的points属性并调用数组方法,圆形/椭圆形没有这个属性,自然就抛出reduce is not a function的错误了。
解决方案
这里给你两个可行的方案:
方案1:自定义兼容圆形/椭圆形的Formatter
扩展默认的ShapeLabelsFormatter,添加对Circle和Ellipse类型的处理逻辑,示例代码如下:
window.onload = function() { // 扩展ShapeLabelsFormatter,支持圆形和椭圆形 const CustomShapeLabelsFormatter = () => { const baseFormatter = Annotorious.ShapeLabelsFormatter(); return { // 渲染标注的标签 render: (annotation) => { const selector = annotation.target.selector; // 处理圆形选择器 if (selector.type === 'Circle') { const label = annotation.body?.[0]?.value || '圆形标注'; return `<div class="a9s-shape-label">${label}</div>`; } // 处理椭圆形选择器 if (selector.type === 'Ellipse') { const label = annotation.body?.[0]?.value || '椭圆形标注'; return `<div class="a9s-shape-label">${label}</div>`; } // 其他形状沿用默认逻辑 return baseFormatter.render(annotation); }, // 渲染编辑时的控件 renderEditor: (annotation, onChange) => { const selector = annotation.target.selector; if (['Circle', 'Ellipse'].includes(selector.type)) { // 自定义编辑输入框(和默认标签编辑器逻辑对齐) const input = document.createElement('input'); input.className = 'a9s-text-input'; input.value = annotation.body?.[0]?.value || ''; input.placeholder = '添加标签...'; input.oninput = (e) => { onChange({ ...annotation, body: [{ type: 'TextualBody', value: e.target.value }] }); }; return input; } // 其他形状沿用默认编辑逻辑 return baseFormatter.renderEditor(annotation, onChange); } }; }; // 初始化Annotorious时使用自定义Formatter var anno = Annotorious.init({ image: 'hallstatt', formatter: CustomShapeLabelsFormatter() }); // 加载插件 Annotorious.SelectorPack(anno); Annotorious.Toolbar(anno, document.getElementById('my-toolbar-container')); }
方案2:临时移除圆形/椭圆形工具(如果不需要的话)
如果你的场景暂时用不到圆形和椭圆形标注,可以在初始化Toolbar时指定只加载需要的工具:
Annotorious.Toolbar(anno, document.getElementById('my-toolbar-container'), { tools: ['rect', 'polygon', 'point', 'freehand'] // 去掉circle和ellipse });
这样就能避免触发Formatter的兼容问题,矩形/多边形等工具也能正常工作。
备注:内容来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

