春节快乐
Hi,
各位园主和博客园的工作人员们,先预祝大家春节快乐!
想任性地给大家送一份春节的礼物,但是我们程序员没多少钱,真是送不起啊,可我们有技术啊,于是我们特地用飞快的速度制作了一个“微软对联”App,2月10日在Windows Phone Store上线了。
link在这里,请大家下载后娱乐一下:
与别的对联App不同的是,由于在后台有微软MSRA的电脑对联系统的技术支持,用户可以自己拟定上联,然后让电脑给你出一些下联的建议,你可以做进一步的修改,然后再让电脑给你出一些横批的建议,你当然还可以修改,最后出一幅令自己满意的对联!
下面简单介绍一下这个App的开发过程,供大家参考。
主页
主页上有四个动画,可以先声夺人地让用户眼前一亮,自然会对你的App产生好感。
第一个动画:福字在中央从小到大360度旋转着出现,动画定义如下:
<Storyboard x:Name="sb_FuRotate"> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" From="0" To="360" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" From="0" To="1" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" From="0" To="1" Duration="0:0:1"/> </Storyboard>
这是三个小动画的组合:
1)做360度平面旋转
2)X轴拉伸,从0到1,也就是从无到原始大小
3)Y轴拉伸,从0到1
第二个动画:五个菜单从左侧顺序飞入,动画定义如下:
<Storyboard x:Name="sb_MenuFlyIn" Completed="sb_Fly_Completed"> <DoubleAnimation Storyboard.TargetName="menu1" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="-250" To="0" Duration="0:0:0.20"/> <DoubleAnimation Storyboard.TargetName="menu2" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="-250" To="0" Duration="0:0:0.20" BeginTime="0:0:0.10"/> <DoubleAnimation Storyboard.TargetName="menu3" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="-250" To="0" Duration="0:0:0.20" BeginTime="0:0:0.20"/> <DoubleAnimation Storyboard.TargetName="menu4" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="-250" To="0" Duration="0:0:0.20" BeginTime="0:0:0.30"/> <DoubleAnimation Storyboard.TargetName="menu5" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="-250" To="0" Duration="0:0:0.20" BeginTime="0:0:0.40"/> </Storyboard>
每个子动画的参数都一样,都是从-250的位置,也就是页面左侧外部,在X轴(横向)进入页面。但是如果一起进入效果不好,所以做了一个时间差,从第二个菜单开始,用BeginTime=”0:0:0.10”设置了一个延迟,也就是每隔10毫秒,飞入一个菜单。
第三个动画:福字从中央的位置飞到页面右下角,并作为Setting Page的入口可以点击,动画定义如下:
<Storyboard x:Name="sb_FuMoveDown" Completed="sb_FuMoveDown_Completed"> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" From="0" To="540" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)" From="1" To="0.2" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleY)" From="1" To="0.2" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" From="0" To="100" Duration="0:0:1"/> <DoubleAnimation Storyboard.TargetName="img_Fu" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" From="0" To="100" Duration="0:0:1"/> </Storyboard>
也是一些子动画的组合。
1)福字平面旋转540度,最后是倒着的
2)在X轴拉伸到原尺寸的0.2
3)在Y轴拉伸到原尺寸的0.2
4)在X轴横向移动一些距离
5)在Y轴竖向移动一些距离
在XAML中,虽然定义了移动的距离是100,但是考虑到不同手机的屏幕大小不一样,所以需要用code实际算一下:
DoubleAnimation da1 = this.sb_FuMoveDown.Children[3] as DoubleAnimation; da1.To = this.ActualWidth / 2 - 60; DoubleAnimation da2 = this.sb_FuMoveDown.Children[4] as DoubleAnimation; da2.To = this.ActualHeight / 2 - 50; this.sb_FuMoveDown.Begin();
首先获得实际的屏幕宽度,除以2再减去60,也就是从中间向右移动距离右边60个像素的位置,Y方向同理,然后再执行动画。
第四个动画比较简单,就是“微软对联”4个字总上部飞下来:
<Storyboard x:Name="sb_TitleFlyIn"> <DoubleAnimation Storyboard.TargetName="tb_Title" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)" From="-400" To="0" Duration="0:0:1"/> </Storyboard>
这种“飞入”,要在屏幕上先定义好最终的位置,然后用-400来定义起飞的位置,终点位置一定是0。
写对联
写对联一共有3页,拟上联,对下联,题横批:
拟上联,首先预定义一些羊年的吉祥话在本地文件里,用JSON格式,页面显示时绑定在ListView上就可以了。注意ListView一定要放在Grid里,如果放在StackPanel里,ListView在屏幕外的部分会把StackPanel拉长,从而造成ListView在屏幕外的部分始终看不到。
对下联,后台调用了MSRA提供的API,自动生成一些建议。
题横批,也是调用了API,自动生成4字横批。
效果页
效果页的制作比较复杂。
这张图是5个字的例子,但是对联允许1-10个字,所以在10个字时,字号要缩小到刚好充满屏幕高度的值,才能使整个效果完美。而且TextBlock里不能竖着写字,用折行也不好控制左右边距,因此我们使用了最原始的方法,一个字一个字的拼上去:
for (int i = 0; i < this.favCouplet.shanglian.Length; i++) { CharControl cc = new CharControl(); cc.DataContext = this.favCouplet.shanglian[i]; cc.FontFamily = this.favCouplet.Font; cc.Foreground = this.favCouplet.Color; this.sp_Left.Children.Add(cc); float scaleValueL = float.Parse((this.scrollLeft.ActualHeight / sp_Left.ActualHeight > this.scrollLeft.ActualWidth / sp_Left.ActualWidth ? this.scrollLeft.ActualWidth / sp_Left.ActualWidth : this.scrollLeft.ActualHeight / sp_Left.ActualHeight).ToString()); this.scrollLeft.ChangeView(null, null, scaleValueL); }
但是要同时保证外边框完整,所以把外边框分成了3个图片元素:
中间的那个可以随着字数任意扩展数量,两头的图片最后拼接上去即可。
搞好整体效果后,可以通过5种方式分享给朋友们:短信,邮件,微博,图片(可供微信分享),云端。
可选效果
底板变成了木纹,红色纸张也变了另一个样子,是通过改Style实现的。福字是可以点击的,点一次旋转180度,可正可倒。
字体
我们使用了3种字体:普通等线字体,姑且叫黑体吧;楷体;隶书。后两种字体在WP中没有,你可以从Windows的ControlPanel->Font中把楷体字体文件拷贝下来,作为Assets的一部分放在资源中,然后当你编辑TextBlock时,会在Text的Font中,最上面,多出一种字体,就是楷体:
我们为什么没有使用书法体从而使对联更有手写感呢?因为书法体是要买的,有知识产权。咱们要注意素质。
云端对联
你写好的对联,如果特满意,可以上传到云端;同时你也可以从云端下载其它人的得意之作,乱改一气,作为自己的作品。点击云端对联可以直接进入效果页。
好吧,先写到这里,一会儿收拾收拾回家了。别忘了下载我们的春联App哟!
MSRA的网页版对联在这里:http://couplet.msra.cn/
祝大家春节快乐!