zoukankan      html  css  js  c++  java
  • WPF 中Canvas图形移动、缩放代码

    从Flash转C#,很多内容一知半解,边摸索边前进,代码粗糙,权当留个脚印。

    只是想得到一个基础的移动和缩放功能的界面,找了很久都是画线、画矩形等基础形状的代码,移动和缩放说的并不清晰,只能自己努力来解决一下。

    素材准备:

    WPF项目的屏幕上放一个Canvas控件,名称为canvas1。

    代码如下:

      1 using System;
      2 using System.Windows;
      3 using System.Windows.Media;
      4 using System.Windows.Input;
      5 using System.Windows.Shapes;
      6 using System.Windows.Controls;
      7 
      8 namespace WpfcanvasDrawing
      9 {
     10     /// <summary>
     11     /// MainWindow.xaml 的交互逻辑
     12     /// </summary>
     13     public partial class MainWindow : Window
     14     {
     15         //移动标志
     16         bool isMoving = false;
     17         //鼠标按下去的位置
     18         Point startMovePosition;
     19 
     20         TranslateTransform totalTranslate = new TranslateTransform();
     21         TranslateTransform tempTranslate = new TranslateTransform();
     22         ScaleTransform totalScale = new ScaleTransform();
     23         Double scaleLevel = 1;
     24 
     25         public MainWindow()
     26         {
     27             InitializeComponent();
     28 
     29             canvas1.Focusable = true;//重要:默认条件下不接收鼠标事件
     30             canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
     31             canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
     32             canvas1.Background = Brushes.Transparent;//.Cyan;
     33 
     34 
     35             DrawingLine(new Point(100, 100), new Point(300, 200));
     36             DrawingLine(new Point(100, 200), new Point(300, 100));
     37         }
     38 
     39         protected void DrawingLine(Point startPt, Point endPt)
     40         {
     41             LineGeometry myLineGeometry = new LineGeometry();
     42             myLineGeometry.StartPoint = startPt;
     43             myLineGeometry.EndPoint = endPt;
     44 
     45             Path myPath = new Path();
     46             myPath.Stroke = Brushes.Black;
     47             myPath.StrokeThickness = 1;
     48             myPath.Data = myLineGeometry;
     49 
     50             canvas1.Children.Add(myPath);
     51         }
     52 
     53         private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
     54         {           
     55             startMovePosition = e.GetPosition((Canvas)sender);
     56             isMoving = true;
     57         }
     58 
     59         private void canvas1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
     60         {
     61             isMoving = false;
     62             Point endMovePosition = e.GetPosition((Canvas)sender);
     63 
     64             //为了避免跳跃式的变换,单次有效变化 累加入 totalTranslate中。           
     65             totalTranslate.X += (endMovePosition.X - startMovePosition.X)/scaleLevel;
     66             totalTranslate.Y += (endMovePosition.Y - startMovePosition.Y)/scaleLevel;           
     67         }
     68 
     69         private void canvas1_MouseMove(object sender, MouseEventArgs e)
     70         {
     71             if (isMoving)
     72             {
     73                 Point currentMousePosition = e.GetPosition((Canvas)sender);//当前鼠标位置
     74                 
     75                 Point deltaPt = new Point(0, 0);               
     76                 deltaPt.X = (currentMousePosition.X - startMovePosition.X) /scaleLevel;                
     77                 deltaPt.Y = (currentMousePosition.Y - startMovePosition.Y) /scaleLevel;
     78                 
     79                 tempTranslate.X = totalTranslate.X + deltaPt.X;
     80                 tempTranslate.Y = totalTranslate.Y + deltaPt.Y;
     81 
     82                 adjustGraph();
     83             }
     84         }        
     85         
     86         private void canvas1_MouseWheel(object sender, MouseWheelEventArgs e)
     87         {
     88             Point scaleCenter = e.GetPosition((Canvas)sender);
     89 
     90             if (e.Delta > 0)
     91             {
     92                 scaleLevel *= 1.08;
     93             }
     94             else
     95             {
     96                 scaleLevel /= 1.08;
     97             }
     98             //Console.WriteLine("scaleLevel: {0}", scaleLevel);
     99 
    100             totalScale.ScaleX = scaleLevel;
    101             totalScale.ScaleY = scaleLevel;
    102             totalScale.CenterX = scaleCenter.X;
    103             totalScale.CenterY = scaleCenter.Y;
    104 
    105             adjustGraph();
    106         }
    107        
    108         private void adjustGraph()
    109         {
    110             TransformGroup tfGroup = new TransformGroup();
    111             tfGroup.Children.Add(tempTranslate);
    112             tfGroup.Children.Add(totalScale);
    113 
    114             foreach (UIElement ue in canvas1.Children)
    115             {
    116                 ue.RenderTransform = tfGroup;
    117             }
    118         }
    119 
    120     }
    121 }

    变量说明:

         //移动标志
            bool isMoving = false;
            //鼠标按下去的位置
            Point startMovePosition;
    
            TranslateTransform totalTranslate = new TranslateTransform();//多次操作中需要对总的移动量进行统计。        
            ScaleTransform totalScale = new ScaleTransform();//缩放变量
            Double scaleLevel = 1;//缩放的级别

    函数功能说明:
    DrawingLine 在指定的Canvas控件中画线,用于测试。
    鼠标按下时,记录起始移动的位置点,标记拖动操作开始 isMoving = true。
    鼠标移动过程中,将有效的移动距离记录到总移动变量 totalTranslate 当中,并对位置进行刷新
    鼠标滚轮变化时,根据滚轮方向调整
    缩放级别。

    不同缩放级别下,屏幕中移动相同的距离,对于Canvs内的图形来说距离不同,因此需要对鼠标移动的距离进行修正,即将移动距离除以缩放级别,这样可以得到相对精确的移动位置。

    遗留问题:
    1、连续在不同位置进行缩放时,仍会有较小的抖动,细节处理上还有瑕疵。
    2、使用下面的语句,可以实现canvas1自动缩放(将canvas1的宽度与高度设为Auto)。
    canvas1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
    canvas1.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;



    学习太辛苦,采购点东西鼓励一下自己,微信扫描二维码,“香雪杂货店”欢迎您的到来,遇到喜欢的东西尽管带走~~


  • 相关阅读:
    ssh批量远程执行脚本screen后台运行
    使用screen共享shell会话(终端共享)
    php获取一个月前的时间戳,获取三个月前的时间戳,获取一年前的时间戳
    jquery 鼠标经过延时触发事件,jquery插件
    jquery 克隆div 复制div 克隆元素 复制元素
    js实现一个可以兼容PC端和移动端的div拖动效果
    完美实现鼠标拖拽事件,解决各种小bug,基于jquery
    js将秒转换为 分:秒 函数
    php将秒转换为 分:秒 函数
    phpStudy启动失败时的解决方法 提示缺vc9运行库
  • 原文地址:https://www.cnblogs.com/windspiral/p/8047490.html
Copyright © 2011-2022 走看看