Реализуйте увеличение как в Expression Blend - PullRequest
1 голос
/ 17 января 2012

В Expression Blend, когда вы прокручиваете колесо мыши, элементы на экране увеличиваются / уменьшаются, фокусируясь на положении мыши.

Я пытаюсь реализовать идентичный зум в моем собственном проекте, однако у меня возникают проблемы с его перепрыгиванием после масштабирования, перемещением мыши и последующим масштабированием.

Пока что я использую RenderTransform с ScaleTransform, используя координаты мыши в качестве centerX и centerY для ScaleTransform.

Кто-нибудь знает, как они это сделали в Expression Blend?

Это то, что я сделал до сих пор:

    private void ScrollCanvasMouseWheel(object sender, MouseWheelEventArgs e)
    {
        double zoomAmnt = e.Delta > 0 ? 0.2 : -0.2;
        _scaleTransformAmount += zoomAmnt;

        if (_scaleTransformAmount < 0.5)
            _scaleTransformAmount = 0.5;

        Point position = e.GetPosition(ScrollCanvas);

        var scaleTransform = ScrollCanvas.RenderTransform as ScaleTransform;
        if (scaleTransform == null) throw new ArgumentNullException("scaleTransform");

        scaleTransform.ScaleX = _scaleTransformAmount;
        scaleTransform.ScaleY = _scaleTransformAmount;
        scaleTransform.CenterX = position.X;
        scaleTransform.CenterY = position.Y;
    }

1 Ответ

2 голосов
/ 17 января 2012

Такой масштаб хорош, поэтому я попытался реализовать его один раз, математика немного странная, у меня ушло около двух дней, чтобы понять, что сработало, хотя это может быть довольно уродливый код (переменные с _ - это поля в элементе управления масштабированием):

Point cursorPos = e.GetPosition(this);
Point newCenter = _scaleT.Inverse.Transform(_translateT.Inverse.Transform(cursorPos));
Point oldCenter = new Point(_scaleT.CenterX, _scaleT.CenterY);
Vector oldToNewCenter = newCenter - oldCenter;
_scaleT.CenterX = newCenter.X;
_scaleT.CenterY = newCenter.Y;
_translateT.X += oldToNewCenter.X * (_scaleT.ScaleX - 1.0);
_translateT.Y += oldToNewCenter.Y * (_scaleT.ScaleY - 1.0);

_scalingAnimation.From = _scaleT.ScaleX;
if (e.Delta > 0)
{
    _scalingAnimation.To = _scaleT.ScaleX * ZoomScaleChangeFactor;
}
else
{
    _scalingAnimation.To = _scaleT.ScaleX / ZoomScaleChangeFactor;
}
_scaleT.BeginAnimation(ScaleTransform.ScaleXProperty, _scalingAnimation);
_scaleT.BeginAnimation(ScaleTransform.ScaleYProperty, _scalingAnimation);

this.ReleaseMouseCapture();

Порядок преобразований, конечно, важен:

TransformGroup tGroup = new TransformGroup();
tGroup.Children.Add(_scaleT);
tGroup.Children.Add(_translateT);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...