如何通过代码选中SpriteViewable并将SVG URL切换为highlightedUrl?
解决SpriteViewable切换高亮SVG的实现方案
核心思路
SpriteViewable本身没有暴露可直接修改的URL属性,但可以通过「移除目标Sprite → 用高亮URL重新创建并添加Sprite」的方式实现选中效果,结合你已有的dbId与issue.id关联列表,就能完成列表点击到模型Sprite高亮的联动。
具体实现步骤
1. 封装Sprite操作工具函数
先实现两个通用函数,分别用于移除指定dbId的Sprite,以及添加带指定URL的Sprite:
// 移除指定dbId的Sprite function removeSpriteByDbId(viewer, dbId) { const spriteManager = viewer.getDataVisualization().getSpriteManager(); const sprites = spriteManager.getSprites(); const targetSprite = sprites.find(sprite => sprite.dbId === dbId); if (targetSprite) { spriteManager.removeSprite(targetSprite); } } // 添加带指定URL的Sprite function addSpriteWithUrl(viewer, dbId, spriteUrl, position) { const spriteManager = viewer.getDataVisualization().getSpriteManager(); const sprite = new Autodesk.DataVisualization.Core.Sprite( dbId, spriteUrl, position ); spriteManager.addSprite(sprite); }
2. 绑定问题列表点击事件
在你的问题列表点击回调中,通过issue.id找到对应的dbId,再执行移除旧Sprite、添加高亮Sprite的操作:
// 假设这是你的问题列表点击事件处理函数 function onIssueListItemClick(issueId) { // 从你的关联列表中获取对应issue的Sprite信息 const issueSpriteMap = getIssueSpriteMapping(); // 替换为你的关联列表获取逻辑 const targetItem = issueSpriteMap.find(item => item.issueId === issueId); if (!targetItem) return; const { dbId, highlightedUrl, position } = targetItem; const viewer = window.viewer; // 替换为你的Viewer实例 // 先移除原有Sprite,再添加高亮版本 removeSpriteByDbId(viewer, dbId); addSpriteWithUrl(viewer, dbId, highlightedUrl, position); }
3. 优化:支持切换回默认状态
如果需要取消选中时恢复原始SVG,可以在关联列表中存储原始URL,点击新问题时先把之前高亮的Sprite切回默认状态:
// 关联列表结构示例(包含原始URL) const issueSpriteMap = [ { issueId: 'ISSUE-001', dbId: 123, originalUrl: '/assets/original-sprite.svg', highlightedUrl: '/assets/highlighted-sprite.svg', position: new THREE.Vector3(15, 25, 35) } ]; // 记录当前高亮的issue ID let currentHighlightedIssue = null; function onIssueListItemClick(issueId) { const issueSpriteMap = getIssueSpriteMapping(); // 恢复之前高亮的Sprite到原始状态 if (currentHighlightedIssue) { const prevItem = issueSpriteMap.find(item => item.issueId === currentHighlightedIssue); if (prevItem) { removeSpriteByDbId(window.viewer, prevItem.dbId); addSpriteWithUrl(window.viewer, prevItem.dbId, prevItem.originalUrl, prevItem.position); } } // 高亮当前选中的Sprite const targetItem = issueSpriteMap.find(item => item.issueId === issueId); if (targetItem) { removeSpriteByDbId(window.viewer, targetItem.dbId); addSpriteWithUrl(window.viewer, targetItem.dbId, targetItem.highlightedUrl, targetItem.position); currentHighlightedIssue = issueId; } else { currentHighlightedIssue = null; } }
关键注意点
- 位置复用:初始创建Sprite时,一定要把位置信息存入关联列表,这样重新添加的高亮Sprite才能和原位置完全一致。
- 性能优化:如果Sprite数量极大,频繁移除添加可能有轻微性能损耗,这种情况下可以直接操作Sprite底层的Three.js纹理对象修改URL,但需要对Three.js的材质系统有一定了解。
内容的提问来源于stack exchange,提问作者Gustavo da Costa e Silva
相关产品推荐
相关产品推荐

