You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过动画修改控件尺寸?需实现类iOS 3D Touch动画效果

UWP实现类似iOS 3D Touch的控件尺寸动画(单独修改宽高)

1. 直接通过Storyboard实现基础宽高动画

你可以用DoubleAnimation分别绑定控件的Width和Height属性,实现独立的尺寸变化,配合指针事件触发动画,模拟3D Touch的按压效果。

XAML示例

<Button x:Name="3DTouchBtn" Content="3D Touch Test" Width="200" Height="80"
        PointerPressed="Btn_PointerPressed" PointerReleased="Btn_PointerReleased">
    <Button.Resources>
        <!-- 按压时的尺寸缩小动画 -->
        <Storyboard x:Name="PressAnimation">
            <DoubleAnimation Storyboard.TargetName="3DTouchBtn"
                             Storyboard.TargetProperty="Width"
                             To="180" Duration="0:0:0.1"
                             EasingFunction="{StaticResource CubicEase}" />
            <DoubleAnimation Storyboard.TargetName="3DTouchBtn"
                             Storyboard.TargetProperty="Height"
                             To="70" Duration="0:0:0.1"
                             EasingFunction="{StaticResource CubicEase}" />
        </Storyboard>
        <!-- 释放时的尺寸恢复动画 -->
        <Storyboard x:Name="ReleaseAnimation">
            <DoubleAnimation Storyboard.TargetName="3DTouchBtn"
                             Storyboard.TargetProperty="Width"
                             To="200" Duration="0:0:0.1"
                             EasingFunction="{StaticResource CubicEase}" />
            <DoubleAnimation Storyboard.TargetName="3DTouchBtn"
                             Storyboard.TargetProperty="Height"
                             To="80" Duration="0:0:0.1"
                             EasingFunction="{StaticResource CubicEase}" />
        </Storyboard>
        <CubicEase x:Key="CubicEase" EasingMode="EaseInOut" />
    </Button.Resources>
</Button>

后台代码

private void Btn_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    PressAnimation.Begin();
}

private void Btn_PointerReleased(object sender, PointerRoutedEventArgs e)
{
    ReleaseAnimation.Begin();
}

2. 自定义Behavior实现可绑定的复用动画

如果要把动画快速绑定到任意控件,避免重复写事件和Storyboard,可以自定义Behavior封装逻辑,直接在XAML中附加到控件上。

步骤1:创建自定义Behavior类

using Microsoft.Xaml.Interactivity;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media.Animation;

public class 3DTouchSizeBehavior : Behavior<FrameworkElement>
{
    // 定义依赖属性,用于设置按压后的目标宽高
    public static readonly DependencyProperty PressedWidthProperty =
        DependencyProperty.Register(nameof(PressedWidth), typeof(double), typeof(3DTouchSizeBehavior), new PropertyMetadata(double.NaN));

    public static readonly DependencyProperty PressedHeightProperty =
        DependencyProperty.Register(nameof(PressedHeight), typeof(double), typeof(3DTouchSizeBehavior), new PropertyMetadata(double.NaN));

    public double PressedWidth
    {
        get => (double)GetValue(PressedWidthProperty);
        set => SetValue(PressedWidthProperty, value);
    }

    public double PressedHeight
    {
        get => (double)GetValue(PressedHeightProperty);
        set => SetValue(PressedHeightProperty, value);
    }

    private Storyboard _pressStoryboard;
    private Storyboard _releaseStoryboard;
    private double _originalWidth;
    private double _originalHeight;

    protected override void OnAttached()
    {
        base.OnAttached();
        // 记录控件原始尺寸
        _originalWidth = AssociatedObject.Width;
        _originalHeight = AssociatedObject.Height;

        // 创建按压、释放动画
        _pressStoryboard = BuildSizeAnimation(PressedWidth, PressedHeight);
        _releaseStoryboard = BuildSizeAnimation(_originalWidth, _originalHeight);

        // 绑定指针事件,处理取消场景防止动画不复位
        AssociatedObject.PointerPressed += OnPointerPressed;
        AssociatedObject.PointerReleased += OnPointerReleased;
        AssociatedObject.PointerCanceled += OnPointerReleased;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        // 解绑事件避免内存泄漏
        AssociatedObject.PointerPressed -= OnPointerPressed;
        AssociatedObject.PointerReleased -= OnPointerReleased;
        AssociatedObject.PointerCanceled -= OnPointerReleased;
    }

    private Storyboard BuildSizeAnimation(double targetWidth, double targetHeight)
    {
        var storyboard = new Storyboard();
        var easing = new CubicEase { EasingMode = EasingMode.EaseInOut };

        if (!double.IsNaN(targetWidth))
        {
            var widthAnim = new DoubleAnimation
            {
                To = targetWidth,
                Duration = TimeSpan.FromMilliseconds(100),
                EasingFunction = easing
            };
            Storyboard.SetTarget(widthAnim, AssociatedObject);
            Storyboard.SetTargetProperty(widthAnim, "Width");
            storyboard.Children.Add(widthAnim);
        }

        if (!double.IsNaN(targetHeight))
        {
            var heightAnim = new DoubleAnimation
            {
                To = targetHeight,
                Duration = TimeSpan.FromMilliseconds(100),
                EasingFunction = easing
            };
            Storyboard.SetTarget(heightAnim, AssociatedObject);
            Storyboard.SetTargetProperty(heightAnim, "Height");
            storyboard.Children.Add(heightAnim);
        }

        return storyboard;
    }

    private void OnPointerPressed(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
    {
        _pressStoryboard.Begin();
    }

    private void OnPointerReleased(object sender, Windows.UI.Xaml.Input.PointerRoutedEventArgs e)
    {
        _releaseStoryboard.Begin();
    }
}

步骤2:在XAML中使用Behavior

先引入命名空间(假设你的Behavior位于YourApp.Behaviors下):

xmlns:behaviors="using:YourApp.Behaviors"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"

然后直接附加到任意控件:

<Button Content="复用3D Touch动画" Width="200" Height="80">
    <interactivity:Interaction.Behaviors>
        <behaviors:3DTouchSizeBehavior PressedWidth="180" PressedHeight="70" />
    </interactivity:Interaction.Behaviors>
</Button>

关键注意点

  • 控件必须设置固定的Width和Height,Auto状态下无法用DoubleAnimation修改尺寸;
  • 调整Duration和EasingFunction可以优化动画手感,比如CubicEase能让动画更自然;
  • 必须处理PointerCanceled事件,防止用户按压后移出控件区域导致动画无法复位。

内容的提问来源于stack exchange,提问作者wxinbang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 09:57:28