文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>Silverlight3D 墙效果

Silverlight3D 墙效果

时间:2010-08-19  来源:cnblogs2010

效果图:

C#(xaml)

 

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;

namespace Silverlight3D
{
        public class Panel3D : Panel
        {
                private Point mouseStart, mouseNow;
                private double destinationDistance = 800;

                public enum AlignmentOptions { Left, Center, Right };

                private const double MouseWheelScaleFactor = 2.5;
                private const double Easing = 0.3;
                private const double MaximumDistance = 3000;
                private const double MinimumDistance = 200;
                private const double MouseEasing = 0.03;

                #region Dependency Properties

                public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.RadiusChanged));
                public static readonly DependencyProperty AngleItemProperty = DependencyProperty.Register("AngleItem", typeof(double), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.AngleItemChanged));
                public static readonly DependencyProperty InitialAngleProperty = DependencyProperty.Register("InitialAngle", typeof(double), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.InitialAngleChanged));
                public static readonly DependencyProperty AlignProperty = DependencyProperty.Register("Align", typeof(AlignmentOptions), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.AlignChanged));
                public static readonly DependencyProperty IsDragOnProperty = DependencyProperty.Register("IsDragOn", typeof(bool), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.IsDragChanged));
                public static readonly DependencyProperty OffsetYProperty = DependencyProperty.Register("OffsetY", typeof(double), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.OffsetYChanged));
                public static readonly DependencyProperty DistanceProperty = DependencyProperty.Register("Distance", typeof(double), typeof(CircularPanel3D), new PropertyMetadata(CircularPanel3D.DistanceChanged));

                private static void RadiusChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel3D)sender).Refresh(); }
                private static void AngleItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel3D)sender).Refresh(); }
                private static void InitialAngleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel3D)sender).Refresh(); }
                private static void AlignChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel3D)sender).Refresh(); }
                private static void IsDragChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel3D)sender).OnIsDragChanged(e); }
                private static void OffsetYChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ((CircularPanel3D)sender).Refresh(); }
                private static void DistanceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
                {
                        CircularPanel3D circularPanel3D = (CircularPanel3D)sender;
                        circularPanel3D.destinationDistance = (double)e.NewValue;
                        circularPanel3D.Refresh();
                }

                [Category("Circular Panel 3D")]
                public double Radius
                {
                        get { return (double)this.GetValue(CircularPanel3D.RadiusProperty); }
                        set { this.SetValue(CircularPanel3D.RadiusProperty, value); }
                }

                [Category("Circular Panel 3D")]
                public double AngleItem
                {
                        get { return (double)this.GetValue(CircularPanel3D.AngleItemProperty); }
                        set { this.SetValue(CircularPanel3D.AngleItemProperty, value); }
                }

                [Category("Circular Panel 3D")]
                public double InitialAngle
                {
                        get { return (double)this.GetValue(CircularPanel3D.InitialAngleProperty); }
                        set { this.SetValue(CircularPanel3D.InitialAngleProperty, value); }
                }

                [Category("Circular Panel 3D")]
                public AlignmentOptions Align
                {
                        get { return (AlignmentOptions)this.GetValue(CircularPanel3D.AlignProperty); }
                        set { this.SetValue(CircularPanel3D.AlignProperty, value); }
                }

                [Category("Circular Panel 3D")]
                public bool IsDragOn
                {
                        get { return (bool)this.GetValue(CircularPanel3D.IsDragOnProperty); }
                        set { this.SetValue(CircularPanel3D.IsDragOnProperty, value); }
                }

                [Category("Circular Panel 3D")]
                public double OffsetY
                {
                        get { return (double)this.GetValue(CircularPanel3D.OffsetYProperty); }
                        set { this.SetValue(CircularPanel3D.OffsetYProperty, value); }
                }

                [Category("Circular Panel 3D")]
                public double Distance
                {
                        get { return (double)this.GetValue(CircularPanel3D.DistanceProperty); }
                        set { this.SetValue(CircularPanel3D.DistanceProperty, value); }
                }

                #endregion

                #region Dependency Property Events

                private void OnIsDragChanged(DependencyPropertyChangedEventArgs e)
                {
                        this.CaptureMouse();
                        this.MouseLeftButtonDown += new MouseButtonEventHandler(this.CircularPanel3D_MouseLeftButtonDown);
                        this.MouseLeftButtonUp += new MouseButtonEventHandler(this.CircularPanel3D_MouseLeftButtonUp);
                }

                #endregion

                #region Mouse Interaction

                private void CircularPanel3D_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
                {
                        this.CaptureMouse();
                        this.mouseStart = e.GetPosition(this);
                        this.mouseNow = this.mouseStart;

                        CompositionTarget.Rendering += this.ApplyRotationFromMouseMove;

                        this.MouseMove += new MouseEventHandler(this.CircularPanel3D_MouseMove);
                }

                private void CircularPanel3D_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
                {
                        this.ReleaseMouseCapture();
                        this.MouseMove -= new MouseEventHandler(this.CircularPanel3D_MouseMove);
                }

                // Updates mouse position when mouse moves
                private void CircularPanel3D_MouseMove(object sender, MouseEventArgs e)
                {
                        CompositionTarget.Rendering += this.ApplyRotationFromMouseMove;

                        this.mouseNow = e.GetPosition(this);
                }

                private void HandleMouseWheel(object sender, MouseWheelEventArgs e)
                {
                        double newDistance = this.destinationDistance + CircularPanel3D.MouseWheelScaleFactor * -e.Delta;

                        if (newDistance <= CircularPanel3D.MaximumDistance && 
                                newDistance >= CircularPanel3D.MinimumDistance)
                        {
                                this.destinationDistance += CircularPanel3D.MouseWheelScaleFactor * -e.Delta;
                        }
                }

                private void ApplyZoomDistanceAnimation(object sender, EventArgs e)
                {
                        if (Math.Abs(this.Distance - destinationDistance) < 1)
                        {
                                this.Distance = destinationDistance;
                        }

                        this.Distance += (destinationDistance - this.Distance) * CircularPanel3D.Easing;
                        
                        if (this.Distance > CircularPanel3D.MaximumDistance)
                        {
                                this.destinationDistance = CircularPanel3D.MaximumDistance;
                        }
                        else if (this.Distance < CircularPanel3D.MinimumDistance)
                        {
                                this.destinationDistance = CircularPanel3D.MinimumDistance;
                        }
                }

                #endregion
                
                #region Custom Panel Methods

                protected override Size MeasureOverride(Size availableSize)
                {
                        this.MouseWheel += this.HandleMouseWheel;
                        CompositionTarget.Rendering += this.ApplyZoomDistanceAnimation;

                        Size resultSize = new Size(0, 0);

                        foreach (UIElement child in this.Children)
                        {
                                child.Measure(availableSize);
                                resultSize.Width = Math.Max(resultSize.Width, child.DesiredSize.Width);
                                resultSize.Height = Math.Max(resultSize.Height, child.DesiredSize.Height);
                        }

                        resultSize.Width =
                                double.IsPositiveInfinity(availableSize.Width) ?
                                resultSize.Width : availableSize.Width;

                        resultSize.Height =
                                double.IsPositiveInfinity(availableSize.Height) ?
                                resultSize.Height : availableSize.Height;

                        return resultSize;
                }

                protected override Size ArrangeOverride(Size finalSize)
                {
                        this.Refresh();
                        return base.ArrangeOverride(finalSize);
                }

                #endregion

                #region Programmatic Animation Methods

                private void ApplyRotationFromMouseMove(object sender, EventArgs e)
                {
                        // Rotates Circular Panel 3D using MouseMove (X)
                        if (Math.Abs(this.mouseNow.X - this.mouseStart.X) < 1)
                        {
                                this.mouseNow.X = this.mouseStart.X;
                        }
                        this.InitialAngle += ((this.mouseNow.X - this.mouseStart.X) * CircularPanel3D.MouseEasing) / 2.2;

                        this.mouseStart.X += ((this.mouseNow.X - this.mouseStart.X) * CircularPanel3D.MouseEasing);
                        if ((Math.Abs(this.mouseNow.X - this.mouseStart.X) < 1))
                        {
                                CompositionTarget.Rendering -= this.ApplyRotationFromMouseMove;
                        }
                }

                private void Refresh()
                {
                        int count = 0;
                        int col = 0;
                        int row = 0;
                        int zLevel = 0;

                        foreach (FrameworkElement childElement in this.Children)
                        {
                                double angle = (this.AngleItem * count++) - this.InitialAngle;
                                double x = this.Radius * Math.Cos(Math.PI * angle / 180);
                                double z = this.Radius * Math.Sin(Math.PI * angle / 180);
                                PlaneProjection projection = new PlaneProjection();
                                if (projection != null)
                                {
                                        projection.CenterOfRotationX = 0.5;
                                        projection.CenterOfRotationY = 0.5;
                                        projection.CenterOfRotationZ = 0.5;
                                        projection.RotationY = angle + 90;
                                        projection.GlobalOffsetX = x;
                                        projection.GlobalOffsetZ = z - this.Distance;
                                        projection.GlobalOffsetY = row * (-330) + this.OffsetY;
                                }

                                int depth = (int)(z * 100);

                                double pDist = (this.Distance - 1000) / 2000;
                                double pZ = ((z + 1000) / 2000) + 0.5;

                                double opacity = (pZ - pDist) + 0.4;
                                if (opacity >= 1)
                                {
                                        childElement.Opacity = (2 - opacity);
                                }
                                else if (opacity < 0)
                                {
                                        childElement.Opacity = 0;
                                }
                                else
                                {
                                        childElement.Opacity = opacity;
                                }

                                // Variable zLevel changes value of ZIndex for each item in the ListBox.
                                // This way the reflex of elements at the top will be placed behind the item below it.
                                Canvas.SetZIndex(childElement, depth-(++zLevel*10));

                                double alignX = 0;
                                double alignY = 0;
                                switch (this.Align)
                                {
                                        case AlignmentOptions.Left:
                                                alignX = 0;
                                                alignY = 0;
                                                break;
                                        case AlignmentOptions.Center:
                                                alignX = childElement.DesiredSize.Width / 2;
                                                alignY = childElement.DesiredSize.Height / 2;
                                                break;
                                        case AlignmentOptions.Right:
                                                alignX = childElement.DesiredSize.Width;
                                                alignY = childElement.DesiredSize.Height;
                                                break;
                                }
                                childElement.Projection = projection;
                                childElement.Arrange(new Rect(this.Width / 2 - alignX , this.Height / 2 - alignY, childElement.DesiredSize.Width, childElement.DesiredSize.Height));

                                col++;
                                if (col > 14)
                                {
                                        col = 0;
                                        row++;
                                }
                        }
                }

                #endregion
        }
}



 

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载