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效果的更多相关文章
- flash 逐字,逐行歌词实现,添加伪3D效果
项目结构: 效果如图: 项目为公司项目,下载人员禁止用于商业项目中. 项目开发工具:FlashDevelop 点击下载
- wpf图片切换,幻灯效果
xaml: <Window x:Class="WpfApplication1.PicShow" xmlns="http://schemas.microsoft.co ...
- 实现一个图片轮播-3d播放效果
前言:最近在做一个音乐播放器,首页要做一个图片轮播,看了bootstrap的carousel插件以及移动端的swipe.js库,都是平面图片轮播的效果,所以自己想着实现类似网易云app里那种3d图片轮 ...
- 2.5D(伪3D)站点可视化第一弹
楔子 最近要做一个基站站点的可视化呈现项目. 我们首先尝试的是三维的可视化技术来程序,但是客户反馈的情况是他们的客户端电脑比较差,性能效率都会不好,甚至有的还是云主机. 因此我们先做了一个性能比较极致 ...
- wpf 模拟3D效果(和手机浏览图片效果相似)(附源码)
原文 wpf 模拟3D效果(和手机浏览图片效果相似)(附源码) pf的3D是一个很有意思的东西,类似于ps的效果,类似于电影动画的效果,因为动画的效果,(对于3D基础的摄像机,光源,之类不介绍,对于依 ...
- WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放、图片立体轮播、图片倒影立体滚动)效果实现
原文:WPF技术触屏上的应用系列(四): 3D效果图片播放器(图片立体轮放.图片立体轮播.图片倒影立体滚动)效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7 ...
- 在WPF中使用PlaneProjection模拟动态3D效果
原文:在WPF中使用PlaneProjection模拟动态3D效果 虽然在WPF中也集成了3D呈现的功能,在简单的3D应用中,有时候并不需要真实光影的3D场景.毕竟使用3D引擎会消耗很多资源,有时候使 ...
- Android 高级UI设计笔记14:Gallery(画廊控件)之 3D图片浏览
1. 利用Gallery组件实现 3D图片浏览器的功能,如下: 2. 下面是详细的实现过程如下: (1)这里我是测试性代码,我的图片是自己添加到res/drawable/目录下的,如下: 但是开发中不 ...
- 3d效果的图片轮播
CSS3的3d变换 CSS3给我们提供了一个新的功能,那就是3d变换.3d变换和2d变换的基本API函数类似,只不过多了些在Z轴上的操作,不难使用. 但是,为了让元素拥有3d变换的功能,我们需要给他的 ...
随机推荐
- Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一)
原文:Thinkphp框架拓展包使用方式详细介绍--验证码实例(十一) 拓展压缩包的使用方式详细介绍 1:将拓展包解压:ThinkPHP3.1.2_Extend.zip --> 将其下的 \ ...
- sprintf,多少钱你知道?
选<CSDN 社区电子杂志——C/C++杂志>http://emag.csdn.net 2005 年1 月 总号1 期 - 93 -笔者:steedhorse(晨星)printf 可能是很 ...
- 端口映射工具 redir/socat/xinetd - 运维技术 - 开源中国社区
端口映射工具 redir/socat/xinetd - 运维技术 - 开源中国社区 端口映射工具 redir/socat/xinetd 10人收藏此文章, 我要收藏 发表于3天前(2013-08 ...
- [poj 2991]Crane[线段树表示向量之和,而非数量]
题意: 起重机的机械臂, 由n段组成, 对某一些连接点进行旋转, 询问每次操作后的末端坐标. 思路: 由于旋转会影响到该点之后所有线段的角度, 因此容易想到用线段树记录角度, 成段更新. (但是不是每 ...
- Hive Metastore ObjectStore PersistenceManager自动关闭bug解析
最近在测试HCatalog,由于Hcatalog本身就是一个独立JAR包,虽然它也可以运行service,但是其实这个service就是metastore thrift server,我们在写基于Hc ...
- Linux目录文件详解FHS标准(2013.09.05)
Linux 目录配置的依据FHS(Filesystem Hierarchy Standard)标准,将目录分成为四种交互作用的形态: 四种形态的具体解释: 可分享的:可以分享给其他系统挂载使用的目录, ...
- 一个有趣的swap函数
C语言版: void swap (int a, int b) { a = a ^ b; b = a ^ b; a = a ^ b; } 原理: a ^ a == 0 0 ^ b == b 异或:同则为 ...
- 【网络协议】TCP交互数据流和数据流成块
前言 建立在TCP协议上的应用层协议有非常多,如FTP.HTTP.Telnet等,这些协议依据数据传输的多少能够分为两类:交互数据类型和成块数据类型. 交互数据类型,如:Telnet,这类协议一般仅仅 ...
- STP学习总结
STP学习总结 STP是广泛应用在二层的具有冗余的网络中用来消除环路的一种机制,当然二层环网中用来消除环路的技术还有RRPP和H3C的smart-link技术等. 一.STP的一些基本概念 STP是I ...
- 关于Opencv2.4.x中stitcher类的简单应用
1.opencv2.4以上版本有stitcher类,可以简单方便的实现图像的拼接,目前只是简单的测试一下stitcher类的拼接功能,也是纠结了好长时间,最终发现是要在链接库中加上opencv_sti ...