如何在Forge Viewer中开发标记批量多选功能以支持删除等操作?
Great question! The Forge Viewer’s native markup tools don’t support multi-select out of the box, but building this functionality yourself is totally doable with the viewer’s API and some custom event handling. Let’s walk through a practical, step-by-step solution:
1. Track Selected Markups
First, you’ll need a way to keep track of which markups are selected. Start with a simple array to store selected markup IDs, then hook into the viewer’s markup selection events:
// Global array to track selected markup IDs let selectedMarkups = []; // Get reference to the MarkupsCore extension const markupExt = viewer.getExtension('Autodesk.Viewing.MarkupsCore'); // Listen for when a markup is selected markupExt.addEventListener(Autodesk.Viewing.MarkupsCore.EVENT.MARKUP_SELECTED, (event) => { const markupId = event.markup.id; const clickEvent = event.event; // Handle multi-select with Ctrl/Shift keys if (clickEvent.ctrlKey || clickEvent.shiftKey) { if (selectedMarkups.includes(markupId)) { // Deselect if already in the list selectedMarkups = selectedMarkups.filter(id => id !== markupId); } else { // Add to selected list selectedMarkups.push(markupId); } } else { // Single select: clear previous selection selectedMarkups = [markupId]; } // Update visual feedback for selected items updateSelectedMarkupStyles(); });
2. Add Visual Feedback for Selected Markups
Users need clear visual cues to know which markups are selected. Create a function to style selected items (like a prominent red outline):
function updateSelectedMarkupStyles() { const markupExt = viewer.getExtension('Autodesk.Viewing.MarkupsCore'); const allMarkups = markupExt.getMarkups(); allMarkups.forEach(markup => { const svgElement = markupExt.getMarkupSvg(markup.id); if (selectedMarkups.includes(markup.id)) { // Highlight selected markup svgElement.style.outline = '2px solid #ff4444'; svgElement.style.outlineOffset = '2px'; } else { // Reset style for unselected items svgElement.style.outline = ''; } }); }
3. Implement Batch Actions (Delete, etc.)
Now add functionality to perform bulk actions on selected markups. For example, a Delete key handler to remove all selected items at once:
// Listen for Delete key press to remove selected markups document.addEventListener('keydown', (e) => { if (e.key === 'Delete' && selectedMarkups.length > 0) { const markupExt = viewer.getExtension('Autodesk.Viewing.MarkupsCore'); selectedMarkups.forEach(id => markupExt.removeMarkup(id)); selectedMarkups = []; // Clear selection after deletion } });
You can expand this to add custom UI buttons for other actions (like copying or moving markups) by reusing the selectedMarkups array to target the right elements.
4. Handle Deselection on Canvas Click
Make sure to clear the selection when the user clicks outside any markup to avoid confusion:
// Deselect all when clicking empty canvas area viewer.canvas.addEventListener('click', (e) => { if (!e.target.closest('.adsk-markup-svg')) { selectedMarkups = []; updateSelectedMarkupStyles(); } });
Bonus: Add Box Selection (Optional)
For a more polished experience, you can implement box selection by tracking mouse drag events:
- Listen for
mousedownto start tracking the selection rectangle - Listen for
mousemoveto draw the rectangle on the viewer - Listen for
mouseupto check which markups are inside the rectangle and add them toselectedMarkups
Key Notes
- Always ensure the
MarkupsCoreextension is fully initialized before adding these listeners (wait for the viewer’sGEOMETRY_LOADED_EVENTor similar). - Test with all markup types (text, shapes, arrows) to ensure consistent behavior across different elements.
- You can tweak the visual styles (colors, outline thickness) to match your application’s design system.
内容的提问来源于stack exchange,提问作者Ankit Devani

