VirtualCanvas
VirtualCanvas copied to clipboard
How to scale?
I tried using your demo app, works great. But, how do I scale. I tried binding to the DemoDiagram scale and increasing it, but didn't work. It works only for the first scale, after that when I change it, it doesn't work. Can you give an example on how to use it. Thanks.
I hooked up mouse wheel zooming, see OnPreviewMouseWheel
One more question, I've added zero length lines to display points, but when I zoom, the points are also magnified. This shouldn't be the case right? Since a zero length line cannot be zoomed and will stay as such. Or is the stroke is getting zoomed ?
Here's how I add lines:
return new Line() { Stroke = d.Stroke, StrokeThickness = 3, StrokeStartLineCap = PenLineCap.Round, StrokeEndLineCap = PenLineCap.Round };
Yes, zoom is a render transform, so everything is scaled. If you want to "undo" the zoom effect you can do some post zoom fixups that invert the scale using ISemanticZoomable. I hooked this up so the pen width in the random shapes is now "fixed" and does not zoom. This is done in DemoShapeVisual where the pen is constructed using pen = new Pen(Shape.Stroke, Shape.StrokeThickness / this.scale);
and the key is that the scale is updated whenever the zoom changes because it implements ISemanticZoomable and the ZoomWatcher is updating all ISemanticZoomable items in the canvas.
I also added a PanGesture so you can drag the canvas with mouse left down and drag.
Thanks a lot for all the updates. I've been using this and it's crazy good. I don't want to bother you a lot, but how do I add occlusion culling to this?
Eg: I draw a line with stroke thickness 4 from point (0, 100) to (100, 100) and say I draw a lot of lines between this line with a lesser stroke thickness and of the same color.
Is there anyway I stop drawing these things? Could you please guide me on where you are rendering and how should I be handling this ?
Also one more thing, when we zoom out we could see that the visuals are added in an incremental manner. Is it possible if we stop rendering until all the visuals are added and then render everything in one go ?
Thanks :))
Hi Harish, I'm glad you are enjoying the VirtualCanvas. Actual rendering in WPF is all handled by WPF. First thing to understand is that WPF is a "Retained mode graphics system". The lowest level control you have over rendering is the OnRender method as you see in DemoShapeVisual.cs but WPF decides if/when to call this method. For example, if you set the Visibility of a DemoShapeVisual to Hidden the OnRender method will no longer be called. But if you play with it you will notice that DemoShapeVisual.OnRender is not called very often, and this is because WPF is "retaining" the lower level primitives that you render and automatically compositing those visuals as needed, e.g. during scrolling, panning, etc. VirtualCanvas is tweaking WPF by actually removing shapes that are no longer needed, if VirtualCanvas didn't do this WPF would actually keep them in memory, resulting in smoother scrolling and animation, but as you can imagine retaining everything uses a lot of memory, so that's the classic trade off. In terms of deciding a render is no longer needed because the shape is fully occluded, I believe WPF will already do that for you, but I don't know how smart it is when it comes to a geometry like "lines (or more generally GeometryPaths". My guess is the built in logic is based only on "bounding boxes" and not on actual pixels rendered, because knowing what actual pixels are rendered is complicated - especially when you consider the fact you can using DrawingVisuals as a Brush!