Question

Je dois pouvoir effectuer un zoom avant et arrière sur une toile à l'aide de la molette. J'ai correctement configuré les gestionnaires de molette de la souris et j'utilise actuellement ScaleTransform pour appliquer le zoom. Cependant, la mise à l'échelle n'est pas effectuée de manière "intuitive". façon.

J'essaie d'utiliser le même style de & zoom; zoomer " comme vous pouvez le voir dans MultiScaleImage, Google Maps / Earth ou Adobe Acrobat Reader - mais PAS avec une image, avec un contrôle. La transition n'a pas besoin d'être "lisse". ou animé (sauf s’il s’agit d’une approche plus simple), mais la fonctionnalité doit être identique.

Toute pensée ou idée serait très appréciée et merci d'avance!

Modifier: je suis parvenu à "lisser" le zoom avec animation:

<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>

avec le code suivant:

_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

Toutefois, le problème persiste, à savoir qu'il est en train de faire un zoom arrière dans le coin supérieur gauche, contrairement à des sites tels que Google Maps où le zoom est "autour". la souris.

Était-ce utile?

La solution

Vous devez utiliser une moyenne pondérée comme centre de zoom basé sur la position de la souris. En d'autres termes, conservez le dernier centre de zoom (ou, si vous n'en avez pas encore, réglez-le sur la position actuelle de la souris) et indiquez le nombre de fois où le centre de zoom a été calculé (après le premier zoom, ce serait 1). . Chaque fois que vous recalculez le centre du zoom, incrémentez cette variable.

Exemple de code suivant - deltaZoom correspond au zoom que vous effectuez, à centreX et à centreY au centre du zoom actuel, à ZoomSteps au nombre de fois que nous avons effectué un zoom, et à mouseX et mouseY à la position actuelle de la souris:

_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();

Modifié pour que vous puissiez passer au-dessous du niveau de zoom 1.0 mais qu'il reste des problèmes (ZoomStep = -1, 0 ou 1 provoquent parfois des tremblements étranges).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top