C
C#13mo ago
br4kejet

❔ "Zooming" a WPF ScrollViewer to the center of the view

So I made this control (whose parent is the ScrollViewer i'm talking about), that has a "TargetWidth" and "ZoomScale" property (Setting either results in the Width property being set to TargetWidth * ZoomScale) I've got that implemented, but I've been struggling for the past 2 hours to implement a way to make it "zoom" towards the center of the view (as in, the ScrollViewer's view port, therefore including the current vertical and horizontal offset) Could anyone help? Every attempt I either zooms way too far to the left/right, or it initially works as intended, but then gradually starts zooming towards the left or right here's the mess of code I've been working with so far:
if (this.PART_ScrollViewer is ScrollViewer scroller) {
double multiplier;
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
multiplier = e.Delta > 0 ? 1.05 : 0.95;
}
else {
multiplier = e.Delta > 0 ? 1.1 : 0.9;
}
double oldzoom = this.UnitZoom;
double newzoom = TimelineUtils.ClampUnit(oldzoom * multiplier);
this.UnitZoom = newzoom;
newzoom = this.UnitZoom;
{
double full_horizontal_offset = scroller.HorizontalOffset / this.UnitZoom;
double visible_pixels = newzoom * this.ActualWidth;
double width_ratio = (scroller.ExtentWidth / newzoom) / this.ActualWidth;
double width_ratio_1 = scroller.ExtentWidth / this.ActualWidth;
double ratio_diff = width_ratio_1 / width_ratio;
double pixels_difference = (this.ActualWidth / oldzoom) - (this.ActualWidth / newzoom);
double actual_pixel_change = pixels_difference * newzoom;
double side_ratio_x = (scroller.HorizontalOffset / 2) / full_horizontal_offset;
double new_offset = full_horizontal_offset - actual_pixel_change;
scroller.ScrollToHorizontalOffset(scroller.HorizontalOffset + new_offset);
return;
}
}
if (this.PART_ScrollViewer is ScrollViewer scroller) {
double multiplier;
if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) {
multiplier = e.Delta > 0 ? 1.05 : 0.95;
}
else {
multiplier = e.Delta > 0 ? 1.1 : 0.9;
}
double oldzoom = this.UnitZoom;
double newzoom = TimelineUtils.ClampUnit(oldzoom * multiplier);
this.UnitZoom = newzoom;
newzoom = this.UnitZoom;
{
double full_horizontal_offset = scroller.HorizontalOffset / this.UnitZoom;
double visible_pixels = newzoom * this.ActualWidth;
double width_ratio = (scroller.ExtentWidth / newzoom) / this.ActualWidth;
double width_ratio_1 = scroller.ExtentWidth / this.ActualWidth;
double ratio_diff = width_ratio_1 / width_ratio;
double pixels_difference = (this.ActualWidth / oldzoom) - (this.ActualWidth / newzoom);
double actual_pixel_change = pixels_difference * newzoom;
double side_ratio_x = (scroller.HorizontalOffset / 2) / full_horizontal_offset;
double new_offset = full_horizontal_offset - actual_pixel_change;
scroller.ScrollToHorizontalOffset(scroller.HorizontalOffset + new_offset);
return;
}
}
2 Replies
br4kejet
br4kejet13mo ago
That code I posted just zooms towards the left if the current horizontal offset is 0 and when you zoom out it starts zooming towards the right. BUt if the horizontal offset is a bit greater than 0, then it shoots off to the right
Accord
Accord13mo ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.