在 WPF 中变形形状

Morph a shape in WPF

我想将圆圈动画化为正方形。与我们在 Flash 动画时代采用的方式相同,但在 WPF 中。 我愿意接受有关如何处理它的任何建议。我确实有最终和初始形状的路径数据,但我找不到任何相关信息。

我的 google 搜索只涉及沿路径为表单设置动画的方向。这不是我想要的,我希望我的对象保持静止但将其轮廓从圆形更改为正方形。

您可以像这样为矩形的 RadiusXRadiusY 属性设置动画:

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

或者,使用自定义动画为边框 CornerRadius 设置动画:

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

角半径动画:

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);
    }
}