WPF以鼠标当前位置进行缩放
<Window x:Class="ImageViewer.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:ImageViewer" mc:Ignorable="d" Title="MainWindow" Height="600" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="80"/> </Grid.RowDefinitions> <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"> <Grid Name="grid" Background="White" PreviewMouseLeftButtonDown="img_MouseLeftButtonDown" MouseLeftButtonUp="img_MouseLeftButtonUp" MouseMove="img_MouseMove"> <Image Stretch="None" Name="img" PreviewMouseWheel="Img_MouseWheel" Source="1.png"> <Image.RenderTransform> <TransformGroup x:Name="group"> <ScaleTransform x:Name="mScaleTf" ScaleX="1.0" CenterX="0"/> <TranslateTransform x:Name="mTranslateTf" X="0" Y="0"/> </TransformGroup> </Image.RenderTransform> <Image.LayoutTransform> <RotateTransform x:Name="rotateTransform" ></RotateTransform> </Image.LayoutTransform> </Image> </Grid> </ScrollViewer> <StackPanel Grid.Row="1" Orientation="Horizontal"> <Button x:Name="btnRotate" Click="btnRotate_Click" Margin="15" Width="100">旋转</Button> <Button x:Name="btnOrg" Click="BtnOrg_Click" Margin="15" Width="100">1:1</Button> <Label Name="lbScale" Content="100%" VerticalAlignment="Center"></Label> </StackPanel> </Grid> </Window>
using System; using System.Diagnostics; using System.Windows; using System.Windows.Input; namespace ImageViewer { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { Point oldPt; public MainWindow() { InitializeComponent(); this.Loaded += MainWindow_Loaded; grid.SizeChanged += Grid_SizeChanged; } private void Grid_SizeChanged(object sender, SizeChangedEventArgs e) { } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { } private void Img_MouseWheel(object sender, MouseWheelEventArgs e) { if (e.Delta < 0) { if (mScaleTf.ScaleX <= 0.2) return; } else if (e.Delta > 0) { if (mScaleTf.ScaleX >= 5) return; } Point zoomCenter = e.GetPosition(img); //if (img.ActualHeight * mScaleTf.ScaleY < grid.ActualHeight && img.ActualWidth * mScaleTf.ScaleX < grid.ActualHeight) //{ // zoomCenter.X = img.ActualWidth / 2; // zoomCenter.Y = img.ActualHeight / 2; // img.HorizontalAlignment = HorizontalAlignment.Center; // img.VerticalAlignment = VerticalAlignment.Center; //} double x = zoomCenter.X; double y = zoomCenter.Y; if (rotateTransform.Angle == 90) { zoomCenter.X = img.ActualHeight - zoomCenter.Y; zoomCenter.Y = x; } else if (rotateTransform.Angle == 180) { zoomCenter.X = img.ActualWidth - zoomCenter.X; zoomCenter.Y = img.ActualHeight - zoomCenter.Y; } else if (rotateTransform.Angle == 270) { zoomCenter.X = y; zoomCenter.Y = img.ActualWidth - x; } Point pt = img.RenderTransform.Inverse.Transform(zoomCenter); this.mTranslateTf.X = (zoomCenter.X - pt.X) * this.mScaleTf.ScaleX; this.mTranslateTf.Y = (zoomCenter.Y - pt.Y) * this.mScaleTf.ScaleY; this.mScaleTf.CenterX = zoomCenter.X; this.mScaleTf.CenterY = zoomCenter.Y; if (e.Delta > 0) { this.mScaleTf.ScaleX += 0.1; this.mScaleTf.ScaleY += 0.1; } else { this.mScaleTf.ScaleX -= 0.1; this.mScaleTf.ScaleY -= 0.1; } lbScale.Content = $"{Math.Round(mScaleTf.ScaleX * 100, 0)} %"; //this.mScaleTf.ScaleX += e.Delta / 1500.0; //this.mScaleTf.ScaleY += e.Delta / 1500.0; } private void img_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { oldPt = e.GetPosition(grid); } private void img_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) { oldPt = e.GetPosition(grid); } private void img_MouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { Point pt = e.GetPosition(grid); Point ptImg = e.GetPosition(img); Debug.WriteLine($"Grid:{pt.X}---{pt.Y}"); Debug.WriteLine($"Img:{ptImg.X}---{ptImg.Y}"); //if (pt.X > oldPt.X)//right drag //{ // if (e.GetPosition(img).X * mScaleTf.ScaleX > pt.X) // { // mTranslateTf.X += pt.X - oldPt.X; // } //} //if (pt.Y > oldPt.Y)//down //{ // if (e.GetPosition(img).Y * mScaleTf.ScaleY > pt.Y) // { // mTranslateTf.Y += pt.Y - oldPt.Y; // } //} //if (pt.X < oldPt.X)//left //{ // if ((img.ActualWidth - e.GetPosition(img).X) * mScaleTf.ScaleX > (grid.ActualWidth -pt.X)) // mTranslateTf.X += pt.X - oldPt.X; //} //if (pt.Y < oldPt.Y)//up //{ // if ((img.ActualHeight - e.GetPosition(img).Y) * mScaleTf.ScaleY > (grid.ActualHeight - pt.Y)) // mTranslateTf.Y += pt.Y - oldPt.Y; //} mTranslateTf.X += pt.X - oldPt.X; mTranslateTf.Y += pt.Y - oldPt.Y; oldPt = pt; } } private void btnRotate_Click(object sender, RoutedEventArgs e) { rotateTransform.Angle = (rotateTransform.Angle + 90) % 360; } private void BtnOrg_Click(object sender, RoutedEventArgs e) { rotateTransform.Angle = 0; mScaleTf.ScaleX = 1; mScaleTf.ScaleY = 1; mTranslateTf.X = 0; mTranslateTf.Y = 0; } } }