WPF/Silverligh实现图片的放大缩小拖动
来源:互联网 发布:雷神vpn软件 编辑:程序博客网 时间:2024/05/18 02:24
实现功能如下
- 以滚轮中心点对图片容器进行放大和缩小
- 对放大后的图片进行拖动
- 对拖动的范围进行控制
由于在后续的功能中需要动态加载不同的图片,所以此示例中是针对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
- WPF/Silverligh实现图片的放大缩小拖动
- WPF/Silverligh实现图片的放大缩小拖动
- 实现图片的点击拖动与多指放大缩小
- wpf下实现图片的放大缩小和平移
- WPF下实现图片的放大缩小移动
- WPF下实现图片的放大缩小移动
- wpf下实现图片的放大缩小和平移
- WPF图片放大缩小
- android中图片的放大缩小拖动
- 图片里放大缩小拖动
- GTK+实现图片显示、放大、缩小、拖动、选中区域
- js实现图片滚轮放大缩小以及鼠标拖动
- JS实现鼠标滚轮缩小放大拖动图片代码
- 实现SVG图片放大缩小(zoom)与拖动(pan)的方法
- 支持点击放大缩小图片,拖动放大缩小图片功能
- Winform窗体图片的拖动,放大,缩小,复位,打印预览,鼠标滑轮的放大缩小
- android Matrix图片随意的放大缩小,拖动
- android Matrix图片随意的放大缩小,拖动
- Jersey1.8在spring环境下的实现 包括实例代码
- ThinkPHP调用存储过程不能返回结果集的解决方案
- Windows Media Player 属性解释
- 表达式解析引擎的设计
- sun-java-sdk安装方法
- WPF/Silverligh实现图片的放大缩小拖动
- mysql安装图解 mysql图文安装教程(详细说明)
- 杭电1592
- spring+ibatis 批量提交数据
- myeclipse8.5中自带的struts2需要的jar包放在哪啊?
- 去除旋转图片时的锯齿
- CS服务器异步模式下如何建立安全连接OPENSSL之RSA篇
- perl数据库连接操作
- 关于ORACLE COMMIT操作的详解