Mejorado de Zoom y panning
This commit is contained in:
parent
506ee16ae1
commit
77c9f3db5e
|
@ -8,6 +8,7 @@ using MouseEventArgs = System.Windows.Input.MouseEventArgs;
|
||||||
using UserControl = System.Windows.Controls.UserControl;
|
using UserControl = System.Windows.Controls.UserControl;
|
||||||
using CtrEditor.ObjetosSim;
|
using CtrEditor.ObjetosSim;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
|
||||||
namespace CtrEditor
|
namespace CtrEditor
|
||||||
|
@ -25,6 +26,14 @@ namespace CtrEditor
|
||||||
private Image imagenDeFondo;
|
private Image imagenDeFondo;
|
||||||
|
|
||||||
private DispatcherTimer _zoomTimer;
|
private DispatcherTimer _zoomTimer;
|
||||||
|
private double _targetZoomFactor;
|
||||||
|
private double _initialZoomFactor;
|
||||||
|
private double _currentZoomStep;
|
||||||
|
private Point _zoomCursorPosition;
|
||||||
|
private const int ZoomDuration = 500; // Duración del zoom en milisegundos
|
||||||
|
private int _ZoomDuration;
|
||||||
|
private const double MinZoomScale = 0.1; // Límite mínimo de zoom
|
||||||
|
private Stopwatch _stopwatch;
|
||||||
|
|
||||||
// Para los UserControl
|
// Para los UserControl
|
||||||
private Point _startPointUserControl;
|
private Point _startPointUserControl;
|
||||||
|
@ -40,6 +49,11 @@ namespace CtrEditor
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
|
_zoomTimer = new DispatcherTimer();
|
||||||
|
_zoomTimer.Interval = TimeSpan.FromMilliseconds(1);
|
||||||
|
_zoomTimer.Tick += ZoomTimer_Tick;
|
||||||
|
_stopwatch = new Stopwatch();
|
||||||
|
|
||||||
this.Loaded += MainWindow_Loaded;
|
this.Loaded += MainWindow_Loaded;
|
||||||
ImagenEnTrabajoScrollViewer.PreviewMouseWheel += ImagenEnTrabajoCanvas_MouseWheel;
|
ImagenEnTrabajoScrollViewer.PreviewMouseWheel += ImagenEnTrabajoCanvas_MouseWheel;
|
||||||
ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown_Panning;
|
ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown_Panning;
|
||||||
|
@ -380,26 +394,70 @@ namespace CtrEditor
|
||||||
|
|
||||||
private void ImagenEnTrabajoCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
|
private void ImagenEnTrabajoCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
|
||||||
{
|
{
|
||||||
|
_initialZoomFactor = ((ScaleTransform)((TransformGroup)ImagenEnTrabajoCanvas.RenderTransform).Children.First(t => t is ScaleTransform)).ScaleX;
|
||||||
|
|
||||||
|
// Calcula el factor de escala mínimo para que toda la imagen sea visible
|
||||||
|
double minZoomFactor = Math.Min(
|
||||||
|
ImagenEnTrabajoScrollViewer.ViewportWidth / ImagenEnTrabajoCanvas.ActualWidth,
|
||||||
|
ImagenEnTrabajoScrollViewer.ViewportHeight / ImagenEnTrabajoCanvas.ActualHeight);
|
||||||
|
|
||||||
|
// Ajusta el targetZoomFactor pero no permite que baje del mínimo
|
||||||
|
_targetZoomFactor = e.Delta > 0 ? _initialZoomFactor * 1.4 : Math.Max(_initialZoomFactor * 0.75, minZoomFactor);
|
||||||
|
|
||||||
|
_zoomCursorPosition = e.GetPosition(ImagenEnTrabajoCanvas);
|
||||||
|
|
||||||
|
// Desactivar el escalado de alta calidad para mejorar el rendimiento
|
||||||
|
RenderOptions.SetBitmapScalingMode(ImagenEnTrabajoCanvas, BitmapScalingMode.LowQuality);
|
||||||
|
|
||||||
|
if (!_zoomTimer.IsEnabled)
|
||||||
|
_ZoomDuration = ZoomDuration;
|
||||||
|
else
|
||||||
|
_ZoomDuration = ZoomDuration / 3;
|
||||||
|
|
||||||
|
_stopwatch.Restart();
|
||||||
|
_zoomTimer.Start();
|
||||||
|
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ZoomTimer_Tick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
double elapsedMilliseconds = _stopwatch.ElapsedMilliseconds;
|
||||||
|
|
||||||
|
if (elapsedMilliseconds >= _ZoomDuration)
|
||||||
|
{
|
||||||
|
_zoomTimer.Stop();
|
||||||
|
_stopwatch.Stop();
|
||||||
|
|
||||||
|
// Volver a activar el escalado de alta calidad después de completar el zoom
|
||||||
|
RenderOptions.SetBitmapScalingMode(ImagenEnTrabajoCanvas, BitmapScalingMode.HighQuality);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var tg = (TransformGroup)ImagenEnTrabajoCanvas.RenderTransform;
|
var tg = (TransformGroup)ImagenEnTrabajoCanvas.RenderTransform;
|
||||||
var st = (ScaleTransform)tg.Children.First(t => t is ScaleTransform);
|
var st = (ScaleTransform)tg.Children.First(t => t is ScaleTransform);
|
||||||
var tt = (TranslateTransform)tg.Children.First(t => t is TranslateTransform);
|
var tt = (TranslateTransform)tg.Children.First(t => t is TranslateTransform);
|
||||||
|
|
||||||
double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
|
// Interpolación cuadrática para la desaceleración
|
||||||
Point cursorPosition = e.GetPosition(ImagenEnTrabajoCanvas);
|
double t = elapsedMilliseconds / _ZoomDuration;
|
||||||
|
double easeOutT = t * (2 - t); // Función de interpolación cuadrática (ease-out)
|
||||||
|
double zoomFactor = _initialZoomFactor + (_targetZoomFactor - _initialZoomFactor) * easeOutT;
|
||||||
|
|
||||||
|
// Asegúrate de no ir por debajo del zoom mínimo
|
||||||
|
zoomFactor = Math.Max(zoomFactor, MinZoomScale);
|
||||||
|
|
||||||
|
Point cursorPosition = _zoomCursorPosition;
|
||||||
|
|
||||||
// Calcular el punto focal del zoom relativo al contenido del Canvas
|
|
||||||
var relativeX = cursorPosition.X * st.ScaleX + tt.X;
|
var relativeX = cursorPosition.X * st.ScaleX + tt.X;
|
||||||
var relativeY = cursorPosition.Y * st.ScaleY + tt.Y;
|
var relativeY = cursorPosition.Y * st.ScaleY + tt.Y;
|
||||||
|
|
||||||
// Aplicar el zoom
|
st.ScaleX = zoomFactor;
|
||||||
st.ScaleX *= zoomFactor;
|
st.ScaleY = zoomFactor;
|
||||||
st.ScaleY *= zoomFactor;
|
|
||||||
|
|
||||||
// Ajustar la transformación de traducción para mantener el punto de zoom centrado
|
|
||||||
tt.X = relativeX - cursorPosition.X * st.ScaleX;
|
tt.X = relativeX - cursorPosition.X * st.ScaleX;
|
||||||
tt.Y = relativeY - cursorPosition.Y * st.ScaleY;
|
tt.Y = relativeY - cursorPosition.Y * st.ScaleY;
|
||||||
|
|
||||||
e.Handled = true; // Evita el procesamiento adicional del evento
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListaOs_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void ListaOs_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
|
Loading…
Reference in New Issue