3D 穿梭效果?使用 UWP 也能搞定
昨天 ChokCoco 大佬搞了个 3D 穿梭效果出来,具体可见这里:
这个效果太神奇了,他还问我能不能用 WPF 搞出来,因为我完全没用过 WPF 的 3D,我第一反应是“这太难为我了”。
晚上回家吃饭溜娃打打帝国时代 4,突然想起我很久没有宠幸 UWP 了。一股“吾有上将 UWP,可搞定 3D 穿梭效果”的豪气油然而生。
于是就把这动画效果造出来了。
总的来说,实现 3D 穿梭的原理是靠改变 CSS 中的 perspective 产生透视效果。perspective指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。它的值越小,视角越深。

perspective 的具体用法可见此文档:
perspective - CSS(层叠样式表) _ MDN
与之对应,UWP 中提供了 PerspectiveTransform3D 类,它的 Depth 属性 也有类似的效果,当 Depth 越小,视觉越深,与平面相交的对象就越变形:

了解原理后马上开工。首先在 Xaml 中将 Grid 的大小写死为 300,然后将 PerspectiveTransform3D 的 Depth 设得很小:
<Grid Height="300" Width="300">
<Grid.Transform3D>
<media3D:PerspectiveTransform3D Depth="2" />
</Grid.Transform3D>
然后从 ChokCoco 大佬那里搞到张星空图片,放在 Grid 里:

然后将 CompositeTransform3D 的 RotationY 设为 -90,这时候图片就扭曲起来了:
<media3D:CompositeTransform3D RotationY="-90" />

然后再设置 TranslateZ="100",让图片向外拉伸:
<media3D:CompositeTransform3D RotationY="-90" TranslateZ="100" />

搞定了一个方向后,所有方向都大致这样操作,只是改变 Rotation 和 Translate 还有中心点,就完成了一张静态的 3D 穿梭图:
<media3D:CompositeTransform3D x:Name="TransformLeft" x:Key="TransformLeft" RotationY="-90" TranslateZ="100" />
<media3D:CompositeTransform3D x:Name="TransformUp" x:Key="TransformUp" RotationX="90" TranslateZ="50" />
<media3D:CompositeTransform3D x:Name="TransformRight" x:Key="TransformRight" RotationY="90" CenterX="300" TranslateZ="50"/>
<media3D:CompositeTransform3D x:Name="TransformDown" x:Key="TransformDown" RotationX="-90" CenterY="300" TranslateZ="50" />
<Grid Background="{StaticResource ImageBackground}" Transform3D="{StaticResource TransformLeft}" />
<Grid Background="{StaticResource ImageBackground}" Transform3D="{StaticResource TransformUp}" />
<Grid Background="{StaticResource ImageBackground}" Transform3D="{StaticResource TransformRight}" />
<Grid Background="{StaticResource ImageBackground}" Transform3D="{StaticResource TransformDown}" />

下一步就是要让这四张图片动起来。这简单,用最基本的 DoubleAnimation 操作TranslateZ 从 10 变到 200:
<Storyboard x:Name="Move" x:Key="Move" RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="TransformLeft" Storyboard.TargetProperty="TranslateZ" From="10" To="200" Duration="0:0:8"/>
<DoubleAnimation Storyboard.TargetName="TransformUp" Storyboard.TargetProperty="TranslateZ" From="10" To="200" Duration="0:0:8"/>
<DoubleAnimation Storyboard.TargetName="TransformRight" Storyboard.TargetProperty="TranslateZ" From="10" To="200" Duration="0:0:8"/>
<DoubleAnimation Storyboard.TargetName="TransformDown" Storyboard.TargetProperty="TranslateZ" From="10" To="200" Duration="0:0:8"/>
</Storyboard>
这时候基本的动画就已经实现了,但是没办法做到首尾相连,所以先把之前的成果封装成一个控件:

然后给它加上透明度变化的动画:
<Storyboard x:Name="Fade" RepeatBehavior="Forever">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Root" Storyboard.TargetProperty="Opacity" Duration="0:0:8" >
<LinearDoubleKeyFrame KeyTime="0:0:0" Value="0"/>
<LinearDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
<LinearDoubleKeyFrame KeyTime="0:0:4.8" Value="1"/>
<LinearDoubleKeyFrame KeyTime="0:0:8" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
通过叠加两个 GalaxyShuttleControl ,并且控制它们动画开始的时间,互相掩盖开头和结尾动画衔接不上的问题:
public TimeSpan Delay { get; set; }
private async void GalaxyShettleControl_Loaded(object sender, RoutedEventArgs e)
{
await Task.Delay(Delay);
Move.Begin();
Fade.Begin();
}
<galaxyshuttles:GalaxyShuttleControl Delay="0:0:4" />
<galaxyshuttles:GalaxyShuttleControl/>
这样 3D 穿梭效果就实现了。
最后还差一点,ChokCoco 大佬的动画里加上了 hueRotate ,让颜色一直变化。UWP 里也可以使用 HueRotationEffect 实现这点,不过它的 Angle 的值范围是 0 到 2 * Math.Pi。要实现它的动画可以试试 Windows Community Toolkit 里的 PipelineVisualFactory 和 AnimationSet,这两个工具可以用来处理很复杂的效果和动画,用在这里反而大材小用:
<media:UIElementExtensions.VisualFactory>
<media:PipelineVisualFactory>
<media:HueRotationEffect x:Name="HueRotationEffect" IsAnimatable="True"/>
</media:PipelineVisualFactory>
</media:UIElementExtensions.VisualFactory>
<animations:Explicit.Animations>
<animations:AnimationSet x:Name="HueAnimation" >
<animations:AnimationScope>
<animations:HueRotationEffectAnimation From="0" To="6.28318530718" Target="{Binding ElementName=HueRotationEffect}" Repeat="Forever" Duration="0:0:28"/>
</animations:AnimationScope>
</animations:AnimationSet>
</animations:Explicit.Animations>
最终实现的效果如下:

