在WPF中Canvas 绘制图形的平移、缩放

cg1221 2016-01-04 05:47:18
我在WPF中(C#)Canvas中画了N多条线段、圆、文字。现在我想用鼠标滚轮以鼠标指针为缩放点同时缩放Canvas中的所有图形,鼠标左键按下能同时平移所有图形。改怎么做,我写出来的缩放是以左上角为原点的,平移时会跳动。
当Canvas大小改变时整个Canvas里的图形会等比例的放大缩小。
1、缩放时Canvas大小不得改变,只是缩放图形
2、能同时支持鼠标和平板触屏操作平移缩放。
3、给源代码最好。

谢谢各位老师
...全文
2862 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
longjr020 2018-04-21
  • 打赏
  • 举报
回复
解决了,对缩放对象的RenderTransform进行矩阵操作,画布的canvas.RenderTransform不要牵扯进去就好.结合https://www.cnblogs.com/TianFang/p/3950557.html那里的图像放缩拖拽来学习比较好
城墙下的猫 2017-12-16
  • 打赏
  • 举报
回复
可以参考这篇文章 WPF 中Canvas图形移动、缩放代码 http://www.cnblogs.com/windspiral/p/8047490.html
exception92 2017-04-14
  • 打赏
  • 举报
回复
1:根据鼠标滚轮值,操作顶级容器的ScaleTransform,注意要要设置 缩放的”中心点“ centerX,centerY ;设置滚轮值为ScaleX与ScaleY 2:平移操作 可以 在未释放鼠标左键的情况下,在PreviewMouseMove 事件中 获取当前鼠标相对于canvas的位置,类似:
void  canvas_PreviewMouseMove(object sender,MouseEventArgs e){
    if (e.LeftButton == MouseButtonState.Pressed)
       {
                Point point = e.GetPosition(canvas);
                // TODO: 设置顶级容器的Canvas.Left 与Canvas.Top 为别为point的X,Y 值
       }
}
xuggzu 2017-04-13
  • 打赏
  • 举报
回复
ScaleTransform
mitch99 2017-04-13
  • 打赏
  • 举报
回复
楼主是想画布不缩放,只缩放画布里面的图件。我也找了好久没找到,楼主知道的话分享下。
cg1221 2016-01-04
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
关于“平移时会跳动”的问题,不知道你是怎样实现的。在平移时就是简单地修改一下控件的X、Y属性就行了,而且在你平移开始之前可以禁止WPF刷新界面,等平移完所有控件之后再允许刷新,应该没有任何跳动。
private void sf(object sender, MouseWheelEventArgs e)//图形缩放 { Point cen = e.GetPosition(hb); sfk.CenterX = cen.X; sfk.CenterY = cen.Y; if (sfk.ScaleX < 0.3 && sfk.ScaleY < 0.3 && e.Delta < 0) { return; } sfk.ScaleX += (double)e.Delta / 1000.0; sfk.ScaleY += (double)e.Delta / 1000.0; } private void hb_MouseMove(object sender, MouseEventArgs e)//平移 { if (e.LeftButton ==MouseButtonState.Pressed) { foreach (UIElement s in hb.Children) { Point pCanvas = e.GetPosition(hb); Canvas.SetLeft(s, pCanvas.X - targetPoint.X); Canvas.SetTop(s,pCanvas.Y - targetPoint.Y); } } }
cg1221 2016-01-04
  • 打赏
  • 举报
回复
private void sf(object sender, MouseWheelEventArgs e)//图形缩放 { Point cen = e.GetPosition(hb); sfk.CenterX = cen.X; sfk.CenterY = cen.Y; if (sfk.ScaleX < 0.3 && sfk.ScaleY < 0.3 && e.Delta < 0) { return; } sfk.ScaleX += (double)e.Delta / 1000.0; sfk.ScaleY += (double)e.Delta / 1000.0; } private void hb_MouseMove(object sender, MouseEventArgs e)//平移 { if (e.LeftButton ==MouseButtonState.Pressed) { foreach (UIElement s in hb.Children) { Point pCanvas = e.GetPosition(hb); Canvas.SetLeft(s, pCanvas.X - targetPoint.X); Canvas.SetTop(s,pCanvas.Y - targetPoint.Y); } } }
  • 打赏
  • 举报
回复
关于“平移时会跳动”的问题,不知道你是怎样实现的。在平移时就是简单地修改一下控件的X、Y属性就行了,而且在你平移开始之前可以禁止WPF刷新界面,等平移完所有控件之后再允许刷新,应该没有任何跳动。
  • 打赏
  • 举报
回复
每一个图形控件,它只要修改一下缩放参数 Scale 就能自动化地缩放,这完全是你滚轮事件来决定的。因此控件自身的大小缩放本身并不用考虑鼠标位置问题。 在你整体缩放地图的时候,可以捕获鼠标中心点。那么对于地图上任何一点(比如说你的任何图形控件的左上角的坐标),可以算出它与中心点在x、y坐标上的直线距离,然后缩放这个偏移距离。例如中心点在(100,100),那么一个点(98,99)距离中心点的偏移就是(-2,-1),如果缩放系数为2,就是要偏移(-4,-2),也就是挪动到(96,98)这个新位置上。

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