mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 10:36:30 +00:00
add zoom and panning
zoom: ctrl + wheel, zoomed image: ctrl + move mousr
This commit is contained in:
@@ -3,11 +3,12 @@ using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using Azaion.Annotator.DTO;
|
||||
using Azaion.Common.DTO;
|
||||
using MediatR;
|
||||
using Color = System.Windows.Media.Color;
|
||||
using Image = System.Windows.Controls.Image;
|
||||
using Point = System.Windows.Point;
|
||||
using Rectangle = System.Windows.Shapes.Rectangle;
|
||||
using Size = System.Windows.Size;
|
||||
@@ -28,10 +29,15 @@ public class CanvasEditor : Canvas
|
||||
|
||||
private Rectangle _curRec = new();
|
||||
private DetectionControl _curAnn = null!;
|
||||
|
||||
|
||||
private readonly MatrixTransform _matrixTransform = new();
|
||||
private Point _panStartPoint;
|
||||
private bool _isZoomedIn;
|
||||
|
||||
private const int MIN_SIZE = 20;
|
||||
private readonly TimeSpan _viewThreshold = TimeSpan.FromMilliseconds(400);
|
||||
|
||||
|
||||
private Image _backgroundImage { get; set; } = new() { Stretch = Stretch.Fill };
|
||||
public IMediator Mediator { get; set; } = null!;
|
||||
|
||||
public static readonly DependencyProperty GetTimeFuncProp =
|
||||
@@ -107,13 +113,42 @@ public class CanvasEditor : Canvas
|
||||
MouseUp += CanvasMouseUp;
|
||||
SizeChanged += CanvasResized;
|
||||
Cursor = Cursors.Cross;
|
||||
|
||||
Children.Insert(0, _backgroundImage);
|
||||
Children.Add(_newAnnotationRect);
|
||||
Children.Add(_horizontalLine);
|
||||
Children.Add(_verticalLine);
|
||||
Children.Add(_classNameHint);
|
||||
|
||||
Loaded += Init;
|
||||
RenderTransform = _matrixTransform;
|
||||
MouseWheel += CanvasWheel;
|
||||
}
|
||||
|
||||
public void SetImageSource(ImageSource? source)
|
||||
{
|
||||
_backgroundImage.Source = source;
|
||||
}
|
||||
|
||||
private void CanvasWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
if (Keyboard.Modifiers != ModifierKeys.Control)
|
||||
return;
|
||||
|
||||
var mousePos = e.GetPosition(this);
|
||||
var scale = e.Delta > 0 ? 1.1 : 1 / 1.1;
|
||||
|
||||
var matrix = _matrixTransform.Matrix;
|
||||
if (scale < 1 && matrix.M11 * scale < 1.0)
|
||||
{
|
||||
_matrixTransform.Matrix = Matrix.Identity;
|
||||
_isZoomedIn = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
matrix.ScaleAt(scale, scale, mousePos.X, mousePos.Y);
|
||||
_matrixTransform.Matrix = matrix;
|
||||
_isZoomedIn = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void Init(object sender, RoutedEventArgs e)
|
||||
@@ -127,7 +162,13 @@ public class CanvasEditor : Canvas
|
||||
private void CanvasMouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
ClearSelections();
|
||||
NewAnnotationStart(sender, e);
|
||||
if (Keyboard.Modifiers == ModifierKeys.Control && _isZoomedIn)
|
||||
{
|
||||
_panStartPoint = e.GetPosition(this);
|
||||
SelectionState = SelectionState.PanZoomMoving;
|
||||
}
|
||||
else
|
||||
NewAnnotationStart(sender, e);
|
||||
}
|
||||
|
||||
private void CanvasMouseMove(object sender, MouseEventArgs e)
|
||||
@@ -137,17 +178,32 @@ public class CanvasEditor : Canvas
|
||||
_verticalLine.X1 = _verticalLine.X2 = pos.X;
|
||||
SetLeft(_classNameHint, pos.X + 10);
|
||||
SetTop(_classNameHint, pos.Y - 30);
|
||||
|
||||
if (e.LeftButton != MouseButtonState.Pressed)
|
||||
return;
|
||||
if (SelectionState == SelectionState.NewAnnCreating)
|
||||
NewAnnotationCreatingMove(sender, e);
|
||||
|
||||
if (SelectionState == SelectionState.AnnResizing)
|
||||
AnnotationResizeMove(sender, e);
|
||||
|
||||
if (SelectionState == SelectionState.AnnMoving)
|
||||
AnnotationPositionMove(sender, e);
|
||||
switch (SelectionState)
|
||||
{
|
||||
case SelectionState.NewAnnCreating:
|
||||
NewAnnotationCreatingMove(sender, e);
|
||||
break;
|
||||
case SelectionState.AnnResizing:
|
||||
AnnotationResizeMove(sender, e);
|
||||
break;
|
||||
case SelectionState.AnnMoving:
|
||||
AnnotationPositionMove(sender, e);
|
||||
break;
|
||||
case SelectionState.PanZoomMoving:
|
||||
PanZoomMove(sender, e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PanZoomMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
var currentPoint = e.GetPosition(this);
|
||||
var delta = currentPoint - _panStartPoint;
|
||||
|
||||
var matrix = _matrixTransform.Matrix;
|
||||
matrix.Translate(delta.X, delta.Y);
|
||||
_matrixTransform.Matrix = matrix;
|
||||
}
|
||||
|
||||
private void CanvasMouseUp(object sender, MouseButtonEventArgs e)
|
||||
@@ -173,15 +229,12 @@ public class CanvasEditor : Canvas
|
||||
});
|
||||
control.UpdateLayout();
|
||||
CheckLabelBoundaries(control);
|
||||
SelectionState = SelectionState.None;
|
||||
e.Handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
else if (SelectionState != SelectionState.PanZoomMoving)
|
||||
CheckLabelBoundaries(_curAnn);
|
||||
SelectionState = SelectionState.None;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
SelectionState = SelectionState.None;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void CheckLabelBoundaries(DetectionControl detectionControl)
|
||||
@@ -213,6 +266,8 @@ public class CanvasEditor : Canvas
|
||||
{
|
||||
_horizontalLine.X2 = e.NewSize.Width;
|
||||
_verticalLine.Y2 = e.NewSize.Height;
|
||||
_backgroundImage.Width = e.NewSize.Width;
|
||||
_backgroundImage.Height = e.NewSize.Height;
|
||||
}
|
||||
|
||||
#region Annotation Resizing & Moving
|
||||
@@ -319,7 +374,7 @@ public class CanvasEditor : Canvas
|
||||
SetLeft(_newAnnotationRect, _newAnnotationStartPos.X);
|
||||
SetTop(_newAnnotationRect, _newAnnotationStartPos.Y);
|
||||
_newAnnotationRect.MouseMove += NewAnnotationCreatingMove;
|
||||
|
||||
|
||||
SelectionState = SelectionState.NewAnnCreating;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user