Domanda

Devo essere in grado di ingrandire e ridurre una tela utilizzando la rotellina del mouse. Ho impostato con successo i gestori della rotellina del mouse e attualmente sto usando un ScaleTransform per applicare lo zoom; tuttavia, il ridimensionamento non viene eseguito in un "intuitivo" modo.

Sto cercando di ottenere lo stesso stile di " zoom " come puoi vedere in MultiScaleImage, Google Maps / Earth o Adobe Acrobat Reader, ma NON con un'immagine, con un controllo. Non è necessario che la transizione sia "liscia". o animato (a meno che non sia un approccio più semplice), ma la funzionalità deve essere la stessa.

Qualsiasi pensiero o idea sarebbe molto apprezzato e grazie in anticipo!

Modifica: sono riuscito a " smooth " lo zoom usando l'animazione:

<Canvas.Resources>
            <Storyboard x:Name="ZoomStoryboard">
                <DoubleAnimation x:Name="ZoomAnimationX"
                                 Storyboard.TargetName="Workspace"
                                 Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleX"
                                 Duration="0:0:0.2"/>
                <DoubleAnimation x:Name="ZoomAnimationY"
                                 Storyboard.TargetName="Workspace"
                                 Storyboard.TargetProperty="Canvas.RenderTransform.ScaleTransform.ScaleY"
                                 Duration="0:0:0.2"/>
            </Storyboard>
        </Canvas.Resources>

con il seguente codice:

_Zoom += (args.Delta / 7);
if (_Zoom < 0.15)
    _Zoom = 0.15;
ZoomAnimationX.To = _Zoom;
ZoomAnimationY.To = _Zoom;
ZoomStoryboard.Begin();
ZoomScale.Text = _Zoom.ToString("0.00") + "x";
_PreviousMousePosition = _CurrentMousePosition

Tuttavia, il problema si pone ancora quando si sta ingrandendo l'angolo in alto a sinistra, al contrario di siti come Google Maps in cui lo zoom è "attorno a". il topo.

È stato utile?

Soluzione

È necessario utilizzare una media ponderata come centro dello zoom in base alla posizione del mouse. In altre parole, mantieni l'ultimo centro di zoom (o se non ne hai ancora uno impostato sulla posizione corrente del mouse) e mantieni il numero di volte in cui il centro di zoom è stato calcolato (dopo il primo zoom, sarebbe 1) . Ogni volta che ricalcoli il centro dello zoom, incrementa quella var.

Segue un esempio di codice: deltaZoom indica quanto stai ingrandendo, centerX e centerY sono il centro di zoom corrente, ZoomSteps è il numero di volte che abbiamo ingrandito e mouseX e mouseY sono la posizione corrente del mouse:

_Zoom += deltaZoom;
        if (_Zoom <= 0)
            _Zoom = 0.1;

        if (deltaZoom >= 0)
        {
            if (_ZoomSteps == -1)
            {
                _CenterX = 0;
                _CenterY = 0;
                _ZoomSteps = 0;
            }
            else
            {
                _CenterX = (_CenterX * Math.Abs(_ZoomSteps) + mouseX) / (Math.Abs(_ZoomSteps + 1));
                _CenterY = (_CenterY * Math.Abs(_ZoomSteps) + mouseY) / (Math.Abs(_ZoomSteps + 1));
                _ZoomSteps++;
            }
        }
        else
        {
            if (_ZoomSteps == 1)
            {
                _CenterX = 0;
                _CenterY = 0;
                _ZoomSteps = 0;
            }
            else
            {
                _CenterX = (_CenterX * Math.Abs(_ZoomSteps) - mouseX) / (Math.Abs(_ZoomSteps - 1));
                _CenterY = (_CenterY * Math.Abs(_ZoomSteps) - mouseY) / (Math.Abs(_ZoomSteps - 1));
                _ZoomSteps--;
            }
        }

        ZoomAnimationX.To = _Zoom;
        ZoomAnimationY.To = _Zoom;
        CenterAnimationX.To = Math.Abs(_CenterX);
        CenterAnimationY.To = Math.Abs(_CenterY);
        ZoomStoryboard.Begin();

Modificato in modo da poter scendere al di sotto del livello di zoom 1,0 ma ci sono ancora alcuni problemi (ZoomStep = -1, 0 o 1 a volte causano strane vibrazioni).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top