微博上有同学问我MyerSplash是如何实现那个很炫的图片点亮,然后移动到屏幕中央的效果。惭愧啊,我又不是作者哪里会知道。硬着头皮去GitHub拜读了高手的代码,自愧弗如,比我不知道高到哪里去了……这时我就面临一个艰难的抉择,要么就写个几十篇来分析一下MyerSplash(万一分析错了好丢人……),要么就说看不懂(貌似也很丢人……)。

  幸亏我临机一动,决定山寨一个极简版,做一点微小的工作,顺便写一篇博客蹭点热度,给某软,给UWP续一秒……

  首先要明确我们希望以少量的代码来模拟MyerSplash的部分效果,较少的代码分析起来更为易懂,所以各位同学就不要抱怨说这个是五毛钱特效……

  

    <ListView ItemsSource="{Binding Photos,Mode=OneTime}" ItemContainerStyle="{StaticResource photoItemContainerStyle}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"></ItemsWrapGrid>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageUri,Mode=OneTime}" Stretch="UniformToFill" IsTapEnabled="True" Tapped="Image_Tapped"></Image>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

  上面的XAML绘制了一个根据元素数量自动换行的列表,列表中的Item元素就是单纯的Image,同时Item元素响应一个Tapped事件(这个我们后面说)。

  

  可以看到鼠标移动时,会有一个动画,0.5秒的渐变点亮同时图片放大的效果(生成的这个gif图比较渣,实际效果请运行代码)。这是通过自定义ItemContainerStyle并在其中添加VisualStateManager来实现的。

        <Style x:Key="photoItemContainerStyle" TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<DoubleAnimation Duration="0:0:0.5" From="0.5" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="contentPhoto" ></DoubleAnimation>
<DoubleAnimation Duration="0:0:0.5" From="1" To="1.2" Storyboard.TargetProperty="ScaleX" Storyboard.TargetName="scaleGrid" ></DoubleAnimation>
<DoubleAnimation Duration="0:0:0.5" From="1" To="1.2" Storyboard.TargetProperty="ScaleY" Storyboard.TargetName="scaleGrid" ></DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups> <Grid.Clip>
<RectangleGeometry Rect="0 0 200 200"/>
</Grid.Clip> <Grid Background="Black">
<ContentPresenter x:Name="contentPhoto" Width="200" Height="200" Opacity="0.5">
<ContentPresenter.RenderTransform>
<ScaleTransform x:Name="scaleGrid" ScaleX="1.0" ScaleY="1.0" CenterX="100" CenterY="100"></ScaleTransform>
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>

  在 <VisualState x:Name="PointerOver">这个状态我们通过Storyboard播放了三个Animation来改变图片的透明度,以及长宽。透明度从0.5变化至1时,图片不再透明,背景黑色Grid不再可见,模拟高亮效果。同时通过Clip将放大后图片的外缘裁剪仍保持原始大小。

  貌似已经做的差不多了……至少你已经学会如何山寨照片墙了。接下来我们要做点不一样的,换一种方式来使用Storyboard和Animation,点击图片放大并移动到屏幕中央的功能,我打算通过C#代码实现(话说这部分有点坑,写得时候搞死我了……)

  浮动显示的图片我们采用Popup来显示,通过给Popup添加Child,并通过storyboard和animation来改变Width,Height属性控制图片大小的变化。图片的位移则是将Popup的RenderTransform属性设置为TranslateTransform,然后改变X轴和Y轴坐标来实现。

  这里需要注意Animation对象的EnableDependentAnimation属性,这个坑爹的属性是 Windows Runtime 8.1新增的,如果你发现自定义的Animation不能播放,又找不到任何错误,那就需要把这个属性值置为true。

        private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
popup.IsOpen = false; var tappedImage = e.OriginalSource as Image;
var image = new Image { Source = tappedImage.Source };
popup.Child = image;
popup.IsOpen = true; //获取被点击图片相对MainPage的坐标
var position = tappedImage.TransformToVisual(this).TransformPoint(new Point());
//获取MainPage的中心坐标
var xCenter = ActualWidth / - ;
var yCenter = ActualHeight / - ; var storyBoard = new Storyboard();
var extendAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.5)), From = , To = , EnableDependentAnimation = true };
Storyboard.SetTarget(extendAnimation, image);
Storyboard.SetTargetProperty(extendAnimation, "Width");
Storyboard.SetTargetProperty(extendAnimation, "Height"); var xAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.5)), From = position.X, To = xCenter, EnableDependentAnimation = true };
Storyboard.SetTarget(xAnimation, popup);
Storyboard.SetTargetProperty(xAnimation, "(UIElement.RenderTransform).(TranslateTransform.X)"); var yAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromSeconds(0.5)), From = position.Y, To = yCenter, EnableDependentAnimation = true };
Storyboard.SetTarget(yAnimation, popup);
Storyboard.SetTargetProperty(yAnimation, "(UIElement.RenderTransform).(TranslateTransform.Y)"); storyBoard.Children.Add(extendAnimation);
storyBoard.Children.Add(xAnimation);
storyBoard.Children.Add(yAnimation); storyBoard.Begin();
}

  补充下Popup的定义,记得要设置popup.RenderTransform = TranslateTransform(),默认可是null

    public sealed partial class MainPage : Page
{
public List<PhotoModel> Photos { get; set; } private Popup popup = new Popup(); public MainPage()
{
this.InitializeComponent();
Photos = CreatePhotos();
this.DataContext = this;
popup.RenderTransform = new TranslateTransform();
}

  总体就这么些了,大约100行左右的代码,直接拿去卖钱肯定是不行的。作为Demo演示给吃瓜群众,或者忽悠BOSS还是可以的。如果需要用到产品中,去GayHub下载代码自己改吧改吧,调调UI。

