Home > OS >  Morph a shape in WPF
Morph a shape in WPF

Time:02-22

I want to animate the form o a circle into a square. The same way we did it in the flash animations time, but in WPF. I'm open to any suggestion on how to approach it. I do have my path data for the final and initial shapes but I cannot find anything relevant.

My google search only go into the directions of animating a form along a path. This is not what I want, I want my object to stay stationary but change it outline from a circle to a square.

CodePudding user response:

You could animate the RadiusX and RadiusY properties of a Rectangle like this:

<Rectangle Width="100" Height="100" RadiusX="50" RadiusY="50"
           Stroke="Red" StrokeThickness="3">
    <Rectangle.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard BeginTime="0:0:2">
                    <DoubleAnimation 
                        Storyboard.TargetProperty="RadiusX"
                        To="0" Duration="0:0:2"/>
                    <DoubleAnimation 
                        Storyboard.TargetProperty="RadiusY"
                        To="0" Duration="0:0:2"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Rectangle.Triggers>
</Rectangle>

Alternatively, animate the CornerRadius of a Border with a custom animation:

<Border Width="100" Height="100" CornerRadius="50"
        BorderBrush="Red" BorderThickness="3">
    <Border.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard BeginTime="0:0:2">
                    <local:CornerRadiusAnimation 
                        Storyboard.TargetProperty="CornerRadius"
                        To="0" Duration="0:0:2"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Border.Triggers>
</Border>

The CornerRadiusAnimation:

public class CornerRadiusAnimation : AnimationTimeline
{
    public CornerRadius To { get; set; }

    public override Type TargetPropertyType
    {
        get { return typeof(CornerRadius); }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new CornerRadiusAnimation { To = To };
    }

    public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock)
    {
        if (!animationClock.CurrentProgress.HasValue)
        {
            return defaultOriginValue;
        }

        var p = animationClock.CurrentProgress.Value;
        var from = (CornerRadius)defaultOriginValue;

        return new CornerRadius(
            (1 - p) * from.TopLeft   p * To.TopLeft,
            (1 - p) * from.TopRight   p * To.TopRight,
            (1 - p) * from.BottomRight   p * To.BottomRight,
            (1 - p) * from.BottomLeft   p * To.BottomLeft);
    }
}
  • Related