原文:WPF 图片浏览 伪3D效果

首先上效果图:

因项目要求,需要把图片以“好看”、“炫”的效果展示出来,特地研究了一下WPF关于3D方面的制作,奈何最终成果只是能够画出一个立方体并使之旋转。

项目时间仅剩两天,只好放弃3D另找出路,于是就想起了Flash中各种“炫丽”的动画效果,图片按椭圆排列,并且旋转。

于是开始代码,然后发现关于椭圆啊、正玄余玄、x,y,r等等数学知识都忘得光光了,仅有思路没有进展,无奈之下开始百度恶补数学知识。图形变换、3D是很考验数学知识的,本人对于3D方面的学习就败在数学之下,高中数学学的还不错的,现在……哎,不提也罢。

然后找到这么一篇博文——javascript-按圆形排列DIV元素(三)实例---- 图片按椭圆形转动,是js代码,在此感谢这位船长op大大的无私奉献。

下面正式上代码:

定义ImageInfo类,实现INotifyPropertyChanged接口,属性没有写说明,不过看名称我想各位也能知道是什么含义了。

public class ImageInfo : INotifyPropertyChanged
{
private int _zIndex; public int ZIndex
{
get { return _zIndex; }
set
{
if (value != _zIndex)
{
_zIndex = value;
this.NotifyPropertyChanged("ZIndex");
}
}
}
private double _left; public double Left
{
get { return _left; }
set
{
if (value != _left)
{
_left = value;
this.NotifyPropertyChanged("Left");
}
}
}
private double _top; public double Top
{
get { return _top; }
set
{
if (value != _top)
{
_top = value;
this.NotifyPropertyChanged("Top");
}
}
}
private double _width; public double Width
{
get { return _width; }
set
{
if (value != _width)
{
_width = value;
this.NotifyPropertyChanged("Width");
}
}
}
private double _height; public double Height
{
get { return _height; }
set
{
if (value != _height)
{
_height = value;
this.NotifyPropertyChanged("Height");
}
}
} private double _opacity = 1.0; public double Opactity
{
get { return _opacity; }
set
{
if (value != _opacity)
{
_opacity = value;
this.NotifyPropertyChanged("Opactity");
}
}
} private string _imagePath; public string ImagePath
{
get { return _imagePath; }
set
{
if (value != _imagePath)
{
_imagePath = value;
this.NotifyPropertyChanged("ImagePath");
}
}
} public ImageInfo(string path)
{
this.ImagePath = path;
} public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

在xaml中binding ImageInfo 中的对应的属性,在后台代码中使用计时器来定时更改ImageInfo中的属性,当属性值发生改变时就会通知到界面,于是就实现了动画效果了。

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_ImageShow" x:Class="WPF_ImageShow.MainWindow"
Title="MainWindow" Height="600" Width="800" >
<Window.Resources>
<local:DoubleConverter x:Key="doubleConverter"/>
</Window.Resources>
<Grid>
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" Loaded="lv_Loaded"
ScrollViewer.VerticalScrollBarVisibility="Disabled" x:Name="lv" Background="Black">
<!--<ListView.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel>
<Image Source="{Binding ImagePath, Mode=OneWay}" x:Name="img"
Stretch="UniformToFill" Width="{Binding Width, Mode=OneWay}"
Height="{Binding Height, Mode=OneWay}"/>
<Rectangle RenderTransformOrigin="1,0.5" Height="{Binding Height, Converter={StaticResource doubleConverter}, Mode=OneWay}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=img}" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" />
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.3" Color="Transparent" />
<GradientStop Offset="1" Color="#44000000" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>-->
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}" >
<Border>
<StackPanel>
<Image Source="{Binding ImagePath, Mode=OneWay}" x:Name="img"
Stretch="UniformToFill" Width="{Binding Width, Mode=OneWay}"
Height="{Binding Height, Mode=OneWay}"/>
<Rectangle RenderTransformOrigin="1,0.5" Height="{Binding Height, Converter={StaticResource doubleConverter}, Mode=OneWay}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=img}" />
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" />
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0.3" Color="Transparent" />
<GradientStop Offset="1" Color="#44000000" />
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Opacity" Value="{Binding Opactity, Mode=OneWay}"/>
<Setter Property="Canvas.Left" Value="{Binding Left, Mode=OneWay}"/>
<Setter Property="Canvas.Top" Value="{Binding Top, Mode=OneWay}"/>
<Setter Property="Panel.ZIndex" Value="{Binding ZIndex, Mode=OneWay}"/>
</Style>
</ListView.Resources>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
</Grid>
</Window>
 /// <summary>
