zoukankan      html  css  js  c++  java
  • Windows 8 系列 仿新浪微博图片放大功能 随笔

    定义图片放大的Xaml文件:

    View Code
    <UserControl
        x:Class="Win8_ScorllViewer.LodingImage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:Win8_ScorllViewer"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
    
        <Grid x:Name="LayoutRoot"   Background="Transparent"  PointerPressed="LayoutRoot_PointerPressed_1"  >
            <Grid.RowDefinitions>
                <RowDefinition  Height="*"></RowDefinition>
                <RowDefinition Height="160"></RowDefinition>
            </Grid.RowDefinitions>
            <Rectangle x:Name="rectShadow" Grid.RowSpan="2"></Rectangle>
            <Canvas Grid.RowSpan="2">
                <!-- 注意 Stretch="Fill"  -->
                <Image 
                    x:Name="img" 
                    PointerMoved="img_PointerMoved_1" 
                    PointerReleased="img_PointerReleased_1" 
                    PointerPressed="img_PointerPressed_1"  
                    PointerEntered="img_PointerEntered_1" 
                    PointerExited="img_PointerExited_1"  
                    Stretch="Fill"   
                       >
                <Image.RenderTransform>
                    <ScaleTransform x:Name="st" />
                </Image.RenderTransform>
            </Image>
            </Canvas>
            <StackPanel HorizontalAlignment="Center" Orientation="Vertical" VerticalAlignment="Center" Grid.Row="1">
                <StackPanel Margin="30" Orientation="Horizontal">
                <Rectangle x:Name="rectProcess" Width="180" Height="10"  RadiusX="3" RadiusY="3" >
                        <Rectangle.Fill>
                            <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
                                <GradientStop Color="#4682b4" Offset="0" />
                                <GradientStop Color="#4682b4" x:Name="blue1" Offset="0" />
                                <GradientStop Color="gray" x:Name="gray1" Offset="0" />
                                <GradientStop Color="gray" Offset="1" />
                            </LinearGradientBrush>
                            
                        </Rectangle.Fill>
                            <Rectangle.Resources>
                            <Storyboard x:Name="sbRect">
                                
                            </Storyboard>
                            
                        </Rectangle.Resources>
    
                    </Rectangle>
                <TextBlock Margin="10 0 0 0"  Text="正在加载 85%" x:Name="TxtLoading" HorizontalAlignment="Center" Foreground="Black" VerticalAlignment="Center" />
                </StackPanel>
                <Rectangle Width="30" Height="30" Fill="Red" RadiusX="3" RadiusY="3" ></Rectangle>
            </StackPanel>
        </Grid>
    </UserControl>

    后台文件:

    View Code
     public sealed partial class LodingImage : UserControl
        {
    
    
            /// <summary>
            /// 屏幕大小
            /// </summary>
            Rect bounds = Window.Current.Bounds;
            private string _uri = string.Empty;
            private Uri _baseUri = new Uri("ms-appx:///");
            BitmapImage bitmapImage;
            /// <summary>
            /// 是否可以移动
            /// </summary>
            private bool canMove = false;
            /// <summary>
            /// 鼠标/手指 移动前的坐标
            /// </summary>
            PointerPoint startPoint;
            /// <summary>
            /// 加载时图片默认Canvas.Left Canvas.Top坐标
            /// </summary>
            Point defaultPosition;
            /// <summary>
            /// 屏幕的中心位置
            /// </summary>
            Point defaultPoint;
            /// <summary>
            /// 当前移动位置和默认坐标的相差位移
            /// </summary>
            Point destancePoint = new Point(0, 0);
            /// <summary>
            /// 要显示的URI地址
            /// </summary>
            public string Uri
            {
                set
                {
                    bitmapImage = new BitmapImage();
                    img.Source = bitmapImage;
                    bitmapImage.UriSource = new Uri(_baseUri, value);//测试用本地图片
                    SetImageProperty();
                    TxtLoading.Visibility = rectProcess.Visibility = Visibility.Visible;
                    bitmapImage.DownloadProgress += bitmapImage_DownloadProgress;
                    bitmapImage.ImageFailed += bitmapImage_ImageFailed;
                    bitmapImage.ImageOpened += bitmapImage_ImageOpened;
                }
                get
                {
                    return _uri;
                }
            }
    
            private double _scaleRate = 0.2;
            public double ScaleRate
            {
                get
                {
                    return _scaleRate;
                }
                set
                {
                    _scaleRate = value;
                }
            }
    
            public Image OriginalImage
            {
                set
                {
    
                    img.Height = value.Height;
                    img.Width = value.Width;
                    img.Source = value.Source;
                }
                get
                {
                    return img;
                }
            }
            public Stretch ImageStretch
            {
                get { return img.Stretch; }
                set { img.Stretch = value; }
            }
    
    
            public LodingImage()
            {
                this.InitializeComponent();
                this.Loaded += LodingImage_Loaded;
                this.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            }
            public void Show()
            {
                this.Visibility = Windows.UI.Xaml.Visibility.Visible;
            }
            void LodingImage_Loaded(object sender, RoutedEventArgs e)
            {
                rectShadow.Width = bounds.Width;
                rectShadow.Height = bounds.Height;
                rectShadow.Fill = new SolidColorBrush(Colors.Gray);
                rectShadow.Opacity = 0.3;
            }
    
            void bitmapImage_DownloadProgress(object sender, DownloadProgressEventArgs e)
            {
                double moveRate = e.Progress * 1.0 / 100;
                gray1.Offset += moveRate;
                blue1.Offset += moveRate;
                TxtLoading.Text = string.Format("正在加载 {0}%", e.Progress);
            }
    
            void bitmapImage_ImageFailed(object sender, ExceptionRoutedEventArgs e)
            {
                TxtLoading.Text = string.Format("加载失败");
            }
            void bitmapImage_ImageOpened(object sender, RoutedEventArgs e)
            {
                TxtLoading.Visibility = rectProcess.Visibility = Visibility.Collapsed;
            }
            void ReLoad()
            {
                bitmapImage = new BitmapImage();
            }
    
            private void img_PointerEntered_1(object sender, PointerRoutedEventArgs e)
            {
                img.PointerWheelChanged += img_PointerWheelChanged;
            }
    
            void img_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
            {
                var pointerPointer = e.GetCurrentPoint(img);
                //注意pointerPoint.Properties属性 提供我们想要的很多属性
                var delta = pointerPointer.Properties.MouseWheelDelta;
    
                double rate = ScaleRate;
                if (delta < 0)
                {
                    rate = rate * -1;
                }
    
                if (st.ScaleX + rate <= 0.4)
                {
                    return;
                }
    
    
                /*
                 * 如果产生了相对位移的话即图片位置被移动过
                 * 则处理缩放的大小和相对位移做运算
                 * bug 当缩小时应该为下面的算法
                 *     
                 */
                if (rate < 0)
                {
                    if (destancePoint.Y > 0)
                    {
                        double dY = Math.Abs((rate * img.Height) / 2);
                        double moveTop = Convert.ToDouble(img.GetValue(Canvas.TopProperty));
                        if (dY >= Math.Abs(destancePoint.Y))
                        {
                            img.SetValue(Canvas.TopProperty, defaultPosition.Y);
                            destancePoint.Y = 0;
                        }
                        else
                        {
                            destancePoint.Y -= dY;
                            img.SetValue(Canvas.TopProperty, moveTop - dY);
                        }
                    }
                    else if (destancePoint.Y < 0)
                    {
                        double dY = Math.Abs((rate * img.Height) / 2);
                        double moveTop = Convert.ToDouble(img.GetValue(Canvas.TopProperty));
                        if (dY >= Math.Abs(destancePoint.Y))
                        {
                            img.SetValue(Canvas.TopProperty, defaultPosition.Y);
                            destancePoint.Y = 0;
                        }
                        else
                        {
                            destancePoint.Y += dY;
                            img.SetValue(Canvas.TopProperty, moveTop + dY);
                        }
                    }
    
                    if (destancePoint.X > 0)
                    {
                        double dX = Math.Abs((rate * img.Width) / 2);
                        double moveLeft = Convert.ToDouble(img.GetValue(Canvas.LeftProperty));
                        if (dX >= Math.Abs(destancePoint.X))
                        {
                            img.SetValue(Canvas.LeftProperty, defaultPosition.X);
                            destancePoint.X = 0;
                        }
                        else
                        {
                            destancePoint.X -= dX;
                            img.SetValue(Canvas.LeftProperty, moveLeft - dX);
                        }
                    }
                    else if (destancePoint.X < 0)
                    {
                        double dX = Math.Abs((rate * img.Width) / 2);
                        double moveLeft = Convert.ToDouble(img.GetValue(Canvas.LeftProperty));
                        if (dX >= Math.Abs(destancePoint.X))
                        {
                            img.SetValue(Canvas.LeftProperty, defaultPosition.X);
                            destancePoint.X = 0;
                        }
                        else
                        {
                            destancePoint.X += dX;
                            img.SetValue(Canvas.LeftProperty, moveLeft + dX);
                        }
                    }
    
                }
                else
                {
                        
    
                }
                st.ScaleY += rate;
                st.ScaleX += rate;
    
            }
    
            private void img_PointerExited_1(object sender, PointerRoutedEventArgs e)
            {
                img.PointerWheelChanged -= img_PointerWheelChanged;
            }
    
            private void LayoutRoot_PointerPressed_1(object sender, PointerRoutedEventArgs e)
            {
                this.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            }
    
            private void img_PointerPressed_1(object sender, PointerRoutedEventArgs e)
            {
                FrameworkElement element = sender as FrameworkElement;
                canMove = true;
                if (element != null)
                {
                    element.CapturePointer(e.Pointer);
                }
                startPoint = e.GetCurrentPoint(LayoutRoot);
    
                e.Handled = true;
            }
    
            private void img_PointerMoved_1(object sender, PointerRoutedEventArgs e)
            {
                if (canMove)
                {
                    PointerPoint point = e.GetCurrentPoint(LayoutRoot);
                    if (IsWidthOutBounds())
                    {
                        double left = double.Parse(img.GetValue(Canvas.LeftProperty).ToString());
                        double moveToX = (point.Position.X - startPoint.Position.X) + left;
                        destancePoint.X = moveToX - defaultPoint.X + img.Width / 2;
                        double destanceX = Math.Abs(destancePoint.X);
                        if (destanceX <= (img.Width * st.ScaleX - bounds.Width) / 2)
                        {
                            img.SetValue(Canvas.LeftProperty, moveToX);
                        }
                    }
                    if (IsHeightOutBounds())
                    {
                        double top = double.Parse(img.GetValue(Canvas.TopProperty).ToString());
                        double moveToY = (point.Position.Y - startPoint.Position.Y) + top;
                        destancePoint.Y = moveToY - defaultPoint.Y + img.Height /2;
                        double destanceY = Math.Abs(destancePoint.Y);
                        if (destanceY <= (img.Height * st.ScaleY - bounds.Height) / 2)
                        {
                            img.SetValue(Canvas.TopProperty, moveToY);
                        }
    
                    }
                    startPoint = e.GetCurrentPoint(LayoutRoot);
                }
            }
    
            private void img_PointerReleased_1(object sender, PointerRoutedEventArgs e)
            {
                FrameworkElement element = sender as FrameworkElement;
                element.ReleasePointerCapture(e.Pointer);
                canMove = false;
    
            }
    
    
            private void SetImageProperty()
            {
                st.ScaleX = 1.5;
                st.ScaleY = 1.5;
                st.CenterX = img.Width / 2;
                st.CenterY = img.Height / 2;
                double top = (bounds.Height - img.Height) / 2;
                double left = (bounds.Width - img.Width) / 2;
                defaultPosition = new Point(left, top);
                destancePoint = new Point(0, 0);
                defaultPoint = new Point(bounds.Width / 2, bounds.Height / 2);
                img.SetValue(Canvas.TopProperty, top);
                img.SetValue(Canvas.LeftProperty, left);
            }
            /// <summary>
            /// 判断是否超过纵向边界
            /// </summary>
            /// <returns></returns>
            private bool IsHeightOutBounds()
            {
                double rate = st.ScaleY;
                if ((rate * img.Height) > bounds.Height)
                {
                    return true;
                }
                return false;
            }
            /// <summary>
            /// 判断是否超过横向边界
            /// </summary>
            /// <returns></returns>
            private bool IsWidthOutBounds()
            {
                double rate = st.ScaleX;
                if ((rate * img.Width) > bounds.Width)
                {
                    return true;
                }
                return false;
            }
        }

    调用该用户控件:

    View Code
    loadingImage.OriginalImage = img;
    loadingImage.Uri = item.Uri;
     loadingImage.Show();
    学徒帮-jQuery帮帮帮 欢迎更多的前端交流、Js交流、jQuery交流
  • 相关阅读:
    我的第一个python web开发框架(27)——定制ORM(三)
    我的第一个python web开发框架(26)——定制ORM(二)
    我的第一个python web开发框架(25)——定制ORM(一)
    我的第一个python web开发框架(24)——系统重构与ORM
    我的第一个python web开发框架(23)——代码版本控制管理与接口文档
    我的第一个python web开发框架(22)——一个安全小事故
    CentOS7安装详解
    自动化运维工具-mussh工具安装配置及简单使用讲解
    自动化运维工具-pdsh工具安装配置及简单使用讲解
    自动化运维工具-pssh工具安装配置及简单使用讲解
  • 原文地址:https://www.cnblogs.com/Jusoc/p/2774947.html
Copyright © 2011-2022 走看看