How can I avoid the “transition” when scaling to the canvas object, when the center of scaling changes due to pinching (zooming) or other metropolis-style gesture.
The behavior I'm trying to archive is similar to the scaling behavior of the preinstalled win8 maps application. If you perform a pinch gesture (increase or decrease), the center of zoom is set halfway between the fingers. If you lift one of your fingers, place it on another point, you can immediately perform another zoom operation, the center of zoom will change correctly, without any jumps (moving from the coordinates of the user interface of objects on the canvas).
I am trying to implement similar behavior on a large Canvas object (in a C # WinRT application) using a compound transform. I want to enable translation and scaling, without rotation (for now, maybe I'll add this later):
I initialize this by placing the center of scale at the center of the screen:
this.compositeTransform = new CompositeTransform(); this.compositeTransform.CenterX = this.mainPage.Width / 2.0; this.compositeTransform.CenterY = this.mainPage.Height / 2.0; this.innerCanvas.RenderTransform = compositeTransform;
Then I will use the delta event to process the input
private void InnerCanvas_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) { this.compositeTransform.ScaleX *= e.Delta.Scale; this.compositeTransform.ScaleY *= e.Delta.Scale; this.compositeTransform.CenterX = e.Position.X; this.compositeTransform.CenterY = e.Position.Y; this.compositeTransform.TranslateX += e.Delta.Translation.X; this.compositeTransform.TranslateY += e.Delta.Translation.Y; }
This works correctly if I perform the same gesture. The new center is calculated correctly when I perform tough gestures. However, a change in the center of zoom leads to a sudden jump, for example, when one of the fingers is lifted after a gesture. Of course, I can only change the center for gestures, but the problem of jumping remains. This, of course, is logical, since scaling works with the new center of scaling. I did not understand how to avoid the jump. Since the scale value itself remains constant, it should be possible to have the same form (unchanged coordinates) with a changed center.
My current reasoning is that I have to somehow change the coordinates of TranslateX and TranslateYY in order to balance the new center point so that the current screen coordinates of the ui elements remain unchanged. Something like this (scaleTransform is a ScaleTransform that only gets scale data) ...
Point reverseScaleTransform = this.scaleTransform.Inverse.TransformPoint(new Point(e.Position.X,e.Position.Y)); this.compositeTransform.TranslateX += reverseScaleTransform.X - e.Position.X; this.compositeTransform.TranslateY += reverseScaleTransform.Y - e.Position.Y;
But that doesn't work either. All this seems like a standard problem on the tablet, but I did not find a solution, despite the excessive search, maybe I'm using the wrong keywords.