/// 设置动画
/// </summary>
void Run()
{
//动画速率
double speed = 0.0;
//定时器,定时修改ImageInfo中各属性,从而实现动画效果
DispatcherTimer timer = new DispatcherTimer();
//时间间隔
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += (ss, ee) =>
{
#region
//设置圆心x,y
double centerX = this.ActualWidth / 2;
double centerY = this.ActualHeight / 2 - 50;//减去适当的值,因为会设置最下面的图片最大,上面的图片较小 //设置图片最大的宽、高
double maxWidth = 300;
double maxHeight = 200; //设置椭圆的长边和短边
double a = centerX - maxWidth / 2.0;
double b = centerY - maxHeight / 2.0; //运动一周后恢复为0
speed = speed < 360 ? speed : 0.0;
//运运的速度 此“增值”和 timer.Interval对动画的流畅性有影响
speed += 0.5;
//运动距离,即运动的弧度数;
var ainhd = speed * Math.PI / 180;
//每个图片之间相隔的角度
var angle = (360.0 / data.Count) * Math.PI / 180.0;
//图片序号
int index = 0;
foreach (var img in data)
{
//最下面一张图ZIndex最大,Opacity最大,长宽最大 img.ZIndex = (int)img.Top;
//当前图片与最下面一张图片的Y的比值
var allpers = img.Top / (centerY + b);
//不要小于0.2,太小了就看不见了,可以适当调整
allpers = Math.Max(0.2, allpers);
//设置图片大小
img.Width = allpers * maxWidth;
img.Height = allpers * maxHeight;
//设置透明度
img.Opactity = Math.Max(allpers * 1.5, 0.4); //公式:x=sin * a //+ centerX因为默认wpf默认左上角为坐标原点;//- img.Width / 2.0是以图片中心点作为运动轨迹
img.Left = Math.Sin((angle * index + ainhd)) * a + centerX - img.Width / 2.0;//x=sin * a
//y=cos * b
img.Top = Math.Cos((angle * index + ainhd)) * b + centerY - img.Height / 2.0; index++;
}
#endregion
};
//启动计时器,开始动画
timer.Start();
} private void lv_Loaded(object sender, RoutedEventArgs e)
{
//准备数据源 ObservableCollection<T>
data = new ObservableCollection<ImageInfo>();
//获取程序所在目录中的images文件夹
DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory + "images");
//添加此目录中的图片文件到data中
foreach (var file in di.GetFiles())
{
//验证是否为图片文件 (可以写一个方法来进行验证,此处仅支持jpg和png)
if (file.Extension.ToLower() == ".jpg" || file.Extension.ToLower() == ".png")
{
data.Add(new ImageInfo(file.FullName));
}
}
//设置ListView的ItemsSource
lv.ItemsSource = data; Run();
}

最后上一个简单的Demo:WPF_ImageShow

