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 CtrEditor.ObjetosSim;
|
||||
using System.Windows.Threading;
|
||||
using System.Diagnostics;
|
||||
|
||||
|
||||
namespace CtrEditor
|
||||
|
@ -25,6 +26,14 @@ namespace CtrEditor
|
|||
private Image imagenDeFondo;
|
||||
|
||||
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
|
||||
private Point _startPointUserControl;
|
||||
|
@ -40,6 +49,11 @@ namespace CtrEditor
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
_zoomTimer = new DispatcherTimer();
|
||||
_zoomTimer.Interval = TimeSpan.FromMilliseconds(1);
|
||||
_zoomTimer.Tick += ZoomTimer_Tick;
|
||||
_stopwatch = new Stopwatch();
|
||||
|
||||
this.Loaded += MainWindow_Loaded;
|
||||
ImagenEnTrabajoScrollViewer.PreviewMouseWheel += ImagenEnTrabajoCanvas_MouseWheel;
|
||||
ImagenEnTrabajoCanvas.MouseDown += Canvas_MouseDown_Panning;
|
||||
|
@ -380,26 +394,70 @@ namespace CtrEditor
|
|||
|
||||
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 st = (ScaleTransform)tg.Children.First(t => t is ScaleTransform);
|
||||
var tt = (TranslateTransform)tg.Children.First(t => t is TranslateTransform);
|
||||
|
||||
double zoomFactor = e.Delta > 0 ? 1.1 : 0.9;
|
||||
Point cursorPosition = e.GetPosition(ImagenEnTrabajoCanvas);
|
||||
// Interpolación cuadrática para la desaceleración
|
||||
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 relativeY = cursorPosition.Y * st.ScaleY + tt.Y;
|
||||
|
||||
// Aplicar el zoom
|
||||
st.ScaleX *= zoomFactor;
|
||||
st.ScaleY *= zoomFactor;
|
||||
st.ScaleX = 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.Y = relativeY - cursorPosition.Y * st.ScaleY;
|
||||
|
||||
e.Handled = true; // Evita el procesamiento adicional del evento
|
||||
}
|
||||
|
||||
private void ListaOs_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
|
|
Loading…
Reference in New Issue