博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WFP:Geometries几何图形集合--Geometry几何图形(1)
阅读量:7192 次
发布时间:2019-06-29

本文共 4875 字,大约阅读时间需要 16 分钟。

Geometry几何图形集合+3D变换

实现效果:

  1. 展示玻璃效果的Radiobutton
  2. 选择页面时页面的出现及退出呈现动画旋转、缩放效果

clipboard.png

有关具体类的含义见下章解析。
文件结构:

clipboard.png

主窗口xaml:

主窗口DockPanel承载左侧玻璃Radiobutton按钮区域Border及右侧屏幕的区域Grid,Grid下加载黑色方格+径向渐变色的背景方框、加载页面Page的Frame的ScrollView区域、显示3D动画ViewBox的区域Border。

  1. Viewbox的长宽绑定ScrollView的实际长宽,其中的3D材质的VisualBrush的Visual源绑定到ScrollView元素,同时进行旋转、缩放动画。
  2. 当选择按钮时,在右侧Viewbox执行当前页面的退出动画3D效果。同时Checked事件设置新页面索引,执行完成退出动画后及,再执行新页面的进入动画3D效果。

Radiobutton代码:

Geometry Usage
Shape Geometries
PathGeometry
Geometry Attribute Syntax Example
Combining Geometries Example

右侧展示页面动画及内容的xaml:

其中设有Frame的缩放对象ScaleTransform(取消无影响),

3D动画容器代码:

内容装饰器ViewBox长宽绑定页面的容器ScrollView实际长宽,且其内容Viewport3D二维布局范围内包含的三维内容。

  1. 设置Viewport3D.Camera摄像机对象:PerspectiveCamera透视投影摄像机
  2. 设置Viewport3D.ModelVisual3D 3D模型视觉对象,其中包含3D模型环境光源对象AmbientLight
  3. 3D模型还包含使用指定的 Material 呈现 Geometry3D对象。

    1. 其GeometryModel3D.Geometry中包含三维三角基元类MeshGeometry3D 3D网状几何对象
    2. 其中GeometryModel3D.Material 3D素材对象设为光线漫射素材DiffuseMaterial ,其画刷DiffuseMaterial.Brush设置为VisualBrush,继承Visual的ScrollView对象作为画刷的Visual绑定源。
    3. 至此3D模型构建完成。
  4. ModelVisual3D.Transform 3D模型视觉对象的变换:

    1. RotateTransform3D.Rotation 3D旋转对象设置为AxisAngleRotation3D 3D绕轴角度旋转对象。
    2. 设置ScaleTransform3D缩放3D变换。

选定按钮后页面触发器执行退出3D动画:

  1. 对上面的3D模型的水平轴、缩放x/y/z的值进行动画
  2. 同理设置页面进入时的3D模型动画效果,作为动画资源,被设置为退出动画后Completed》完成进入动画的执行。

后台代码:

主页面初始化时就储存各页面初始化对象:
ps:可设置动态加载页面?

public SampleViewer(){    InitializeComponent();    _examples = new Page[5];    _examples[0] = new GeometryUsageExample();    _examples[1] = new ShapeGeometriesExample();    _examples[2] = new PathGeometryExample();    _examples[3] = new CombiningGeometriesExample();    _examples[4] = new GeometryAttributeSyntaxExample();}

主页面加载后执行选定一个Radiobutton,同时触发执行之前画面的退场动画。

private void PageLoaded(object sender, RoutedEventArgs args){    Example1RadioButton.IsChecked = true;}

动画退场后执行Frame导航到新选定的页面并显示内容。

private void ZoomOutStoryboardCompleted(object sender, EventArgs args){    mainFrame.Navigate(_examples[_sampleIndex]);}

新页面加载呈现内容后执行进场动画资源启动:

private void FrameContentRendered(object sender, EventArgs args){    var s = (Storyboard)Resources["ZoomInStoryboard"];    s.Begin(this);}

进场动画完成后执行页面内容的显示,遮住动画画面并提供操作:

private void ZoomInStoryboardCompleted(object sender, EventArgs e){    scrollViewerBorder.Visibility = Visibility.Visible;}