WPF 图片浏览 伪3D效果的更多相关文章

  1. flash 逐字,逐行歌词实现,添加伪3D效果

    项目结构: 效果如图: 项目为公司项目,下载人员禁止用于商业项目中. 项目开发工具:FlashDevelop 点击下载

  2. wpf图片切换,幻灯效果

    xaml: <Window x:Class="WpfApplication1.PicShow" xmlns="http://schemas.microsoft.co ...

  3. 实现一个图片轮播-3d播放效果

    前言:最近在做一个音乐播放器,首页要做一个图片轮播,看了bootstrap的carousel插件以及移动端的swipe.js库,都是平面图片轮播的效果,所以自己想着实现类似网易云app里那种3d图片轮 ...

  4. 2.5D(伪3D)站点可视化第一弹

    楔子 最近要做一个基站站点的可视化呈现项目. 我们首先尝试的是三维的可视化技术来程序,但是客户反馈的情况是他们的客户端电脑比较差,性能效率都会不好,甚至有的还是云主机. 因此我们先做了一个性能比较极致 ...

  5. wpf 模拟3D效果(和手机浏览图片效果相似)(附源码)

    原文 wpf 模拟3D效果(和手机浏览图片效果相似)(附源码) pf的3D是一个很有意思的东西,类似于ps的效果,类似于电影动画的效果,因为动画的效果,(对于3D基础的摄像机,光源,之类不介绍,对于依 ...

  6. WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现

    原文:WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放.图片立体轮播.图片倒影立体滚动)效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7 ...

  7. 在WPF中使用PlaneProjection模拟动态3D效果

    原文:在WPF中使用PlaneProjection模拟动态3D效果 虽然在WPF中也集成了3D呈现的功能,在简单的3D应用中,有时候并不需要真实光影的3D场景.毕竟使用3D引擎会消耗很多资源,有时候使 ...

  8. Android 高级UI设计笔记14:Gallery(画廊控件)之 3D图片浏览

    1. 利用Gallery组件实现 3D图片浏览器的功能,如下: 2. 下面是详细的实现过程如下: (1)这里我是测试性代码,我的图片是自己添加到res/drawable/目录下的,如下: 但是开发中不 ...

  9. 3d效果的图片轮播

    CSS3的3d变换 CSS3给我们提供了一个新的功能,那就是3d变换.3d变换和2d变换的基本API函数类似,只不过多了些在Z轴上的操作,不难使用. 但是,为了让元素拥有3d变换的功能,我们需要给他的 ...

随机推荐

  1. 如何下载和编译Android4.0内核源代码goldfish(图像)

    如何下载Android4.0源代码.请参阅我的博客文章中有(同样是图文教程): http://blog.csdn.net/flydream0/article/details/7036156 怎样编译A ...

  2. [c++语法]类

    什么是类 类 是 面向对象的基础.c里面是没有对象的,只有数据,即静态的死物. 从面向过程升级到面向对象后,有了对象的概念,对象是数据与方法的合体,是动态的活物. 类代表着一类事物的特征.而对象,是类 ...

  3. [Android学习笔记]获取view的尺寸和坐标

    对于UI方面很多时候需要获取它的很多信息,具体情况见view的文档 View文档 http://developer.android.com/training/index.html 常用方法:获取vie ...

  4. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  5. 一则简单演示样例看Oracle的“无私”健壮性

    Oracle的强大之处就在于他能总帮助让你选择正确的运行计划,即使你给了它错误的指示. 实验: 1. 创建測试表: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZ ...

  6. 2015年十大热门Android开源新项目

    2015年十大热门Android开源新项目 2015 即将结束,又到了大家喜闻乐见的年终盘点时刻啦,今天给大家盘点一下 2015 年 Android 开发领域新出现的 10 大热门开源项目.数据来自于 ...

  7. Android入门之login设计

    效果图: MainActivity.java package jk.quickpay.login; import jk.quickpay.login.FileService; import java. ...

  8. Unity MegaFiers 顶点动画

        使用 MegaFiers 插件,能够使得Unity支持顶点动画的播放. 官方视频教程例如以下: 在这里简单測试使用下,环境例如以下: Blender 2.72 Unity 4.5.4 Mega ...

  9. 折扣&折让-看清实质的思考

    折扣&折让 看清实质的思考 Author:zfive5(zidong) Email:zfive5@163.com 引子 有些东西,在没有人指点的情况,一时理解不了,就放一放,等到某一个契机到来 ...

  10. hdu4027(线段树)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=4027 线段树功能:区间修改,区间求和. 分析:因为每个数至多开6次平方就变1了,所以对于每一段全为1的 ...