Skip to content

Commit 1ad1196

Browse files
Adding support for panning
Adding support for panning
1 parent 5fd878f commit 1ad1196

File tree

1 file changed

+35
-24
lines changed

1 file changed

+35
-24
lines changed

Sources/Microcharts.Forms/ChartView.cs

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ private void OnPaintCanvas(object sender, SKPaintSurfaceEventArgs e)
9292
}
9393

9494

95-
float currentScale = 1;
96-
float startScale = 1;
97-
SKPoint offsetPosition = new SKPoint(0, 0);
98-
SKPoint translation = new SKPoint(0, 0);
95+
double zoomCurScale = 1;
96+
double zoomStartScale = 1;
97+
98+
SKPoint zoomStartOrigin = new SKPoint(0, 0);
99+
SKPoint zoomStartOffset = new SKPoint(0, 0);
100+
SKPoint zoomTranslation = new SKPoint(0, 0);
99101

100102
void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
101103
{
@@ -106,51 +108,60 @@ void OnPinchUpdated(object sender, PinchGestureUpdatedEventArgs e)
106108
{
107109
// Store the current scale factor applied to the wrapped user interface element,
108110
// and zero the components for the center point of the translate transform.
109-
startScale = currentScale;
111+
zoomStartScale = zoomCurScale = axisChart.XForm.Scale;
112+
zoomStartOrigin = new SKPoint( (float)e.ScaleOrigin.X, (float)e.ScaleOrigin.Y);
113+
zoomStartOffset = axisChart.XForm.Offset;
110114
}
115+
111116
if (e.Status == GestureStatus.Running)
112117
{
118+
// e.Scale is the delta to be applied for the current frame
113119
// Calculate the scale factor to be applied.
114-
currentScale += (float)((e.Scale - 1) * startScale);
115-
currentScale = Math.Max(1, currentScale);
116-
currentScale = Math.Min(5, currentScale);
120+
zoomCurScale += (e.Scale - 1) * zoomStartScale;
121+
zoomCurScale = Math.Max(1, zoomCurScale);
122+
zoomCurScale = Math.Min(5, zoomCurScale);
123+
124+
125+
SKPoint zoomPanDelta = new SKPoint((float)((e.ScaleOrigin.X - zoomStartOrigin.X) * CanvasSize.Width), (float)((e.ScaleOrigin.Y - zoomStartOrigin.Y) * CanvasSize.Height));
117126

118127
// The ScaleOrigin is in relative coordinates to the wrapped user interface element,
119128
// so get the X pixel coordinate.
120-
double renderedX = X + offsetPosition.X;
129+
double renderedX = X + zoomStartOffset.X;
121130
double deltaX = renderedX / CanvasSize.Width;
122-
double deltaWidth = CanvasSize.Width / (CanvasSize.Width * startScale);
131+
double deltaWidth = CanvasSize.Width / (CanvasSize.Width * zoomStartScale);
123132
double originX = (e.ScaleOrigin.X - deltaX) * deltaWidth;
124133

134+
//Console.WriteLine("ScaleOrigin: {0}, {1}", e.ScaleOrigin.X, e.ScaleOrigin.Y);
135+
125136
// The ScaleOrigin is in relative coordinates to the wrapped user interface element,
126137
// so get the Y pixel coordinate.
127-
double renderedY = Y + offsetPosition.Y;
138+
double renderedY = Y + zoomStartOffset.Y;
128139
double deltaY = renderedY / CanvasSize.Height;
129-
double deltaHeight = CanvasSize.Height / (CanvasSize.Height * startScale);
140+
double deltaHeight = CanvasSize.Height / (CanvasSize.Height * zoomStartScale);
130141
double originY = (e.ScaleOrigin.Y - deltaY) * deltaHeight;
131142

132143
// Calculate the transformed element pixel coordinates.
133-
double targetX = offsetPosition.X - (originX * CanvasSize.Width) * (currentScale - startScale);
134-
double targetY = offsetPosition.Y - (originY * CanvasSize.Height) * (currentScale - startScale);
144+
double targetX = zoomStartOffset.X - (originX * CanvasSize.Width) * (zoomCurScale - zoomStartScale);
145+
double targetY = zoomStartOffset.Y - (originY * CanvasSize.Height) * (zoomCurScale - zoomStartScale);
135146

136147
// Apply translation based on the change in origin.
137-
translation.X = (float)targetX.Clamp(-CanvasSize.Width * (currentScale - 1), 0);
138-
translation.Y = (float)targetY.Clamp(-CanvasSize.Height * (currentScale - 1), 0);
148+
zoomTranslation.X = (float)targetX;
149+
zoomTranslation.Y = (float)targetY;
150+
139151

140-
//Console.WriteLine("{0}, {1}", translation.X, translation.Y);
152+
SKPoint final = zoomTranslation + zoomPanDelta;
153+
final.X = Math.Min(Math.Max(final.X, -CanvasSize.Width * (float)(zoomCurScale - 1)), 0);
154+
final.Y = Math.Min(Math.Max(final.Y, -CanvasSize.Height * (float)(zoomCurScale - 1)), 0);
155+
141156

142-
axisChart.XForm.Scale = currentScale;
143-
axisChart.XForm.Offset = translation;
157+
axisChart.XForm.Scale = (float)zoomCurScale;
158+
axisChart.XForm.Offset = final;
144159
InvalidateSurface();
145160

146161
}
162+
147163
if (e.Status == GestureStatus.Completed)
148164
{
149-
// Store the translation delta's of the wrapped user interface element.
150-
offsetPosition = translation;
151-
152-
axisChart.XForm.Scale = currentScale;
153-
axisChart.XForm.Offset = translation;
154165
InvalidateSurface();
155166
}
156167
}

0 commit comments

Comments
 (0)