讲一下
微软爸爸的开发者大会2016又暴了个表达式动画和Windows.UI.Composition的API,好叼的样子。
官方示例库GitHub
目前是懵逼状态,好复杂。脑细胞已经在地府排队了。
(有没有IOS解锁的既视感?)上图的效果是照搬了微软爸爸的代码实现的。示例项目中有一个SurfaceLoader.cs类这玩意完全可以复制到任何项目中使用
提示
当然我这里没有改Package.appxmanifest中SplashScreen图片的背景色,改到和扩展初始屏一致的颜色就没违和感了
这里有个坑爹的问题,在图上的背景色位置多次改颜色编译都不会修改为当前设置的颜色,还是前一次的颜色,得打开Package.appxmanifest在xml中修改,不知道是不是最新的更新导致的,以前没太注意。
不得不吐槽:你说你越更新越回去,简体中文版还在清单中变英文,搞的我都不确定是不是下成英文版了
搞的和以前windows mobile 10 上一样简体中文系统设置一水的英文,
准备
1.需要添加一个内裤:Win2D。
2.把示例中的SurfaceLoader.cs类复制到自己的项目中。
第一步修改过APP.xaml.cs中的OnLaunched方法
if (rootFrame.Content == null)
{//rootFrame.Navigate(typeof(MainPage), e.Arguments);ExtendedSplashScreen ess = new ExtendedSplashScreen(e.SplashScreen);rootFrame.Content = ess;
}
看名字就知道这个是GIF中出现的大概是橘红色的启动屏,就是原来的启动屏的扩展(我无耻的连名字都照搬了
),
然后新建一个ExtendedSplashScreen.xaml页面,后退CS中的代码如下
private Rect _splashImageBounds;public ExtendedSplashScreen(SplashScreen ss){this.InitializeComponent();if (ss != null){_splashImageBounds = ss.ImageLocation;}}private void Page_Loaded(object sender, RoutedEventArgs e){//创建MainPageMainPage mainPage = new MainPage(_splashImageBounds);//导航到MainPagevar rootFrame = Window.Current.Content as Frame;if (rootFrame == null){Window.Current.Content = rootFrame = new Frame();}rootFrame.Content = mainPage;}
现在到了MainPage.cs了然后复制示例代码中
MainPage构造函数
SurfaceLoader.Initialize(ElementCompositionPreview.GetElementVisual(this).Compositor);//显示初始屏幕ShowCustomSplashScreen(imageBounds);
SurfaceLoader.Initialize(ElementCompositionPreview.GetElementVisual(this).Compositor);
这一句必须有,不然下面代码暴异常
CompositionDrawingSurface surface = await SurfaceLoader.LoadFromUri(new Uri("ms-appx:///Assets/SplashScreen.png"));
显示动画
private async void ShowCustomSplashScreen(Rect imageBounds){Compositor compositor = ElementCompositionPreview.GetElementVisual(this).Compositor;Vector2 windowSize = new Vector2((float)Window.Current.Bounds.Width, (float)Window.Current.Bounds.Height);//1.创建ContainerVisual实例填充背景色和图片;//2.设置中心缩放ContainerVisual cv = compositor.CreateContainerVisual();cv.Size = windowSize;cv.CenterPoint = new Vector3(windowSize.X, windowSize.Y, 0) * 0.5f;ElementCompositionPreview.SetElementChildVisual(this,cv);//创建sprite的背景色为APP的主题色SpriteVisual backgroundSprite = compositor.CreateSpriteVisual();backgroundSprite.Size = windowSize;backgroundSprite.Brush = compositor.CreateColorBrush((Application.Current.Resources["日间主色"] as SolidColorBrush).Color);cv.Children.InsertAtBottom(backgroundSprite);//创建包含初始屏图像的sprite的尺寸和位置CompositionDrawingSurface surface = await SurfaceLoader.LoadFromUri(new Uri("ms-appx:///Assets/SplashScreen.png"));SpriteVisual imageSprite = compositor.CreateSpriteVisual();imageSprite.Brush = compositor.CreateSurfaceBrush(surface);imageSprite.Offset = new Vector3((float)imageBounds.X, (float)imageBounds.Y, 0f);imageSprite.Size = new Vector2((float)imageBounds.Width, (float)imageBounds.Height);cv.Children.InsertAtTop(imageSprite);}
隐藏动画
private void HideCustomSplashScreen(){ContainerVisual container = (ContainerVisual)ElementCompositionPreview.GetElementChildVisual(this);Compositor compositor = container.Compositor;// 设置缩放和动画const float ScaleFactor = 20f;TimeSpan duration = TimeSpan.FromMilliseconds(1200);LinearEasingFunction linearEase = compositor.CreateLinearEasingFunction();CubicBezierEasingFunction easeInOut = compositor.CreateCubicBezierEasingFunction(new Vector2(.38f, 0f), new Vector2(.45f, 1f));// 创建淡出动画ScalarKeyFrameAnimation fadeOutAnimation = compositor.CreateScalarKeyFrameAnimation();fadeOutAnimation.InsertKeyFrame(1, 0);fadeOutAnimation.Duration = duration;// Grid的动画Vector2KeyFrameAnimation scaleUpGridAnimation = compositor.CreateVector2KeyFrameAnimation();scaleUpGridAnimation.InsertKeyFrame(0.1f, new Vector2(1 / ScaleFactor, 1 / ScaleFactor));scaleUpGridAnimation.InsertKeyFrame(1, new Vector2(1, 1));scaleUpGridAnimation.Duration = duration;// 初始屏动画Vector2KeyFrameAnimation scaleUpSplashAnimation = compositor.CreateVector2KeyFrameAnimation();scaleUpSplashAnimation.InsertKeyFrame(0, new Vector2(1, 1));scaleUpSplashAnimation.InsertKeyFrame(1, new Vector2(ScaleFactor, ScaleFactor));scaleUpSplashAnimation.Duration = duration;// 设置Grid的中心缩放视觉Visual gridVisual = ElementCompositionPreview.GetElementVisual(MainFrame);gridVisual.Size = new Vector2((float)MainFrame.ActualWidth, (float)MainFrame.ActualHeight);gridVisual.CenterPoint = new Vector3(gridVisual.Size.X, gridVisual.Size.Y, 0) * .5f;// 创建一个视觉组,当改组所有视觉执行完后不再显示CompositionScopedBatch batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);container.StartAnimation("Opacity", fadeOutAnimation);container.StartAnimation("Scale.XY", scaleUpSplashAnimation);gridVisual.StartAnimation("Scale.XY", scaleUpGridAnimation);batch.Completed += Batch_Completed;batch.End();}
动画完成
private void Batch_Completed(object sender, CompositionBatchCompletedEventArgs args){// 动画完成后处理自定义视觉效果ElementCompositionPreview.SetElementChildVisual(this, null);}
mainPage加载完成
private void Page_Loaded(object sender, RoutedEventArgs e){MainFrame.Navigate(typeof(HomePage));HideCustomSplashScreen();}
最后这个叫Widonw UI Dev Labs的示例
SurfaceLoader.cs
哈哈又水了一波