当选定一个按钮后发生:

  1. 设置3D三角基元的开始位置
  2. scrollViewerBorder内容隐藏,只显示动画界面
  3. 设置选定的页面对应索引值,作为退场动画后加载新页面的索引值。
private void SampleSelected(object sender, RoutedEventArgs args){    var points = new Point3DCollection();    var ratio = myScrollViewer.ActualWidth/myScrollViewer.ActualHeight;    points.Add(new Point3D(5, -5*ratio, 0));    points.Add(new Point3D(5, 5*ratio, 0));    points.Add(new Point3D(-5, 5*ratio, 0));    points.Add(new Point3D(-5, 5*ratio, 0));    points.Add(new Point3D(-5, -5*ratio, 0));    points.Add(new Point3D(5, -5*ratio, 0));    points.Add(new Point3D(-5, 5*ratio, 0));    points.Add(new Point3D(-5, -5*ratio, 0));    points.Add(new Point3D(5, -5*ratio, 0));    points.Add(new Point3D(5, -5*ratio, 0));    points.Add(new Point3D(5, 5*ratio, 0));    points.Add(new Point3D(-5, 5*ratio, 0));    myGeometry.Positions = points;    myViewport3D.Width = 100;    myViewport3D.Height = 100*ratio;    scrollViewerBorder.Visibility = Visibility.Hidden;    var button = sender as RadioButton;    if (button != null)    {        if (button.Content.ToString() == "Geometry Usage")            _sampleIndex = 0;        else if (button.Content.ToString() == "Shape Geometries")            _sampleIndex = 1;        else if (button.Content.ToString() == "PathGeometry")            _sampleIndex = 2;        else if (button.Content.ToString() == "Combining Geometries Example")            _sampleIndex = 3;        else if (button.Content.ToString() == "Geometry Attribute Syntax Example")            _sampleIndex = 4;    }}

扩展:

  1. 以上按钮点击在某种情况下有bug:当正在显示第一个页面退场时点击第二个按钮,随机马上再点击之前的第一个页面按钮,那么当第一个页面退出动画完成后,不会出现第一个页面的进场动画及内容显示.
  2. 分析原因:同一个页面退场动画执行后,再次触发同样的动画时,会覆盖之前的效果。其中包括完成动画要执行的mainFrame.Navigate方法并没有执行。
  3. 当新的退出动画完成后发现mainFrame.Navigate导航的内容还是原来的第一个页面,那么就不会再重新程序内容及进场动画,此时页面内容是隐藏的。
  4. 临时解决方法:记录当前页面索引值,比较确定是否最后选择的页面还是之前第一个,那么直接显示内容画面。
private void ZoomOutStoryboardCompleted(object sender, EventArgs args){    mainFrame.Navigate(_examples[_sampleIndex]);       if (_currentIndex == _sampleIndex)    {                        scrollViewerBorder.Visibility = Visibility.Visible;    }    else    {        _currentIndex = _sampleIndex;    }}

玻璃按钮请看下一章。

转载地址:http://azxkm.baihongyu.com/

你可能感兴趣的文章
装饰器复习
查看>>
pymysql数据库操作
查看>>
elasticsearch问题解决之分片副本UNASSIGNED
查看>>
|"|&|<|>等html字符转义
查看>>
ORACLE参数max_shared_servers空值与零的区别
查看>>
线程池
查看>>
EditPlus自行添加行注释的快捷键
查看>>
读书笔记—CLR via C#章节11-13
查看>>
poj 2154 Color——带优化的置换
查看>>
Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式'](转)
查看>>
asp.net 服务器 上传文件到 FTP服务器
查看>>
ZooKeeper学习第一期---Zookeeper简单介绍
查看>>
Mybatis(spring)(多个参数)(插入数据返回id)
查看>>
操作系统学习笔记三 进程
查看>>
Map的嵌套使用
查看>>
实习公司的开发环境搭建教程
查看>>
Linux busybox mount -a fstab
查看>>
Dijkstra
查看>>
property测试代码:
查看>>
[C# | WinCE | Solution] 在 WinCE 上访问 SSL 加密后的 WCF SOAP 服务接口出现“未能与远程服务器建立信任关系”...
查看>>