Posted 13 January 2026, 12:41 am EST
Hi Yuji,
Thank you for the detailed explanation and for sharing your findings.
In this scenario, the behavior you are observing is expected. SpreadJS APIs such as getRowHeight, getColumnWidth, and getViewportHeight/Width return logical sheet sizes, and the zoom factor is applied later at the rendering layer. Because of this, combining these APIs does not yield the exact rendered area when the zoom level is other than 100%.
For cases like yours - where a custom SVG or canvas layer is required for rendering user presence, the recommended approach is to:
- Size the overlay using the SpreadJS host element (spread.getHost().getBoundingClientRect()), which already reflects zoom and DPI scaling.
- Use the sheet.getCellRect(row, col) to convert logical row/column ranges into accurate visual coordinates.
- Redraw the overlay in response to relevant events such as zoom, scroll, active sheet change, and window resize.
This pattern ensures correct alignment regardless of the zoom factor and is suitable for custom presence rendering scenarios.
We have shared a working sample and a detailed implementation below that demonstrates this overlay-based approach in another SpreadJS query. To avoid duplication, we recommend referring to that query and the attached code sample, which fully covers:
- Zoom-independent sizing
- High-DPI handling
- Viewport clipping
- Event-driven redraw logic
Please follow the link to the query for the complete reference implementation: https://developer.mescius.com/forums/spreadjs/custom-spreadsheet-overlays.
Please let us know if you require any further assistance.
Kind regards,
Chirag
Attachment: https://jscodemine.mescius.io/share/rICrkv4ueka4MqLNAnhBpA