Continuous zoom and direct rendering#79
Conversation
Variable is unused, left over from previous version?
use min() instead of the index/loop approach
- added pinch-to-zoom gesture support for trackpads - added Cmd + scroll wheel support for mouse both zoom methods are centered on mouse position
Previously we'd pre-render the entire canvas to a bitmap at the current zoom level, convert it to a CALayer's contents, and display that layer. This is replaced by directly drawing to the view's graphics context. Changes: - removed layer-based rendering approach (CALayer and bitmap caching) - added drawRect_ method to draw canvas contents directly to view's graphics context, with viewport clipping - updated placeholder image handling to use direct drawing - removed unused backing scale factor (_dpr) and related bitmap rendering code - canvas contents are now scaled using NSAffineTransform instead of pre-scaling bitmaps
|
That's a huge improvement in the animated case; nice work! I'm a little worried about the static case though. Have you tried scrolling around while zoomed in on moderately complex graphics (e.g., the Drawing›Spider example)? That's the scenario that prompted the existing bitmap + CALayer approach. I wonder if there's a hybrid option available to us, where it uses direct drawing while animating then switches to the cached-bitmap approach when the animation terminates (or when a single image is being generated)? |
|
Thanks for taking a look! I agree that the static case is a concern (scroll performance with Drawing›Spider is poor) and I think your suggestion of a hybrid approach is the right balance. I'll take a crack at that and build on this PR. With Drawing›Spider, the trackpad/mouse zoom isn't great either, and honestly this direct-drawing implementation is redrawing much too often on zoom in any case. For the static case, what I can try is displaying a cached bitmap that gets scaled when zoom starts, and when zoom ends (or we hit some gate condition during the zoom) asynchronously render a new cached bitmap that gets swapped in when ready. That way we have smooth zoom and scroll no matter what. |
This PR adds the ability to continuously zoom in and out on the PlotDevice canvas with a trackpad or mouse. It also improves rendering performance by replacing the bitmap-based approach with directly rendering to the graphic context.
Continuous zoom
zoom_demo.mov
Direct render approach
Previously, the GraphicsView would pre-render the entire canvas to a bitmap (NSImage) at the current zoom level, convert it to a CALayer's contents, and display that layer. This has been replaced by directly drawing to the view's graphics context, with viewport clipping to only draw the visible portion of the canvas.
This avoids potentially expensive pre-rendering and caching, which can be significantly faster for large scenes or high zoom levels:

This is particularly helpful when working with animations, since each frame draws faster:
animation_test.mp4
Note: The old bitmap approach was smoother when scrolling at high zoom (just moving a cached bitmap around instead of redrawing), but overall I think the benefits of direct drawing outweigh this.