满足了好奇心后,下一步(自己生成图片)就不玩了。3D 穿梭动画实现起来不算难,最难的部分是 ChokCoco 大佬提供的创意,期待 ChokCoco 大佬下次再有别的动画让我抄来玩。
最后说一句,虽然用 MAIU 或 WinUI3 应该都能搞,而且这两个技术听起来更时髦些,可惜它们还没发布正式版,我还是趁现在多陪陪 UWP 好了。
源码: https://github.com/DinoChan/uwp_design_and_animation_lab
3D 穿梭效果?使用 UWP 也能搞定的更多相关文章
- 3D 穿梭效果?使用 CSS 轻松搞定
背景 周末在家习惯性登陆 Apex,准备玩几盘.在登陆加速器的过程中,发现加速器到期了. 我一直用的腾讯网游加速器,然而点击充值按钮,提示最近客户端升级改造,暂不支持充值(这个操作把我震惊了~).只能 ...
- 一分钟搞定触手app主页酷炫滑动切换效果
代码地址如下:http://www.demodashi.com/demo/12826.html 前言: 前几天在看手机直播的时候,自己就用上了触手app.一进到主页就看上了里面页面切换的效果,自己想这 ...
- CSS3 3D立方体效果-transform也不过如此
CSS3系列已经学习了一段时间了,第一篇文章写了一些css3的奇技淫巧,原文戳这里,还获得了较多网友的支持,在此谢过各位,你们的支持是我写文章最大的动力^_^. 那么这一篇文章呢,主要是通过一个3D立 ...
- css3之3D翻牌效果
最近一直在学css3,发现他真的是越来越牛逼.现在的css3已经不在是以前的css了,它能做出的功能效果是我们没法想象的了.它可以实现flash,可以制作一些js能做出来的效果,还可以写出ps做出 ...
- 用FireFox火狐浏览器的3D Tilt 插件查看网页3D视图效果
逛博客发现了网页的3D视图效果,一搜原来是Firefox特有的一个功能,先看效果: 相当炫酷,接下来介绍如何实现. 1.首先安装3d tilt 插件: 从火狐浏览器的添加插件页面,搜索:3D Tilt ...
- Space.js – HTML 驱动的页面 3D 滚动效果
为了让我们的信息能够有效地沟通,我们需要创建用户和我们的媒体之间的强有力的联系.今天我们就来探讨在网络上呈现故事的新方法,并为此创造了一个开源和免费使用的 JavaScript 库称为 space.j ...
- Codrops 教程:实现内容倾斜的 3D 幻灯片效果
今天给大家分享的优秀教程来自 Codrops 网站,实现一个内容倾斜的 3D 幻灯片效果.我们平常见到的都是那种水平或者垂直滚动的效果,这个倾斜的内容滑动效果相信会让你眼前一亮.因为使用了 CSS 3 ...
- 拖拽碰撞效果,高级浏览器下全部搞定(ie6-8还没有搞定)
<!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8& ...
- iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果
8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...
随机推荐
- 『Python』matplotlib常用函数
1. 绘制图表组成元素的主要函数 1.1 plot()--展现量的变化趋势 import numpy as np import matplotlib.pyplot as plt import matp ...
- Git:分布式版本控制系统
参考廖雪峰的 Git 教程:https://www.liaoxuefeng.com/wiki/896043488029600 讲解很详细,这里只做一些个人笔记: 各系统安装 Git :https:/ ...
- Ubuntu开发相关环境搭建
一.Ubuntu系统语言环境切换修改 安装时,选择的中文版,但实际使用起来,很不爽,果断切换为英文 1.1 打开终端: vim /etc/default/locale 1.2 修改配置 LANG=&q ...
- windows下如何查看所有端口及占用
1.在windows下查看所有端口: 先点击电脑左下角的开始,然后选择运行选项,接着我们在弹出的窗口中,输入[cmd]命令,进行命令提示符. 然后我们在窗口中输入[netstat -ano]按下回车, ...
- T-SQL——关于SQL打开Excel文件
目录 0. 背景说明 1. 安装Access Database Engine 1. SQL脚本 3. .net项目中通过Micsoft.ACE.oledb读取Excel文件 志铭-2021年10月1日 ...
- ElasticSearch搜索引擎
官网:Elasticsearch:官方分布式搜索和分析引擎 | Elastic Elaticsearch,简称为es,es是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储.检索数据;本身扩 ...
- JS 开发中数组常用的方法
大家有没有想过,js数组为什么会有这么多的方法,没错,就是为了不同场景下处理数据的需要,就像设计模式一样,都是为了能更好的处理当前场景的需要. 首先怎么创建一个数组呢, // 两种方式 // 1,构造 ...
- mysql创建用户及赋予某用户权限(附带基础查看表内容)
首先登陆mysql 一:show databases; 展示所有数据库(root用户下) 二:use xxx (数据库名)使用use选择数据库 三:show xxx 查看数据库中的表 四:des ...
- YouTube爬虫下载
最近在想用爬虫写youtube网站下载学习视频,找了好多资料也没有有个有用的. 真不容易找到几行代码,代码实现很简单,基于youtube_dl 来之不易,仅参考 from __future__ imp ...
- selenium3 利用cookie实现免登陆
1.首先访问要操作的页面 2.登陆一次,使用Fiddle等工具抓取出cookie 3.按照如下代码,即可成功登陆 from selenium import webdriver url = " ...