  有问题新浪微博@楼上那个蜀黍,免费咨询,当然质量也是免费的程度……

  GitHub:

  https://github.com/manupstairs/UWPSamples/tree/master/UWPSamples/StoryboardSample

UWP开发入门(二十二)——Storyboard和Animation的更多相关文章

  1. UWP开发入门(十二)——神器Live Visual Tree

    很久以前,我们就有Snoop这样的工具实时修改.查看正在运行的WPF程序,那时候调个样式,修改个模板,相当滋润.随着历史的车轮陷进WP的泥潭中,无论WP7的Silverlight还是WP8.1的run ...

  2. UWP开发入门(十)——通过继承来扩展ListView

    本篇之所以起这样一个名字,是因为重点并非如何自定义控件,不涉及创建CustomControl和UserControl使用的Template和XAML概念.而是通过继承的方法来扩展一个现有的类,在继承的 ...

  3. UWP开发入门(十六)——常见的内存泄漏的原因

    本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)——用Diagnostic Tool检查内存泄漏>中提到过,即使有 ...

  4. UWP开发入门(十九)——10分钟学会在VS2015中使用Git

    写程序必然需要版本控制,哪怕是个人项目也是必须的.我们在开发UWP APP的时候,VS2015默认提供了对微软TFS和Git的支持.考虑到现在Git很火,作为微软系的程序员也不得不学一点防身,以免被开 ...

  5. UWP开发入门(十八)——使用ContentControl减少页面元素数量

    我们今天学习一下ContentControl,主要介绍如何使用ContentControl搭配DataTemplate来进行界面的复用,以及通过ContentTemplateSelector进一步减少 ...

  6. UWP开发入门(十五)——在FlipView中通过手势操作图片

    本篇的最终目的,是模拟系统的照片APP可以左右滑动,缩放图片的操作.在实现的过程中,我们会逐步分析UWP编写UI的一些思路和技巧. 首先我们先实现一个横向的可以浏览图片的功能,也是大部分APP中的实现 ...

  7. UWP开发入门(十四)—— UserControl中Adaptive UI的小技巧

    本篇我们通过绘制一个非常简单的UserControl控件,来分享一下对Adaptive UI的理解及一些图形绘制的技巧. 现在流行的APP都少不了精致的用户头像,首先假设我们需要绘制如下的图形作为默认 ...

  8. UWP入门(十二)--数据绑定用法

    原文:UWP入门(十二)--数据绑定用法 主要几个元素: Template DataTemplate ItemSource 数据绑定是一个数据提取的方法,能使数据和UI上的控件紧密相连,下面的Demo ...

  9. Web 前端开发精华文章推荐(HTML5、CSS3、jQuery)【系列二十二】

    <Web 前端开发精华文章推荐>2014年第一期(总第二十二期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML ...

  10. Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明

    紧接上一篇<Senparc.Weixin.MP SDK 微信公众平台开发教程(十一):高级接口说明>,这里专讲OAuth2.0. 理解OAuth2.0 首先我们通过一张图片来了解一下OAu ...

随机推荐

  1. Mysql常用表操作 | 单表查询

    160905 常用表操作 1. mysql -u root -p 回车 输入密码   2. 显示数据库列表 show databases     3. 进入某数据库 use database data ...

  2. Ubuntu Server无线连接配置

    由于Ubuntu  Linux内核对于WPA的加密方式支持不是很好,所有使用普通方式的命令行无法连接WPA2类型的路由.首先检查是否安装了wpasupplicant,Ubuntu 10.04已经安装了 ...

  3. Android_SQLite数据库增删改查操作

    一:什么是SQLite? 在Android平台上,集成了一个嵌入式关系型轻量级的数据库. 二:什么时候用的数据库? 有大量相似机构的数据需要存储时. 三:如何创建一个数据库? 1.创建一个Sqlite ...

  4. Tomcat 中响应头信息(Http Response Header) Content-Length 和 Transfer-Encoding

    户端(PC浏览器或者手机浏览器)在接受到Tomcat的响应的时候,头信息通常都会带上Content-Length ,一般情况下客户端会在接受完Content-Length长度的数据之后才会开始解析.而 ...

  5. JAVA第五次作业

    import javax.media.; import java.awt.; import java.awt.event.; class MediaPlayer extends Frame imple ...

  6. 春节前最后一篇,CRUD码农专用福利:PDF.NET之SOD Version 5.1.0 开源发布(兼更名)

    废话不多说,直接入正题,明天赶着坐火车回老家过年. 从2013.10.1日起,原PDF.NET将更名为 SOD :- one SQL-MAP,ORM,Data Control framework 原P ...

  7. UI控件(UIPickerView)

    @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; _item1 = [[NSArray alloc]i ...

  8. Google分布式构建软件之二:构建系统如何工作

    分布式软件构建第二部分:构建系统如何工作 注:本文英文原文在google开发者工具组的博客上[需要FQ],以下是我的翻译,欢迎转载,但请尊重作者版权,注名原文地址. 上篇文章中提到了在Google,所 ...

  9. EF:split your EDMX file into multiple diagrams

    我们可以把一个EDMX文件划分为多个类图: 1.在VS中打开EDMX设计器: 2.切换到“模型浏览器”属性设置窗口: 3.在diagrams上右键菜单中选择“添加新的关系图”: 4.在原来的关系图上可 ...

  10. Hadoop 裡的 fsck 指令

    Hadoop 裡的 fsck 指令,可檢查 HDFS 裡的檔案 (file),是否有 corrupt (毀損) 或資料遺失,並產生 HDFS 檔案系統的整體健康報告.報告內容,包括:Total blo ...