zoukankan      html  css  js  c++  java
  • WPF/Silverligh实现图片的放大缩小拖动

    实现功能如下

    1. 以滚轮中心点对图片容器进行放大和缩小
    2. 对放大后的图片进行拖动
    3. 对拖动的范围进行控制

             由于在后续的功能中需要动态加载不同的图片,所以此示例中是针对grid的放大和缩小,图片是自动填充的!

    本人头脑比较笨,用最简单的原理来实现的,实现原理如下:

    1.放大操作

    假设我们要对(1.5,1.5)这个点为中心进行放大,那么放大1倍后,应该是矩形2的位置,需要将(3,3)的点移动到原来点的位置,需要将矩形2向上移动1.5,向左移动1.5

    ScaleTransform放大1倍,TranslateTransform移动为(-1.5,-1.5).得出如下图所示

    2.移动后放大,放大后移动再放大等情况

    看下图的情况:我们将矩形1向左移动1个单位后,再放大1倍

    当我们点击相对于原点(2.5,1.5)的点时,实际上我们想放大的是相对于矩形1(1.5,1.5)的点!那么我们首先利用矩阵的逆变换得到相对于矩形1的点。然后对矩形1的点(1.5,1.5)进行放大1倍的处理,重复步骤1(放大操作)。

    然后再计算出(2.5,1.5)与逆变换后(1.5,1.5)的偏移距离,将TranslateTransform再次移动(1,0)。即得到所要的矩形2,如下图

    下面是实现的代码:

    界面层,我使用grdMap来作为变换的对象,grdMap的内容为1.jpg图片(也可以是其他控件等各类元素)。这里使用grdRelative作为参照物(起到原点的作用,原始图片位置)。注意里面的元素数据绑定,可以做到自适应屏幕,所有宽度和高度不指定。slider可用可不用,自己修改。

    <Window x:Class="WpfMap.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow"
            Height="350"
            Width="525">
        <Grid x:Name="grd">
            <Grid x:Name="grdRelative"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"
                  Width="{Binding ActualWidth, ElementName=grdMap}"
                  Height="{Binding ActualHeight, ElementName=grdMap}"></Grid>
            <Grid x:Name="grdMap"
                  MouseWheel="grdMap_MouseWheel"
                  MouseLeave="grdMap_MouseLeave"
                  MouseDown="grdMap_MouseDown"
                  MouseUp="grdMap_MouseUp"
                  MouseMove="grdMap_MouseMove"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"
                  RenderTransformOrigin="0,0">
                <Grid.RenderTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="{Binding Value, ElementName=slider}"
                                        ScaleY="{Binding Value, ElementName=slider}" />
                        <SkewTransform />
                        <RotateTransform />
                        <TranslateTransform />
                    </TransformGroup>
                </Grid.RenderTransform>
                <Image Source="1.jpg" />
            </Grid>
            <Slider x:Name="slider"
                    HorizontalAlignment="Left"
                    VerticalAlignment="Center"
                    Orientation="Vertical"
                    Width="20"
                    Height="200"
                    Maximum="3"
                    Minimum="1" />
        </Grid>
    </Window>
    


    后台代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace WpfMap
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            }
    
            ScaleTransform st;
            TranslateTransform tt;
            TransformGroup group;
            bool isDrag = false;
            Point startPoint;
    
            void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                group = (TransformGroup)grdMap.RenderTransform;
                st = group.Children[0] as ScaleTransform;
                tt = group.Children[3] as TranslateTransform;
            }
    
            private void grdMap_MouseWheel(object sender, MouseWheelEventArgs e)
            {
                var point = e.GetPosition(grdRelative); // 实际点击的点
                var actualPoint = group.Inverse.Transform(point); // 想要缩放的点
                slider.Value = slider.Value + (double)e.Delta / 1000;
                tt.X = -((actualPoint.X * (slider.Value - 1))) + point.X - actualPoint.X;
                tt.Y = -((actualPoint.Y * (slider.Value - 1))) + point.Y - actualPoint.Y;
            }
    
            private void grdMap_MouseDown(object sender, MouseButtonEventArgs e)
            {
                isDrag = true;
                startPoint = e.GetPosition(grdRelative);
            }
    
            private void grdMap_MouseUp(object sender, MouseButtonEventArgs e)
            {
                isDrag = false;
            }
    
            private void grdMap_MouseLeave(object sender, MouseEventArgs e)
            {
                isDrag = false;
            }
    
            private void grdMap_MouseMove(object sender, MouseEventArgs e)
            {
                if (isDrag)
                {
                    Point p = e.GetPosition(grdRelative);
                    Point topPoint = grdMap.TranslatePoint(new Point(0, 0), grdRelative);
                    Point bottomPoint = grdMap.TranslatePoint(new Point(grdMap.ActualWidth, grdMap.ActualHeight), grdRelative);
    
                    double moveX = p.X - startPoint.X;
                    double moveY = p.Y - startPoint.Y;
    
                    //向上向下移动条件判断(会有一点点的小偏移,如果想更精确的控制,那么分向上和向下两种情况,并判断边距)
                    if ((moveY < 0 && bottomPoint.Y > grdRelative.ActualHeight) || (moveY > 0 && topPoint.Y < 0))
                    {
                        tt.Y += (p.Y - startPoint.Y);
                        startPoint.Y = p.Y;
                    }
    
                    //向左向右移动条件判断
                    if ((moveX < 0 && bottomPoint.X > grdRelative.ActualWidth) || (moveX > 0 && topPoint.X < 0))
                    {
                        tt.X += (p.X - startPoint.X);
                        startPoint.X = p.X;
                    }
                }
            }
        }
    }
    


    代码很简单,也没有写过多的注释!

    下载代码需要2个积分,其实以上的代码段已经包含所有代码了!

    以下是源码地址,vs2010,可直接运行!

    http://download.csdn.net/detail/wuwo333/5308725

  • 相关阅读:
    mysql慢日志设置
    CURL模拟登陆
    违法图片检测
    PHP取二进制文件头快速判断文件类型
    重写session
    mysql处理高并发,防止库存超卖
    mysql中使用update select
    PHP中使用Luhn算法校验信用卡及借记卡卡号
    红包算法
    DIV当textarea使用,在聚焦的时候将光标移动到内容的末尾
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3047893.html
Copyright © 2011-2022 走看看