将 相较画布的最小缩放大小 作为 property 暴露给用户

This commit is contained in:
杨劼
2024-06-03 16:11:36 +08:00
parent 2d2cecbc74
commit 2e1b776bb6
2 changed files with 38 additions and 11 deletions

View File

@@ -20,7 +20,8 @@
<u:ImageViewer <u:ImageViewer
Name="viewer" Name="viewer"
Width="600" Width="600"
Height="300" Height="300"
MinScale="0.5"
Source="../Assets/3x.png"> Source="../Assets/3x.png">
<u:ImageViewer.Overlayer> <u:ImageViewer.Overlayer>
<Grid <Grid

View File

@@ -51,6 +51,16 @@ public class ImageViewer: TemplatedControl
set => SetAndRaise(ScaleProperty, ref _scale, value); set => SetAndRaise(ScaleProperty, ref _scale, value);
} }
public static readonly DirectProperty<ImageViewer, double> MinScaleProperty = AvaloniaProperty.RegisterDirect<ImageViewer, double>(
nameof(MinScale), o => o.MinScale, (o, v) => o.MinScale = v, unsetValue: 0.1);
public double MinScale
{
get => _minScale;
set => SetAndRaise(ScaleProperty, ref _minScale, value);
}
private double _minScale = 1;
private double _translateX; private double _translateX;
public static readonly DirectProperty<ImageViewer, double> TranslateXProperty = AvaloniaProperty.RegisterDirect<ImageViewer, double>( public static readonly DirectProperty<ImageViewer, double> TranslateXProperty = AvaloniaProperty.RegisterDirect<ImageViewer, double>(
@@ -101,9 +111,7 @@ public class ImageViewer: TemplatedControl
set => SetValue(StretchProperty, value); set => SetValue(StretchProperty, value);
} }
private double _minScale = 0.5; private double _sourceMinScale = 0.1;
private const double defaultMinScale = 0.1;
static ImageViewer() static ImageViewer()
{ {
@@ -113,6 +121,7 @@ public class ImageViewer: TemplatedControl
TranslateXProperty.Changed.AddClassHandler<ImageViewer>((o,e)=>o.OnTranslateXChanged(e)); TranslateXProperty.Changed.AddClassHandler<ImageViewer>((o,e)=>o.OnTranslateXChanged(e));
TranslateYProperty.Changed.AddClassHandler<ImageViewer>((o, e) => o.OnTranslateYChanged(e)); TranslateYProperty.Changed.AddClassHandler<ImageViewer>((o, e) => o.OnTranslateYChanged(e));
StretchProperty.Changed.AddClassHandler<ImageViewer>((o, e) => o.OnStretchChanged(e)); StretchProperty.Changed.AddClassHandler<ImageViewer>((o, e) => o.OnStretchChanged(e));
MinScaleProperty.Changed.AddClassHandler<ImageViewer>((o, e) => o.OnMinScaleChanged(e));
} }
private void OnTranslateYChanged(AvaloniaPropertyChangedEventArgs args) private void OnTranslateYChanged(AvaloniaPropertyChangedEventArgs args)
@@ -165,7 +174,7 @@ public class ImageViewer: TemplatedControl
_image.Height = size.Height; _image.Height = size.Height;
} }
Scale = GetScaleRatio(width/size.Width, height/size.Height, this.Stretch); Scale = GetScaleRatio(width/size.Width, height/size.Height, this.Stretch);
_minScale = Math.Min(width * defaultMinScale / size.Width, height * defaultMinScale / size.Height); _sourceMinScale = Math.Min(width * MinScale / size.Width, height * MinScale / size.Height);
} }
private void OnStretchChanged(AvaloniaPropertyChangedEventArgs args) private void OnStretchChanged(AvaloniaPropertyChangedEventArgs args)
@@ -174,14 +183,31 @@ public class ImageViewer: TemplatedControl
Scale = GetScaleRatio(Width / _image!.Width, Height / _image!.Height, stretch); Scale = GetScaleRatio(Width / _image!.Width, Height / _image!.Height, stretch);
if(_image is { }) if(_image is { })
{ {
_minScale = Math.Min(Width * defaultMinScale / _image.Width, Height * defaultMinScale / _image.Height); _sourceMinScale = Math.Min(Width * MinScale / _image.Width, Height * MinScale / _image.Height);
} }
else else
{ {
_minScale = defaultMinScale; _sourceMinScale = MinScale;
} }
} }
private void OnMinScaleChanged(AvaloniaPropertyChangedEventArgs args)
{
var newMinScale = args.GetNewValue<double>();
if (newMinScale > Scale)
{
Scale = newMinScale;
}
if (_image is { })
{
_sourceMinScale = Math.Min(Width * MinScale / _image.Width, Height * MinScale / _image.Height);
}
else
{
_sourceMinScale = MinScale;
}
}
private double GetScaleRatio(double widthRatio, double heightRatio, Stretch stretch) private double GetScaleRatio(double widthRatio, double heightRatio, Stretch stretch)
{ {
return stretch switch return stretch switch
@@ -216,11 +242,11 @@ public class ImageViewer: TemplatedControl
_image.Width = size.Width; _image.Width = size.Width;
_image.Height = size.Height; _image.Height = size.Height;
Scale = GetScaleRatio(width/size.Width, height/size.Height, this.Stretch); Scale = GetScaleRatio(width/size.Width, height/size.Height, this.Stretch);
_minScale = Math.Min(width * defaultMinScale / size.Width, height * defaultMinScale / size.Height); _sourceMinScale = Math.Min(width * MinScale / size.Width, height * MinScale / size.Height);
} }
else else
{ {
_minScale = defaultMinScale; _sourceMinScale = MinScale;
} }
} }
@@ -236,7 +262,7 @@ public class ImageViewer: TemplatedControl
{ {
var scale = Scale; var scale = Scale;
scale /= 1.1; scale /= 1.1;
if (scale < _minScale) scale = _minScale; if (scale < _sourceMinScale) scale = _sourceMinScale;
Scale = scale; Scale = scale;
} }
} }