Почему курсор мыши больше не соответствует своему положению на экране?

Я написал этот код уже множество раз, и раньше всё работало без ошибок. Однако сейчас я не могу понять, что именно изменилось и где я мог сделать ошибку. Возможно, там присутствует невидимый текст. У меня возникла проблема: курсор мыши не совпадает с предполагаемой позицией, и, похоже, он "скомкан", хотя на элементе нет никаких трансформаций. <br/> 
<br/>
<pre><code class="cs">private void canvas_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
    { 
        var g = e.Surface.Canvas;
        g.Clear(SKColors.PapayaWhip); 
        var pos = new Vector2((float)cur.X, (float)cur.Y);

        g.DrawCircle(pos, 10, new SKPaint() { Color = SKColors.Red }); 
    }
    Point last;
    Point cur;
    private void canvas_MouseMove(object sender, MouseEventArgs e)
    {
        cur= e.GetPosition(canvas);
      
    }</code></pre>
  • 27 марта 2025 г. 0:34
Ответы на вопрос 2
Проблема, с которой вы столкнулись, может быть связана с тем, как координаты мыши преобразуются и используются для рисования на холсте. Давайте рассмотрим несколько возможных причин, по которым курсор мыши может не соответствовать положению объекта на экране.

1. **Координаты холста и родительского элемента**: Убедитесь, что вы правильно получаете позицию мыши относительно элемента, на котором рисуете. Если ваш холст находится внутри другого контейнера или элемента (например, панель, окно и т. д.), со временем могут возникнуть смещения, особенно если у этих элементов есть отступы или границы. 

   Попробуйте использовать `Point` с учетом координат родителя. Используйте метод `Transform` для обеспечения правильного преобразования координат.

   ```csharp
   var positionRelativeToCanvas = e.GetPosition(canvas);
   cur = new Point(positionRelativeToCanvas.X, positionRelativeToCanvas.Y);
   ```

2. **Кэширование в области рисования**: Убедитесь, что вы обновляете изображение на холсте при каждом движении мыши. Это может означать, что функция `canvas_PaintSurface` не вызывается каждый раз, когда курсор двигается. Вы можете использовать `canvas.InvalidateVisual()` после того, как обновили `cur`, чтобы заставить холст перерисовать себя.

3. **Координаты в различных системах**: Убедитесь, что вы используете правильные системы координат. Например, если вы используете `SkiaSharp`, убедитесь, что у вас нет дополнительных трансформаций, изменяющих расположение объектов на холсте.

4. **Тестирование на других элементах**: Попробуйте изменить рисование на другой элемент, чтобы убедиться, что проблема не в самом холсте `canvas`. Это может помочь исключить конфликты с другими частями вашего кода.

5. **Настройки DPI**: Если вы работаете с высоким разрешением (например, DPI), убедитесь, что координаты мыши также правильно масштабируются.

Вот пример, который включает исправления и условия для диагностики:

```csharp
private void canvas_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintSurfaceEventArgs e)
{
    var g = e.Surface.Canvas;
    g.Clear(SKColors.PapayaWhip);
    
    // Просто для отладки, проверьте значение cur
    Console.WriteLine($"Mouse Position: {cur}");

    var pos = new Vector2((float)cur.X, (float)cur.Y);

    g.DrawCircle(pos, 10, new SKPaint() { Color = SKColors.Red });
}

private void canvas_MouseMove(object sender, MouseEventArgs e)
{
    // Обновите текущую позицию курсора
    cur = e.GetPosition(canvas);

    // Перерисуйте холст
    canvas.InvalidateVisual();
}
```

Если после этих изменений всё еще наблюдается несоответствие в положении курсора, может быть полезно проверить всю цепочку родительских элементов, чтобы убедиться, что их размеры и позиции не влияют на вычисления.
Переключите масштабирование экрана в 100% и проверьте код - всё должно работать как было. В WPF накрутили свои фичи вокруг масштабирования и теперь даже банальное размещение окна в нужной позиции и нужного размера - это цирк с конями на велосипедах, жонглирующими хомяками-акробатами. К сожалению под рукой нет кода, но он легко гуглится по ключевым словам типа WPF DPI real cursor position / real window position .
Похожие вопросы