Как анимировать изменение масштаба изображения в WPF? - PullRequest
2 голосов
/ 15 сентября 2011

Я создаю просмотрщик изображений.

Я создал функцию, которая, когда пользователь перемещает ползунок, изменяет значение свойства ZoomLevel. Это впоследствии увеличивает изображение на основе значения, предоставленного свойством ZoomLevel.

<Image 
    Name="image"
    Source="Sample1.jpg"
    Opacity="1" 
    VerticalAlignment="Center"
    HorizontalAlignment="Center"
    Stretch="None"
    RenderTransformOrigin="0.5,0.5" 
    RenderOptions.BitmapScalingMode="HighQuality">
    <Image.RenderTransform>
        <TransformGroup>
            <ScaleTransform 
                ScaleX="{Binding Path=ZoomLevel}" 
                ScaleY="{Binding Path=ZoomLevel}" />
            <TranslateTransform />
        </TransformGroup>
    </Image.RenderTransform>
</Image>

Я хочу иметь возможность анимировать масштабирование с помощью DoubleAnimation. Предполагается, что анимация начинается с текущего уровня масштабирования, а затем достигает масштаба, указанного в свойстве bound ZoomLevel. Было бы здорово, если бы кто-то мог оказать некоторую помощь в XAML. Спасибо!

Код колеса мыши:

private void border_MouseWheel(object sender, MouseWheelEventArgs e)
{
    int delta;

    delta = e.Delta;
    zoom(delta);
}

private void zoom(int delta)
{
    double zoomIncrement;

    //Different zoom levels at different zoom stages
    if (ZoomLevel > 2)
    {
        zoomIncrement = Math.Sign(delta) * 0.2;
    }
    else if (ZoomLevel >= 1 && ZoomLevel <= 2)
    {
        zoomIncrement = Math.Sign(delta) * 0.1;
    }
    else
    {
        zoomIncrement = Math.Sign(delta) * 0.06;
    }

    //Rounding zoom level to boundary values
    //Zooming is allowed from 10% to 600%
    if (ZoomLevel + zoomIncrement > 6)
    {
        ZoomLevel = 6;
    }
    else if (ZoomLevel + zoomIncrement < 0.1)
    {
        ZoomLevel = 0.1;
    }
    else
    {
        ZoomLevel += zoomIncrement;
    }
}

Ответы [ 2 ]

2 голосов
/ 16 сентября 2011

Это немного грязно, но попробуйте это.

namespace Zoom
{

    public partial class Window1
    {   
        public double ZoomLevel { get; set; }
        public double SlideLevel { get; set; }

        public Window1()
        {
            InitializeComponent();

            ZoomLevel = 1.0;
            SlideLevel = 1.0;
            image.MouseWheel += image_MouseWheel;

        }

        private void image_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            double zoom = e.Delta > 0 ? .1 : -.1;
            slider.Value = (SlideLevel + zoom);
        }

        private void ZoomImage(double zoom)
        {
            Storyboard storyboardh = new Storyboard();
            Storyboard storyboardv = new Storyboard();

            ScaleTransform scale = new ScaleTransform(ZoomLevel, ZoomLevel);
            image.RenderTransformOrigin = new Point(0.5, 0.5);
            image.RenderTransform = scale;

            double startNum = ZoomLevel;
            double endNum = (ZoomLevel += zoom);

            if (endNum > 1.0)
            {
                endNum = 1.0;
                ZoomLevel = 1.0;
            }

            DoubleAnimation growAnimation = new DoubleAnimation();
            growAnimation.Duration = TimeSpan.FromMilliseconds(300);
            growAnimation.From = startNum;
            growAnimation.To = endNum;
            storyboardh.Children.Add(growAnimation);
            storyboardv.Children.Add(growAnimation);

            Storyboard.SetTargetProperty(growAnimation, new PropertyPath("RenderTransform.ScaleX"));
            Storyboard.SetTarget(growAnimation, image);
            storyboardh.Begin();

            Storyboard.SetTargetProperty(growAnimation, new PropertyPath("RenderTransform.ScaleY"));
            Storyboard.SetTarget(growAnimation, image);
            storyboardv.Begin();
        }

        private void slider_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
        {
            double zoomChange = (SlideLevel - slider.Value) * -1;
            SlideLevel = SlideLevel + zoomChange;

            ZoomImage(zoomChange);
        }
    }
}

Я нашел этот другой вопрос о стеке весьма полезным

Вот текущая настройка XAML, которая у меня есть.

    <Border MaxWidth="500"
        MaxHeight="500"
        Height="500"
        Width="500"
        Name="border">
    <Image
        Name="image"
        Source="picture1.png"
        Opacity="1"
        VerticalAlignment="Center"
        HorizontalAlignment="Center"
        Stretch="Fill"
        RenderTransformOrigin="0.5,0.5"
        RenderOptions.BitmapScalingMode="HighQuality"
        ClipToBounds="True">
    </Image>
    </Border>
    <Slider
        HorizontalAlignment="Left"
        Margin="44,70,0,148"
        Name="slider"
        Width="24"
        Value="1.0"
        Minimum="0"
        Maximum="1.0"
        LargeChange="0.1"
        Orientation="Vertical"
        FlowDirection="LeftToRight"
        TickFrequency="0.1"
        IsSnapToTickEnabled="False"
        ValueChanged="slider_ValueChanged" />
1 голос
/ 16 сентября 2011

Вы пытались использовать ViewBox? Вы можете привязать конечную ширину к любому значению, которое вам нужно, вот быстрый пример:

<Window.Resources>
    <Storyboard x:Key="ZoomIn">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="ImageContainer">
            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="400"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</Window.Resources>

<Grid x:Name="LayoutRoot">
    <Viewbox x:Name="ImageContainer" Width="200">
        <Image Source="http://images.wikia.com/lossimpson/es/images/a/a7/Homer_Simpson2.png"/>
    </Viewbox>
</Grid>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...