2021-04-17

以DoubleAnimationUsingKeyFrames为例,它支持四种Double的关键帧,其中EasingDoubleKeyFrame、LinearDoubleKeyFrame和SplineDoubleKeyFrame可以归类为连续式关键帧,而DiscreteDoubleKeyFrame则是离散式关键帧。

DoubleAnimationUsingKeyFrames包含一个关键帧的集合,动画开始后,每当达到某个关键帧指定的Time,动画的值也会同时到达这个关键帧指定的Value。下面这段XAML介绍了一个典型的LinearDoubleKeyFrame的用法:

 
  1. <StackPanel>

  2. <StackPanel.Resources>

  3. <Storyboard x:Name="myStoryboard">

  4. <DoubleAnimationUsingKeyFrames

  5. Storyboard.TargetName="myRectangle"

  6. Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">

  7. <LinearDoubleKeyFrame Value="1" KeyTime="0:0:0"/>

  8. <LinearDoubleKeyFrame Value="1.2" KeyTime="0:0:4"/>

  9. <LinearDoubleKeyFrame Value="2" KeyTime="0:0:5"/>

  10. </DoubleAnimationUsingKeyFrames>

  11. </Storyboard>

  12. </StackPanel.Resources>

  13. </StackPanel>

对于连续式的关键帧,两个关键帧之间会进行插值,以上面的XAML为例,当动画运行到4.5秒的时候,DobuleAnimationUsingKeyFrames会根据第二和第三个LinearDoubleKeyFrame的值计算出1.6作为内插的值赋予目标属性ScaleY。EasingDoubleKeyFrame和SplineDoubleKeyFrame也是相同的原理,只是它们的插值计算方式复杂一些。

而离散式关键帧不同,它用在不能插值的数据类型, 例如True/False、Visible/Collapsed这些数据类型,它们之间没有过渡,只能用离散的方式设置值。一段典型的DiscreteObjectKeyFrame示例如下:

 
  1. <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HorizontalRoot" Storyboard.TargetProperty="Visibility">

  2. <DiscreteObjectKeyFrame KeyTime="0:0:0">

  3. <DiscreteObjectKeyFrame.Value>

  4. <Visibility>Collapsed</Visibility>

  5. </DiscreteObjectKeyFrame.Value>

  6. </DiscreteObjectKeyFrame>

  7. </ObjectAnimationUsingKeyFrames>

2. 了解下电影的原理

在电影里,一幅静止的图像被称作一“格”(Frame),只要达到每秒24格,人们的眼睛就会被欺骗,以为看到的是运动的画面。人的双眼及其数据传输系统每秒可以识别10-12格画面,大脑的视觉处理中心会将每格画面保留1/15秒。如果在前一格画面尚且保留的1/15秒内大脑又收到一幅新的画面,那么就产生了画面在连续运动的感觉,这是电影得以实现的认知学基础。

3. 用DiscreteDoubleKeyFrame播放动画

DiscreteObjectKeyFrame是最常用的离散式关键帧,UWP还提供了其它三种离散式关键帧:DiscreteColorKeyFrame、DiscreteDoubleKeyFrame和DiscretePointKeyFrame。如果不是追求动画效果,日常工作中DiscreteDoubleKeyFrame基本上没什么作为(在Github上DiscreteObjectKeyFrame有132K的搜索结果,DiscreteDoubleKeyFrame只有17K)。但只要了解了电影的原理,配合设计师的话DiscreteDoubleKeyFrame也可以大展拳脚。

 
  1. <ScrollViewer Background="Transparent"

  2. VerticalScrollBarVisibility="Disabled"

  3. HorizontalScrollBarVisibility="Disabled">

  4. <Grid Width="2900">

  5. <Image Stretch="None"

  6. AutomationProperties.AccessibilityView="Raw"

  7. Source="/Assets/Images/heart.png"

  8. Height="100"

  9. Loaded="OnHeartLoaded"

  10. RenderTransformOrigin="0.5,0.5">

  11. <Image.RenderTransform>

  12. <CompositeTransform />

  13. </Image.RenderTransform>

  14. </Image>

  15. </Grid>

  16. </ScrollViewer>

上面的XAML是一个Like按钮(模仿某个不存在的网站)的ControlTemplate,ScrollViewer用于裁剪超出范围的内容,里面包含一张由29张100 X 100的图片拼接而成的长图片:

 
  1. private Storyboard _checkStoryboard;

  2. private CompositeTransform _heartTransform;

  3.  
  4. private void OnHeartLoaded(object sender, RoutedEventArgs e)

  5. {

  6. _heartTransform = (sender as Image).RenderTransform as CompositeTransform;

  7. _checkStoryboard = new Storyboard();

  8.  
  9.  
  10. var keyFrames = new DoubleAnimationUsingKeyFrames();

  11. Storyboard.SetTarget(keyFrames, _heartTransform);

  12. Storyboard.SetTargetProperty(keyFrames, nameof(CompositeTransform.TranslateX));

  13. TimeSpan start = TimeSpan.Zero;

  14. for (var i = 0; i < 28; i++)

  15. {

  16. var keyFrame = new DiscreteDoubleKeyFrame

  17. {

  18. KeyTime = TimeSpan.FromSeconds((i + 1d) / 28d),

  19. Value = -(i + 1) * 100

  20. };

  21. keyFrames.KeyFrames.Add(keyFrame);

  22. }

  23.  
  24. _checkStoryboard.Children.Add(keyFrames);

  25.  
  26. _checkStoryboard.FillBehavior = FillBehavior.HoldEnd;

  27. }

  28.  
  29. private void OnChecked(object sender, RoutedEventArgs e)

  30. {

  31. _checkStoryboard.Begin();

  32. }

  33.  

在CodeBehind的OnChecked函数中启动一个Storybord,使用DiscreteDoubleKeyFrame让Image在一秒内向左平移100像素,这样就达到了播放动画的效果:

换一张Demo试试,这次使用了12帧每秒,看上去就有点卡顿:

4. 结语

这篇文章的代码在WPF和UWP上的实现几乎一样,有兴趣的话也可以在WPF上试试。

LikeButton的动画抄自Codepen,在CSS中离散动画实现起来很简洁:

 
  1. .heart {

  2. width: 100px;

  3. height: 100px;

  4. background: url("https://cssanimation.rocks/images/posts/steps/heart.png") no-repeat;

  5. background-position: 0 0;

  6. cursor: pointer;

  7. transition: background-position 1s steps(28);

  8. transition-duration: 0s;

  9.  
  10. &.is-active {

  11. transition-duration: 1s;

  12. background-position: -2800px 0;

  13. }

  14. }

更多关于steps的内容可参考下面这篇文章
CSS3 animation属性中的steps功能符深入介绍

5. 参考

情节提要动画 - UWP applications Microsoft Docs

关键帧动画以及缓动函数动画 - UWP applications Microsoft Docs

DiscreteDoubleKeyFrame Class (Windows.UI.Xaml.Media.Animation) - Windows UWP applications Microsoft Docs

6. 源码

design_and_animation_lab

 
  1.  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值