wpf canvas 移动 缩放

前端

<Canvas x:Name="imageCanvas" 
    Background="Transparent"
    MouseLeftButtonDown="ImageCanvas_MouseLeftButtonDown"
    MouseMove="ImageCanvas_MouseMove"
    MouseLeftButtonUp="ImageCanvas_MouseLeftButtonUp"
    MouseWheel="ImageCanvas_MouseWheel"
    ClipToBounds="True">
    <Image x:Name="imgAnswer" 
           Stretch="Uniform" 
           Source="{Binding Answer.ImgContent}" 
           Visibility="{Binding Answer.ImgContentVisibility}">
        <Image.RenderTransform>
            <MatrixTransform x:Name="imageTransform"/>
        </Image.RenderTransform>
    </Image>
</Canvas>

后台逻辑

    // 状态变量
    private Point _lastMousePosition;
    private bool _isDragging = false;
    private Matrix _matrix = Matrix.Identity;

    // 触摸状态
    private Point? _lastTouchPoint1 = null;
    private Point? _lastTouchPoint2 = null;

    // 缩放限制
    private const double MIN_SCALE = 0.1;
    private const double MAX_SCALE = 10.0;

        #region 鼠标交互

        private void ImageCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (imgAnswer.Visibility != Visibility.Visible || imgAnswer.Source == null)
                return;

            _isDragging = true;
            _lastMousePosition = e.GetPosition(imageCanvas);

            imageCanvas.CaptureMouse();
            imgAnswer.Cursor = Cursors.Hand;
            e.Handled = true;
        }

        private void ImageCanvas_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_isDragging || e.LeftButton != MouseButtonState.Pressed)
                return;

            if (imgAnswer.Visibility != Visibility.Visible || imgAnswer.Source == null)
                return;

            try
            {
                Point currentPosition = e.GetPosition(imageCanvas);
                double deltaX = currentPosition.X - _lastMousePosition.X;
                double deltaY = currentPosition.Y - _lastMousePosition.Y;

                _matrix.OffsetX += deltaX;
                _matrix.OffsetY += deltaY;
                imageTransform.Matrix = _matrix;

                _lastMousePosition = currentPosition;
                e.Handled = true;
            }
            catch
            {
                // 忽略错误
            }
        }

        private double _currentScale = 1.0; // 当前缩放比例

        private void ImageCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            _isDragging = false;
            imageCanvas.ReleaseMouseCapture();
            imgAnswer.Cursor = Cursors.Arrow;
            e.Handled = true;
        }

        private void ImageCanvas_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            // 计算缩放因子(滚轮向上放大,向下缩小)
            double scaleFactor = e.Delta > 0 ? 1.1 : 0.9;
            _currentScale *= scaleFactor;

            // 获取鼠标当前位置(作为缩放中心)
            Point center = e.GetPosition(imageCanvas);

            // 应用缩放变换到所有笔迹
            ApplyScaleToAllStrokes(scaleFactor, center);

            e.Handled = true;
        }
        // 应用缩放
        private void ApplyScaleToAllStrokes(double scaleFactor, Point center)
        {
            // 创建缩放矩阵(以 center 为中心)
            _matrix.Translate(-center.X, -center.Y);  // 平移到原点
            _matrix.Scale(scaleFactor, scaleFactor);  // 缩放
            _matrix.Translate(center.X, center.Y);   // 平移回原中心

            // 应用变换到笔迹
            imageTransform.Matrix = _matrix;
        }
        #endregion

posted @ 2026-03-13 22:05  Hey,Coder!  阅读(2)  评论(0)    收藏  举报