VirtualCanvas icon indicating copy to clipboard operation
VirtualCanvas copied to clipboard

How to scale?

Open harxish opened this issue 1 year ago • 6 comments

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.

harxish avatar Mar 19 '23 16:03 harxish

I hooked up mouse wheel zooming, see OnPreviewMouseWheel

clovett avatar Mar 19 '23 21:03 clovett

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 };

harxish avatar Mar 20 '23 11:03 harxish

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.

lovettchris avatar Mar 20 '23 22:03 lovettchris

I also added a PanGesture so you can drag the canvas with mouse left down and drag.

lovettchris avatar Mar 20 '23 22:03 lovettchris

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 :))

harxish avatar Apr 03 '23 09:04 harxish

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!

lovettchris avatar Apr 03 '23 18:04 lovettchris