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变换的功能,我们需要给他的 ...
随机推荐
- Android 进行单元測试难在哪-part3
原文链接 : HOW TO MAKE OUR ANDROID APPS UNIT TESTABLE (PT. 1) 原文作者 : Matthew Dupree 译文出自 : 开发技术前线 www.de ...
- VC生成的DLL给QT的EXE调用时lib路径问题小结
VC生成的DLL给QT调用,有两种方式,一种是隐式调用调用(使用.lib文件方式): ① 在*.pro工程文件中添加VC生成的lib文件路径时,或者使用一个绝对路径,如: LIBS += " ...
- thinkphp 3.2.3 入门示例
原文:thinkphp3.2 1.安装WAMPServer,到D:\wamp\. 2.下载ThinkPHP3.2.3核心版.解压缩后,放到D:\wamp\www\MyWeb\.打开浏览器,输入网址:h ...
- [IDEs]Eclipse设置花括号样式
用惯Vistual Studio,在使用Eclipse时发现有很多东西还是挺不习惯,第一个就要解决花括号的样式 步骤: 1.Windows->Preferences->Java->C ...
- shell脚本查看网络配置
#!/bin/bash ifconfig|grep -E 'eth|inet'|grep -Ev '(inet6|127.0.0.1)'|sed 's/ /\n/g'|awk NF|grep -Ev ...
- IIS 添加mime 支持 apk,exe,.woff,IIS MIME设置 ,Android apk下载的MIME 设置 苹果ISO .ipa下载mime 设置
原文:IIS 添加mime 支持 apk,exe,.woff,IIS MIME设置 ,Android apk下载的MIME 设置 苹果ISO .ipa下载mime 设置 站点--右键属性--http头 ...
- cocos2d-x 类大全及其概要
CCNode 节点类是Cocos2D-x中的主要类,继承自CCObject. 任何需要画在屏幕上的对象都是节点类.最常用的节点类包括场景类(CCScene).布景层类(CCLayer).人物精灵类(C ...
- java自己主动打开包装盒很容易导致两个误区
从J2SE 5.0开始提供基本数据类型的自己主动装箱(autoboxing).拆箱(unboxing)功能. 何为自己主动装箱: 当我们创建一个Integer对象时,却能够这样: Integer i ...
- iPhone、iPad强制关机
情景:iPad測试应用过程中死机了. 解决:同一时候按住右上方的电源键和屏幕下方的HOME键大约10秒左右. 就会自己主动强制断电关机,然后重新启动. 强制重新启动后你会看到进入苹果的标志,然后进入主 ...
- hdu 4404 Worms(多边形与圆的交)
求出爆炸点的坐标,就成了多边形与圆相交面积的模板题了... #include<algorithm> #include<iostream> #include<cstring ...